OSDN Git Service

LinGui: Make preset key/values mostly align with macui presets.
[handbrake-jp/handbrake-jp-git.git] / gtk / src / callbacks.c
index 36013fa..c0a7e6b 100644 (file)
 #include <glib/gstdio.h>
 #include <gio/gio.h>
 
+#include "hb.h"
 #include "callbacks.h"
+#include "queuehandler.h"
+#include "audiohandler.h"
+#include "resources.h"
 #include "settings.h"
 #include "presets.h"
 #include "values.h"
 #include "ghbcellrenderertext.h"
 
 static void update_chapter_list(signal_user_data_t *ud);
-static void clear_audio_list(signal_user_data_t *ud);
 static GList* dvd_device_list();
-static gboolean cancel_encode();
-static void audio_list_refresh_selected(signal_user_data_t *ud);
-static GValue* get_selected_asettings(signal_user_data_t *ud);
 
 // This is a dependency map used for greying widgets
 // that are dependent on the state of another widget.
@@ -51,20 +51,11 @@ static GValue* get_selected_asettings(signal_user_data_t *ud);
 GValue *dep_map;
 GValue *rev_map;
 
-const gchar widget_deps[] =
-#include "widget_deps.h"
-;
-
-const gchar widget_reverse_deps[] =
-#include "widget_reverse_deps.h"
-;
-
 void
 ghb_init_dep_map()
 {
-       dep_map = ghb_plist_parse(widget_deps, sizeof(widget_deps)-1);
-       rev_map = ghb_plist_parse(widget_reverse_deps, 
-                                                               sizeof(widget_reverse_deps)-1);
+       dep_map = ghb_resource_get("widget-deps");
+       rev_map = ghb_resource_get("widget-reverse-deps");
 }
 
 static gboolean
@@ -148,19 +139,22 @@ dep_check(signal_user_data_t *ud, const gchar *name)
        return result;
 }
 
-static void
-check_depencency(signal_user_data_t *ud, GtkWidget *widget)
+void
+ghb_check_dependency(signal_user_data_t *ud, GtkWidget *widget)
 {
        GObject *dep_object;
        const gchar *name;
        GValue *array, *data;
        gint count, ii;
        gchar *dep_name;
+       GType type;
 
-       if (ghb_widget_index(widget) < 0) return;
+       type = GTK_WIDGET_TYPE(widget);
+       if (type == GTK_TYPE_COMBO_BOX || type == GTK_TYPE_COMBO_BOX_ENTRY)
+               if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) < 0) return;
 
        name = gtk_widget_get_name(widget);
-       g_debug("check_depencency () %s", name);
+       g_debug("ghb_check_dependency () %s", name);
 
        array = ghb_dict_lookup(dep_map, name);
        count = ghb_array_len(array);
@@ -196,7 +190,10 @@ ghb_check_all_depencencies(signal_user_data_t *ud)
 
        g_debug("ghb_check_all_depencencies ()");
        ghb_dict_iter_init(&iter, rev_map);
-       while (g_hash_table_iter_next(&iter, (gpointer*)&dep_name, (gpointer*)&value))
+       // middle (void*) cast prevents gcc warning "defreferencing type-punned
+       // pointer will break strict-aliasing rules"
+       while (g_hash_table_iter_next(
+                       &iter, (gpointer*)(void*)&dep_name, (gpointer*)(void*)&value))
        {
                gboolean sensitive;
                dep_object = gtk_builder_get_object (ud->builder, dep_name);
@@ -213,19 +210,6 @@ ghb_check_all_depencencies(signal_user_data_t *ud)
        }
 }
 
-static void
-clear_presets_selection(signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreeSelection *selection;
-       
-       if (ud->dont_clear_presets) return;
-       g_debug("clear_presets_selection()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
-       selection = gtk_tree_view_get_selection (treeview);
-       gtk_tree_selection_unselect_all (selection);
-}
-
 static gchar*
 expand_tilde(const gchar *path)
 {
@@ -265,16 +249,16 @@ on_quit1_activate(GtkMenuItem *quit, signal_user_data_t *ud)
 {
        gint state = ghb_get_queue_state();
        g_debug("on_quit1_activate ()");
-    if (state & GHB_STATE_WORKING)
-    {
-        if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
-        {
+       if (state & GHB_STATE_WORKING)
+       {
+               if (ghb_cancel_encode("Closing HandBrake will terminate encoding.\n"))
+               {
                        ghb_hb_cleanup(FALSE);
-               gtk_main_quit();
-            return;
-        }
-        return;
-    }
+                       gtk_main_quit();
+                       return;
+               }
+               return;
+       }
        ghb_hb_cleanup(FALSE);
        gtk_main_quit();
 }
@@ -289,10 +273,30 @@ set_destination(signal_user_data_t *ud)
                gchar *dir, *new_name;
                
                filename = ghb_settings_get_string(ud->settings, "destination");
-               extension = ghb_settings_get_string(ud->settings, "container");
+               extension = ghb_settings_get_string(ud->settings, "FileFormat");
                dir = g_path_get_dirname (filename);
                vol_name = ghb_settings_get_string(ud->settings, "volume_label");
-               new_name = g_strdup_printf("%s/%s.%s", dir, vol_name, extension);
+               if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+               {
+                       gint start, end;
+
+                       start = ghb_settings_get_int(ud->settings, "start_chapter");
+                       end = ghb_settings_get_int(ud->settings, "end_chapter");
+                       if (start == end)
+                       {
+                               new_name = g_strdup_printf("%s/%s-%d.%s", 
+                                       dir, vol_name, start, extension);
+                       }
+                       else
+                       {
+                               new_name = g_strdup_printf("%s/%s-%d-%d.%s", 
+                                       dir, vol_name, start, end, extension);
+                       }
+               }
+               else
+               {
+                       new_name = g_strdup_printf("%s/%s.%s", dir, vol_name, extension);
+               }
                ghb_ui_update(ud, "destination", ghb_string_value(new_name));
                g_free(filename);
                g_free(extension);
@@ -358,6 +362,28 @@ camel_convert(gchar *str)
        }
 }
 
+static gchar*
+get_file_label(const gchar *filename)
+{
+       static gchar *containers[] = 
+               {".vob", ".mpg", ".m2ts", ".mkv", ".mp4", ".m4v", ".avi", ".ogm", NULL};
+       gchar *base;
+       gint ii;
+
+       base = g_path_get_basename(filename);
+       for (ii = 0; containers[ii] != NULL; ii++)
+       {
+               if (g_str_has_suffix(base, containers[ii]))
+               {
+                       gchar *pos;
+                       pos = strrchr(base, '.');
+                       *pos = 0;
+                       break;
+               }
+       }
+       return base;
+}
+
 static gboolean
 update_source_label(signal_user_data_t *ud, const gchar *source)
 {
@@ -389,11 +415,7 @@ update_source_label(signal_user_data_t *ud, const gchar *source)
                label = ghb_dvd_volname (filename);
                if (label == NULL)
                {
-                       path = g_strsplit(filename, "/", -1);
-                       len = g_strv_length (path);
-                       // Just use the last combonent of the path
-                       label = g_strdup(path[len-1]);
-                       g_strfreev (path);
+                       label = get_file_label(filename);
                }
                else
                {
@@ -541,11 +563,36 @@ source_dialog_extra_widgets(GtkWidget *dialog, gboolean checkbutton_active)
        return GTK_WIDGET(vbox);
 }
 
-static void
-do_scan(signal_user_data_t *ud, const gchar *filename)
+extern GValue *ghb_queue_edit_settings;
+static gchar *last_scan_file = NULL;
+
+void
+ghb_do_scan(signal_user_data_t *ud, const gchar *filename, gboolean force)
 {
+       if (!force && last_scan_file != NULL &&
+               strcmp(last_scan_file, filename) == 0)
+       {
+               if (ghb_queue_edit_settings)
+               {
+                       gint jstatus;
+
+                       jstatus = ghb_settings_get_int(ghb_queue_edit_settings, "job_status");
+                       ghb_settings_to_ui(ud, ghb_queue_edit_settings);
+                       ghb_set_audio(ud, ghb_queue_edit_settings);
+                       if (jstatus == GHB_QUEUE_PENDING)
+                       {
+                               ghb_value_free(ghb_queue_edit_settings);
+                       }
+                       ghb_queue_edit_settings = NULL;
+               }
+               return;
+       }
+       if (last_scan_file != NULL)
+               g_free(last_scan_file);
+       last_scan_file = NULL;
        if (filename != NULL)
        {
+               last_scan_file = g_strdup(filename);
                ghb_settings_set_string(ud->settings, "source", filename);
                if (update_source_label(ud, filename))
                {
@@ -606,7 +653,7 @@ source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
                filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
                if (filename != NULL)
                {
-                       do_scan(ud, filename);
+                       ghb_do_scan(ud, filename, TRUE);
                        if (strcmp(sourcename, filename) != 0)
                        {
                                ghb_settings_set_string (ud->settings, "default_source", filename);
@@ -628,7 +675,7 @@ dvd_source_activate_cb(GtkAction *action, signal_user_data_t *ud)
 
        sourcename = ghb_settings_get_string(ud->settings, "source");
        filename = gtk_action_get_name(action);
-       do_scan(ud, filename);
+       ghb_do_scan(ud, filename, TRUE);
        if (strcmp(sourcename, filename) != 0)
        {
                ghb_settings_set_string (ud->settings, "default_source", filename);
@@ -648,7 +695,7 @@ update_destination_extension(signal_user_data_t *ud)
        GtkEntry *entry;
 
        g_debug("update_destination_extension ()");
-       extension = ghb_settings_get_string(ud->settings, "container");
+       extension = ghb_settings_get_string(ud->settings, "FileFormat");
        entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "destination"));
        filename = g_strdup(gtk_entry_get_text(entry));
        for (ii = 0; containers[ii] != NULL; ii++)
@@ -748,11 +795,11 @@ destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
        g_debug("destination_browse_clicked_cb ()");
        destname = ghb_settings_get_string(ud->settings, "destination");
        dialog = gtk_file_chooser_dialog_new ("Choose Destination",
-                      NULL,
-                      GTK_FILE_CHOOSER_ACTION_SAVE,
-                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
-                      NULL);
+                                         NULL,
+                                         GTK_FILE_CHOOSER_ACTION_SAVE,
+                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                         GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+                                         NULL);
        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), destname);
        basename = g_path_get_basename(destname);
        g_free(destname);
@@ -783,7 +830,7 @@ window_destroy_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *
        g_debug("window_destroy_event_cb ()");
        ghb_hb_cleanup(FALSE);
        gtk_main_quit();
-    return FALSE;
+       return FALSE;
 }
 
 gboolean
@@ -791,19 +838,19 @@ window_delete_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *u
 {
        gint state = ghb_get_queue_state();
        g_debug("window_delete_event_cb ()");
-    if (state & GHB_STATE_WORKING)
-    {
-        if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
-        {
+       if (state & GHB_STATE_WORKING)
+       {
+               if (ghb_cancel_encode("Closing HandBrake will terminate encoding.\n"))
+               {
                        ghb_hb_cleanup(FALSE);
-               gtk_main_quit();
-            return FALSE;
-        }
-        return TRUE;
-    }
+                       gtk_main_quit();
+                       return FALSE;
+               }
+               return TRUE;
+       }
        ghb_hb_cleanup(FALSE);
        gtk_main_quit();
-    return FALSE;
+       return FALSE;
 }
 
 static void
@@ -819,19 +866,19 @@ container_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        g_debug("container_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
        update_destination_extension(ud);
-       check_depencency(ud, widget);
+       ghb_check_dependency(ud, widget);
        update_acodec_combo(ud);
-       clear_presets_selection(ud);
+       ghb_clear_presets_selection(ud);
 
        audio_list = ghb_settings_get_value(ud->settings, "audio_list");
        if (ghb_ac3_in_audio_list (audio_list))
        {
                gchar *container;
 
-               container = ghb_settings_get_string(ud->settings, "container");
+               container = ghb_settings_get_string(ud->settings, "FileFormat");
                if (strcmp(container, "mp4") == 0)
                {
-                       ghb_ui_update(ud, "container", ghb_string_value("m4v"));
+                       ghb_ui_update(ud, "FileFormat", ghb_string_value("m4v"));
                }
                g_free(container);
        }
@@ -884,6 +931,8 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        widget = GHB_WIDGET (ud->builder, "source_dimensions");
        text = g_strdup_printf ("%d x %d", tinfo->width, tinfo->height);
        gtk_label_set_text (GTK_LABEL(widget), text);
+       ghb_settings_set_int(ud->settings, "source_width", tinfo->width);
+       ghb_settings_set_int(ud->settings, "source_height", tinfo->height);
        g_free(text);
        widget = GHB_WIDGET (ud->builder, "source_aspect");
        text = get_aspect_string(tinfo->aspect_n, tinfo->aspect_d);
@@ -899,7 +948,7 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
                ghb_int64_value(tinfo->width - tinfo->crop[2] - tinfo->crop[3]));
        // If anamorphic or keep_aspect, the hight will be automatically calculated
        gboolean keep_aspect, anamorphic;
-       keep_aspect = ghb_settings_get_boolean(ud->settings, "keep_aspect");
+       keep_aspect = ghb_settings_get_boolean(ud->settings, "PictureKeepRatio");
        anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
        if (!(keep_aspect || anamorphic))
        {
@@ -911,22 +960,34 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        // you pass it a cropped width or height == 0.
        gint bound;
        bound = tinfo->height / 2 - 2;
-       widget = GHB_WIDGET (ud->builder, "crop_top");
+       widget = GHB_WIDGET (ud->builder, "PictureTopCrop");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       widget = GHB_WIDGET (ud->builder, "crop_bottom");
+       widget = GHB_WIDGET (ud->builder, "PictureBottomCrop");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
        bound = tinfo->width / 2 - 2;
-       widget = GHB_WIDGET (ud->builder, "crop_left");
+       widget = GHB_WIDGET (ud->builder, "PictureLeftCrop");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       widget = GHB_WIDGET (ud->builder, "crop_right");
+       widget = GHB_WIDGET (ud->builder, "PictureRightCrop");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       if (ghb_settings_get_boolean(ud->settings, "autocrop"))
-       {
-               ghb_ui_update(ud, "crop_top", ghb_int64_value(tinfo->crop[0]));
-               ghb_ui_update(ud, "crop_bottom", ghb_int64_value(tinfo->crop[1]));
-               ghb_ui_update(ud, "crop_left", ghb_int64_value(tinfo->crop[2]));
-               ghb_ui_update(ud, "crop_right", ghb_int64_value(tinfo->crop[3]));
-       }
+       if (ghb_settings_get_boolean(ud->settings, "PictureAutoCrop"))
+       {
+               ghb_ui_update(ud, "PictureTopCrop", ghb_int64_value(tinfo->crop[0]));
+               ghb_ui_update(ud, "PictureBottomCrop", ghb_int64_value(tinfo->crop[1]));
+               ghb_ui_update(ud, "PictureLeftCrop", ghb_int64_value(tinfo->crop[2]));
+               ghb_ui_update(ud, "PictureRightCrop", ghb_int64_value(tinfo->crop[3]));
+       }
+       gint width, height, crop[4];
+       crop[0] = ghb_settings_get_int(ud->settings, "PictureTopCrop");
+       crop[1] = ghb_settings_get_int(ud->settings, "PictureBottomCrop");
+       crop[2] = ghb_settings_get_int(ud->settings, "PictureLeftCrop");
+       crop[3] = ghb_settings_get_int(ud->settings, "PictureRightCrop");
+       width = tinfo->width - crop[2] - crop[3];
+       height = tinfo->height - crop[0] - crop[1];
+       widget = GHB_WIDGET (ud->builder, "crop_dimensions");
+       text = g_strdup_printf ("%d x %d", width, height);
+       gtk_label_set_text (GTK_LABEL(widget), text);
+       g_free(text);
+
        g_debug("setting max end chapter %d", tinfo->num_chapters);
        widget = GHB_WIDGET (ud->builder, "end_chapter");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->num_chapters);
@@ -935,137 +996,6 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
 }
 
-static void
-adjust_audio_rate_combos(signal_user_data_t *ud)
-{
-       gint titleindex, audioindex, acodec;
-       ghb_audio_info_t ainfo;
-       GtkWidget *widget;
-       
-       g_debug("adjust_audio_rate_combos ()");
-       titleindex = ghb_settings_get_combo_index(ud->settings, "title");
-
-       widget = GHB_WIDGET(ud->builder, "audio_track");
-       audioindex = ghb_widget_int(widget);
-
-       widget = GHB_WIDGET(ud->builder, "audio_codec");
-       acodec = ghb_widget_int(widget);
-
-       if (ghb_audio_is_passthru (acodec))
-       {
-               if (ghb_get_audio_info (&ainfo, titleindex, audioindex))
-               {
-                       // Set the values for bitrate and samplerate to the input rates
-                       ghb_set_passthru_rate_opts (ud->builder, ainfo.bitrate);
-                       ghb_ui_update(ud, "audio_bitrate", ghb_int64_value(ainfo.bitrate));
-                       ghb_ui_update(ud, "audio_rate", ghb_int64_value(0));
-                       ghb_ui_update(ud, "audio_mix", ghb_int64_value(0));
-               }
-               else
-               {
-                       ghb_ui_update(ud, "audio_rate", ghb_int64_value(0));
-                       ghb_ui_update(ud, "audio_mix", ghb_int64_value(0));
-               }
-       }
-       else
-       {
-               ghb_set_default_rate_opts (ud->builder);
-       }
-}
-
-static void
-set_pref_audio(gint titleindex, signal_user_data_t *ud)
-{
-       gint acodec_code, mix_code, track;
-       gchar *source_lang;
-       GtkWidget *button;
-       ghb_audio_info_t ainfo;
-       gint index;
-       GHashTable *track_indicies;
-       gint *iptr;
-
-       GValue *pref_audio;
-       GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
-       gint count, ii, list_count;
-       
-       g_debug("set_pref_audio");
-       track_indicies = g_hash_table_new(g_int_hash, g_int_equal);
-       // Clear the audio list
-       clear_audio_list(ud);
-       // Find "best" audio based on audio preferences
-       button = GHB_WIDGET (ud->builder, "audio_add");
-       source_lang = ghb_settings_get_string(ud->settings, "source_audio_lang");
-
-       pref_audio = ghb_settings_get_value(ud->settings, "pref_audio_list");
-
-       list_count = 0;
-       count = ghb_array_len(pref_audio);
-       for (ii = 0; ii < count; ii++)
-       {
-               audio = ghb_array_get_nth(pref_audio, ii);
-               acodec = ghb_settings_get_value(audio, "audio_codec");
-               bitrate = ghb_settings_get_value(audio, "audio_bitrate");
-               rate = ghb_settings_get_value(audio, "audio_rate");
-               mix = ghb_settings_get_value(audio, "audio_mix");
-               drc = ghb_settings_get_value(audio, "audio_drc");
-               acodec_code = ghb_lookup_acodec(acodec);
-               // If there are multiple audios using the same codec, then
-               // select sequential tracks for each.  This hash keeps track 
-               // of the last used track for each codec.
-               iptr = g_hash_table_lookup(track_indicies, &acodec_code);
-               if (iptr == NULL)
-                       index = 0;
-               else
-                       index = *(gint*)iptr;
-
-               track = ghb_find_audio_track(titleindex, source_lang, index);
-               // Check to see if:
-               // 1. pref codec is ac3
-               // 2. source codec is not ac3
-               // 3. next pref is enabled
-               if (ghb_get_audio_info (&ainfo, titleindex, track) && 
-                       ghb_audio_is_passthru (acodec_code))
-               {
-                       if (!ghb_audio_is_passthru(ainfo.codec))
-                       {
-                               acodec_code = ghb_get_default_acodec();
-                               // If there's more audio to process, or we've already
-                               // placed one in the list, then we can skip this one
-                               if ((ii + 1 < count) || (list_count != 0))
-                               {
-                                       // Skip this audio
-                                       acodec_code = 0;
-                               }
-                       }
-               }
-               if (titleindex >= 0 && track < 0)
-                       acodec_code = 0;
-               if (acodec_code != 0)
-               {
-                       // Add to audio list
-                       g_signal_emit_by_name(button, "clicked", ud);
-                       list_count++;
-                       ghb_ui_update(ud, "audio_track", ghb_int64_value(track));
-                       ghb_ui_update(ud, "audio_codec", acodec);
-                       if (!ghb_audio_is_passthru (acodec_code))
-                       {
-                               // This gets set autimatically if the codec is passthru
-                               ghb_ui_update(ud, "audio_bitrate", bitrate);
-                               ghb_ui_update(ud, "audio_rate", rate);
-                               mix_code = ghb_lookup_mix(mix);
-                               mix_code = ghb_get_best_mix(
-                                       titleindex, track, acodec_code, mix_code);
-                               ghb_ui_update(ud, "audio_mix", ghb_int64_value(mix_code));
-                       }
-                       ghb_ui_update(ud, "audio_drc", drc);
-                       index++;
-                       g_hash_table_insert(track_indicies, &acodec_code, &index);
-               }
-       }
-       g_free(source_lang);
-       g_hash_table_destroy(track_indicies);
-}
-
 static gint preview_button_width;
 static gint preview_button_height;
 static gboolean update_preview = FALSE;
@@ -1077,7 +1007,9 @@ set_preview_image(signal_user_data_t *ud)
        gint preview_width, preview_height, target_height, width, height;
 
        g_debug("set_preview_button_image ()");
-       gint titleindex = ghb_settings_get_int(ud->settings, "title");
+       gint titleindex;
+
+       titleindex = ghb_settings_combo_int(ud->settings, "title");
        if (titleindex < 0) return;
        widget = GHB_WIDGET (ud->builder, "preview_frame");
        gint frame = ghb_widget_int(widget) - 1;
@@ -1118,29 +1050,27 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_title_info_t tinfo;
        gint titleindex;
-       gchar *preset;
        
        g_debug("title_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-
-       titleindex = ghb_settings_get_int(ud->settings, "title");
-       ghb_update_ui_combo_box (ud->builder, "audio_track", titleindex, FALSE);
-       ghb_update_ui_combo_box (ud->builder, "subtitle_lang", titleindex, FALSE);
-       preset = ghb_settings_get_string (ud->settings, "preset");
-       ghb_update_from_preset(ud, preset, "subtitle_lang");
-       g_free(preset);
+       ghb_check_dependency(ud, widget);
+
+       titleindex = ghb_settings_combo_int(ud->settings, "title");
+       ghb_update_ui_combo_box (ud->builder, "AudioTrack", titleindex, FALSE);
+       ghb_update_ui_combo_box (ud->builder, "Subtitles", titleindex, FALSE);
+
+       ghb_update_from_preset(ud, "Subtitles");
        if (ghb_get_title_info (&tinfo, titleindex))
        {
                show_title_info(ud, &tinfo);
        }
        update_chapter_list (ud);
-       adjust_audio_rate_combos(ud);
-       set_pref_audio(titleindex, ud);
+       ghb_adjust_audio_rate_combos(ud);
+       ghb_set_pref_audio(titleindex, ud);
        if (ghb_settings_get_boolean(ud->settings, "vquality_type_target"))
        {
                gint bitrate = ghb_calculate_target_bitrate (ud->settings, titleindex);
-               ghb_ui_update(ud, "video_bitrate", ghb_int64_value(bitrate));
+               ghb_ui_update(ud, "VideoAvgBitrate", ghb_int64_value(bitrate));
        }
 
        // Unfortunately, there is no way to query how many frames were
@@ -1153,111 +1083,11 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 }
 
 void
-audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       static gint prev_acodec = 0;
-       gint acodec_code, mix_code;
-       GValue *asettings;
-       GValue *pref_audio;
-       GValue *audio, *acodec, *bitrate, *rate, *mix, *drc;
-       
-       g_debug("audio_codec_changed_cb ()");
-       acodec_code = ghb_widget_int(widget);
-       if (ghb_audio_is_passthru (prev_acodec) && 
-               !ghb_audio_is_passthru (acodec_code))
-       {
-               // Transition from passthru to not, put some audio settings back to 
-               // pref settings
-               gint titleindex = ghb_settings_get_int(ud->settings, "title");
-               gint track = ghb_settings_get_int(ud->settings, "audio_track");
-
-               pref_audio = ghb_settings_get_value(ud->settings, "pref_audio_list");
-               audio = ghb_array_get_nth(pref_audio, 0);
-               acodec = ghb_settings_get_value(audio, "audio_codec");
-               bitrate = ghb_settings_get_value(audio, "audio_bitrate");
-               rate = ghb_settings_get_value(audio, "audio_rate");
-               mix = ghb_settings_get_value(audio, "audio_mix");
-               drc = ghb_settings_get_value(audio, "audio_drc");
-
-               ghb_ui_update(ud, "audio_bitrate", bitrate);
-               ghb_ui_update(ud, "audio_rate", rate);
-               mix_code = ghb_lookup_mix(mix);
-               mix_code = ghb_get_best_mix( titleindex, track, acodec_code, mix_code);
-               ghb_ui_update(ud, "audio_mix", ghb_int64_value(mix_code));
-       }
-       adjust_audio_rate_combos(ud);
-       ghb_grey_combo_options (ud->builder);
-       check_depencency(ud, widget);
-       prev_acodec = acodec_code;
-       asettings = get_selected_asettings(ud);
-       if (asettings != NULL)
-       {
-               ghb_widget_to_setting(asettings, widget);
-               audio_list_refresh_selected(ud);
-       }
-
-       const GValue *audio_list;
-       audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-       if (ghb_ac3_in_audio_list (audio_list))
-       {
-               gchar *container;
-
-               container = ghb_settings_get_string(ud->settings, "container");
-               if (strcmp(container, "mp4") == 0)
-               {
-                       ghb_ui_update(ud, "container", ghb_string_value("m4v"));
-               }
-               g_free(container);
-       }
-}
-
-static void audio_list_refresh_selected(signal_user_data_t *ud);
-
-void
-audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       GValue *asettings;
-
-       g_debug("audio_track_changed_cb ()");
-       adjust_audio_rate_combos(ud);
-       check_depencency(ud, widget);
-       ghb_grey_combo_options(ud->builder);
-       asettings = get_selected_asettings(ud);
-       if (asettings != NULL)
-       {
-               ghb_widget_to_setting(asettings, widget);
-               audio_list_refresh_selected(ud);
-       }
-}
-
-void
-audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       GValue *asettings;
-
-       g_debug("audio_widget_changed_cb ()");
-       check_depencency(ud, widget);
-       asettings = get_selected_asettings(ud);
-       if (asettings != NULL)
-       {
-               ghb_widget_to_setting(asettings, widget);
-               audio_list_refresh_selected(ud);
-       }
-}
-
-void
-generic_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       g_debug("generic_widget_changed_cb ()");
-       check_depencency(ud, widget);
-}
-
-void
 setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_check_dependency(ud, widget);
+       ghb_clear_presets_selection(ud);
 }
 
 static void
@@ -1268,7 +1098,7 @@ validate_filter_widget(signal_user_data_t *ud, const gchar *name)
        const gchar *str;
        gboolean foundit = FALSE;
        GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, name));
-       if (ghb_widget_index(GTK_WIDGET(combo)) < 0)
+       if (gtk_combo_box_get_active(combo) < 0)
        { // Validate user input
                gchar *val = ghb_settings_get_string(ud->settings, name);
                store = gtk_combo_box_get_model(combo);
@@ -1297,19 +1127,19 @@ validate_filter_widget(signal_user_data_t *ud, const gchar *name)
 
 gboolean
 deint_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
-    signal_user_data_t *ud)
+       signal_user_data_t *ud)
 {
        g_debug("deint_tweak_focus_out_cb ()");
-       validate_filter_widget(ud, "tweak_deinterlace");
+       validate_filter_widget(ud, "tweak_PictureDeinterlace");
        return FALSE;
 }
 
 gboolean
 denoise_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
-    signal_user_data_t *ud)
+       signal_user_data_t *ud)
 {
        g_debug("denoise_tweak_focus_out_cb ()");
-       validate_filter_widget(ud, "tweak_noise");
+       validate_filter_widget(ud, "tweak_PictureDenoise");
        return FALSE;
 }
 
@@ -1317,93 +1147,87 @@ void
 http_opt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_check_dependency(ud, widget);
+       ghb_clear_presets_selection(ud);
+       // AC3 is not allowed when Web optimized
        ghb_grey_combo_options (ud->builder);
 }
 
 void
 vcodec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
-       gint vqmin, vqmax;
+       gdouble vqmin, vqmax, step, page;
+       gint digits;
+       gint vcodec;
 
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-       clear_presets_selection(ud);
-       ghb_vquality_range(ud, &vqmin, &vqmax);
-       GtkWidget *qp = GHB_WIDGET(ud->builder, "video_quality");
+       ghb_check_dependency(ud, widget);
+       ghb_clear_presets_selection(ud);
+       ghb_vquality_range(ud, &vqmin, &vqmax, &step, &page, &digits);
+       GtkWidget *qp = GHB_WIDGET(ud->builder, "VideoQualitySlider");
        gtk_range_set_range (GTK_RANGE(qp), vqmin, vqmax);
-}
-
-void
-vfr_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       //const gchar *name = gtk_widget_get_name(widget);
-       //g_debug("setting_widget_changed_cb () %s", name);
-       ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-       clear_presets_selection(ud);
-       if (ghb_settings_get_boolean(ud->settings, "variable_frame_rate"))
+       gtk_range_set_increments (GTK_RANGE(qp), step, page);
+       gtk_scale_set_digits(GTK_SCALE(qp), digits);
+       vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
+       if (vcodec != HB_VCODEC_X264 && vcodec != HB_VCODEC_FFMPEG)
        {
-               ghb_ui_update(ud, "framerate", ghb_int64_value(0));
+               ghb_ui_update(ud, "directqp", ghb_boolean_value(FALSE));
        }
 }
 
-// subtitles have their differ from other settings in that
-// the selection is updated automaitcally when the title
-// changes.  I don't want the preset selection changed as
-// would happen for regular settings.
-void
-subtitle_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       const gchar *name = gtk_widget_get_name(widget);
-       g_debug("subtitle_changed_cb () %s", name);
-       ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-}
-
 void
 target_size_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        const gchar *name = gtk_widget_get_name(widget);
        g_debug("setting_widget_changed_cb () %s", name);
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_check_dependency(ud, widget);
+       ghb_clear_presets_selection(ud);
        if (ghb_settings_get_boolean(ud->settings, "vquality_type_target"))
        {
-               gint titleindex = ghb_settings_get_int(ud->settings, "title");
+               gint titleindex;
+               titleindex = ghb_settings_combo_int(ud->settings, "title");
                gint bitrate = ghb_calculate_target_bitrate (ud->settings, titleindex);
-               ghb_ui_update(ud, "video_bitrate", ghb_int64_value(bitrate));
+               ghb_ui_update(ud, "VideoAvgBitrate", ghb_int64_value(bitrate));
        }
 }
 
 void
 start_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
+       gint start, end;
        const gchar *name = gtk_widget_get_name(widget);
+
        g_debug("start_chapter_changed_cb () %s", name);
        ghb_widget_to_setting(ud->settings, widget);
-       GtkWidget *end_ch = GHB_WIDGET (ud->builder, "end_chapter");
-       gdouble start, end;
-       gtk_spin_button_get_range (GTK_SPIN_BUTTON(end_ch), &start, &end);
        start = ghb_settings_get_int(ud->settings, "start_chapter");
-       gtk_spin_button_set_range (GTK_SPIN_BUTTON(end_ch), start, end);
-       check_depencency(ud, widget);
+       end = ghb_settings_get_int(ud->settings, "end_chapter");
+       if (start > end)
+               ghb_ui_update(ud, "end_chapter", ghb_int_value(start));
+       ghb_check_dependency(ud, widget);
+       if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+       {
+               set_destination(ud);
+       }
 }
 
 void
 end_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
+       gint start, end;
        const gchar *name = gtk_widget_get_name(widget);
+
        g_debug("end_chapter_changed_cb () %s", name);
        ghb_widget_to_setting(ud->settings, widget);
-       GtkWidget *start_ch = GHB_WIDGET (ud->builder, "start_chapter");
-       gdouble start, end;
-       gtk_spin_button_get_range (GTK_SPIN_BUTTON(start_ch), &start, &end);
+       start = ghb_settings_get_int(ud->settings, "start_chapter");
        end = ghb_settings_get_int(ud->settings, "end_chapter");
-       gtk_spin_button_set_range (GTK_SPIN_BUTTON(start_ch), start, end);
-       check_depencency(ud, widget);
+       if (start > end)
+               ghb_ui_update(ud, "start_chapter", ghb_int_value(end));
+       ghb_check_dependency(ud, widget);
+       if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+       {
+               set_destination(ud);
+       }
 }
 
 void
@@ -1411,7 +1235,7 @@ scale_width_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("scale_width_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
+       ghb_check_dependency(ud, widget);
        ghb_set_scale (ud, GHB_SCALE_KEEP_WIDTH);
        update_preview = TRUE;
        gchar *text;
@@ -1428,7 +1252,7 @@ scale_height_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("scale_height_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
+       ghb_check_dependency(ud, widget);
        ghb_set_scale (ud, GHB_SCALE_KEEP_HEIGHT);
        update_preview = TRUE;
        gchar *text;
@@ -1448,14 +1272,14 @@ crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        
        g_debug("crop_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
+       ghb_check_dependency(ud, widget);
        ghb_set_scale (ud, GHB_SCALE_KEEP_NONE);
 
-       crop[0] = ghb_settings_get_int(ud->settings, "crop_top");
-       crop[1] = ghb_settings_get_int(ud->settings, "crop_bottom");
-       crop[2] = ghb_settings_get_int(ud->settings, "crop_left");
-       crop[3] = ghb_settings_get_int(ud->settings, "crop_right");
-       titleindex = ghb_settings_get_combo_index(ud->settings, "title");
+       crop[0] = ghb_settings_get_int(ud->settings, "PictureTopCrop");
+       crop[1] = ghb_settings_get_int(ud->settings, "PictureBottomCrop");
+       crop[2] = ghb_settings_get_int(ud->settings, "PictureLeftCrop");
+       crop[3] = ghb_settings_get_int(ud->settings, "PictureRightCrop");
+       titleindex = ghb_settings_combo_int(ud->settings, "title");
        if (ghb_get_title_info (&tinfo, titleindex))
        {
                gint width, height;
@@ -1481,14 +1305,14 @@ scale_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("scale_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       check_depencency(ud, widget);
-       clear_presets_selection(ud);
+       ghb_check_dependency(ud, widget);
+       ghb_clear_presets_selection(ud);
        ghb_set_scale (ud, GHB_SCALE_KEEP_NONE);
        update_preview = TRUE;
        
        gchar *text;
        
-       text = ghb_settings_get_boolean(ud->settings, "autocrop") ? "On" : "Off";
+       text = ghb_settings_get_boolean(ud->settings, "PictureAutoCrop") ? "On" : "Off";
        widget = GHB_WIDGET (ud->builder, "crop_auto");
        gtk_label_set_text (GTK_LABEL(widget), text);
        text = ghb_settings_get_boolean(ud->settings, "autoscale") ? "On" : "Off";
@@ -1516,1380 +1340,90 @@ generic_entry_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
        }
 }
 
-gboolean
-generic_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
-    signal_user_data_t *ud)
-{
-       g_debug("generic_focus_out_cb ()");
-       ghb_widget_to_setting(ud->settings, widget);
-       return FALSE;
-}
-
-// Flag needed to prevent x264 options processing from chasing its tail
-static gboolean ignore_options_update = FALSE;
-
 void
-x264_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+prefs_dialog_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
-       ghb_widget_to_setting(ud->settings, widget);
-       if (!ignore_options_update)
-       {
-               ignore_options_update = TRUE;
-               ghb_x264_opt_update(ud, widget);
-               ignore_options_update = FALSE;
-       }
-       check_depencency(ud, widget);
-       clear_presets_selection(ud);
+       GtkWidget *dialog;
+       GtkResponseType response;
+
+       g_debug("prefs_dialog_cb ()");
+       dialog = GHB_WIDGET(ud->builder, "prefs_dialog");
+       response = gtk_dialog_run(GTK_DIALOG(dialog));
+       gtk_widget_hide(dialog);
 }
 
-void
-x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+gboolean
+ghb_message_dialog(GtkMessageType type, const gchar *message, const gchar *no, const gchar *yes)
 {
-       g_debug("x264_entry_changed_cb ()");
-       if (!ignore_options_update)
+       GtkWidget *dialog;
+       GtkResponseType response;
+                       
+       // Toss up a warning dialog
+       dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
+                                                       type, GTK_BUTTONS_NONE,
+                                                       message);
+       gtk_dialog_add_buttons( GTK_DIALOG(dialog), 
+                                                  no, GTK_RESPONSE_NO,
+                                                  yes, GTK_RESPONSE_YES, NULL);
+       response = gtk_dialog_run(GTK_DIALOG(dialog));
+       gtk_widget_destroy (dialog);
+       if (response == GTK_RESPONSE_NO)
        {
-               GtkWidget *textview;
-               gchar *options;
-
-               textview = GTK_WIDGET(GHB_WIDGET(ud->builder, "x264_options"));
-               ghb_widget_to_setting(ud->settings, textview);
-               options = ghb_settings_get_string(ud->settings, "x264_options");
-               ignore_options_update = TRUE;
-               ghb_x264_parse_options(ud, options);
-               if (!GTK_WIDGET_HAS_FOCUS(textview))
-               {
-                       gchar *sopts;
-
-                       sopts = ghb_sanitize_x264opts(ud, options);
-                       ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
-                       ghb_x264_parse_options(ud, sopts);
-                       g_free(sopts);
-               }
-               g_free(options);
-               ignore_options_update = FALSE;
+               return FALSE;
        }
+       return TRUE;
 }
 
 gboolean
-x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, 
-    signal_user_data_t *ud)
+ghb_cancel_encode(const gchar *extra_msg)
 {
-       gchar *options, *sopts;
-
-       ghb_widget_to_setting(ud->settings, widget);
-       options = ghb_settings_get_string(ud->settings, "x264_options");
-       sopts = ghb_sanitize_x264opts(ud, options);
-       ignore_options_update = TRUE;
-       if (sopts != NULL)
-       {
-               ghb_ui_update(ud, "x264_options", ghb_string_value(sopts));
-               ghb_x264_parse_options(ud, sopts);
-       }
-       g_free(options);
-       g_free(sopts);
-       ignore_options_update = FALSE;
-       return FALSE;
+       GtkWidget *dialog;
+       GtkResponseType response;
+       
+       if (extra_msg == NULL) extra_msg = "";
+       // Toss up a warning dialog
+       dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
+                               GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
+                               "%sYour movie will be lost if you don't continue encoding.",
+                               extra_msg);
+       gtk_dialog_add_buttons( GTK_DIALOG(dialog), 
+                                                  "Continue Encoding", GTK_RESPONSE_NO,
+                                                  "Stop Encoding", GTK_RESPONSE_YES, NULL);
+       response = gtk_dialog_run(GTK_DIALOG(dialog));
+       gtk_widget_destroy (dialog);
+       if (response == GTK_RESPONSE_NO) return FALSE;
+       ghb_stop_queue();
+       return TRUE;
 }
 
 static void
-clear_audio_list(signal_user_data_t *ud)
+submit_job(GValue *settings)
 {
-       GtkTreeView *treeview;
-       GtkListStore *store;
-       GValue *audio_list;
-       
-       g_debug("clear_audio_list ()");
-       audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-       if (audio_list == NULL)
-       {
-               audio_list = ghb_array_value_new(8);
-               ghb_settings_set_value(ud->settings, "audio_list", audio_list);
-       }
-       else
-               ghb_array_value_reset(audio_list, 8);
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-       gtk_list_store_clear (store);
+       static gint unique_id = 1;
+
+       g_debug("submit_job");
+       if (settings == NULL) return;
+       ghb_settings_set_int(settings, "job_unique_id", unique_id);
+       ghb_settings_set_int(settings, "job_status", GHB_QUEUE_RUNNING);
+       ghb_add_job (settings, unique_id);
+       ghb_start_queue();
+       unique_id++;
 }
 
 static void
-add_to_audio_list(signal_user_data_t *ud, GValue *settings)
-{
-       GtkTreeView *treeview;
-       GtkTreeIter iter;
-       GtkListStore *store;
-       GtkTreeSelection *selection;
-       gchar *track, *codec, *br, *sr, *mix, *drc;
-       gchar *s_track, *s_codec, *s_br, *s_sr, *s_mix;
-       gdouble s_drc;
-       
-       g_debug("add_to_audio_list ()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
-       selection = gtk_tree_view_get_selection (treeview);
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-
-       track = ghb_settings_get_combo_option(settings, "audio_track"),
-       codec = ghb_settings_get_combo_option(settings, "audio_codec"),
-       br = ghb_settings_get_combo_option(settings, "audio_bitrate"),
-       sr = ghb_settings_get_combo_option(settings, "audio_rate"),
-       mix = ghb_settings_get_combo_option(settings, "audio_mix"),
-       drc = ghb_settings_get_string(settings, "audio_drc");
-
-       s_track = ghb_settings_get_string(settings, "audio_track"),
-       s_codec = ghb_settings_get_string(settings, "audio_codec"),
-       s_br = ghb_settings_get_string(settings, "audio_bitrate"),
-       s_sr = ghb_settings_get_string(settings, "audio_rate"),
-       s_mix = ghb_settings_get_string(settings, "audio_mix"),
-       s_drc = ghb_settings_get_double(settings, "audio_drc"),
-
-       gtk_list_store_append(store, &iter);
-       gtk_list_store_set(store, &iter, 
-               // These are displayed in list
-               0, track,
-               1, codec,
-               2, br,
-               3, sr,
-               4, mix,
-               // These are used to set combo box values when a list item is selected
-               5, drc,
-               6, s_track,
-               7, s_codec,
-               8, s_br,
-               9, s_sr,
-               10, s_mix,
-               11, s_drc,
-               -1);
-       gtk_tree_selection_select_iter(selection, &iter);
-       g_free(track);
-       g_free(codec);
-       g_free(br);
-       g_free(sr);
-       g_free(mix);
-       g_free(drc);
-       g_free(s_track);
-       g_free(s_codec);
-       g_free(s_br);
-       g_free(s_sr);
-       g_free(s_mix);
-}
-
-static void
-audio_list_refresh_selected(signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreePath *treepath;
-       GtkTreeSelection *selection;
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       gint *indices;
-       gint row;
-       GValue *asettings = NULL;
-       const GValue *audio_list;
-       
-       g_debug("audio_list_refresh_selected ()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
-       selection = gtk_tree_view_get_selection (treeview);
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-               gchar *track, *codec, *br, *sr, *mix, *drc;
-               gchar *s_track, *s_codec, *s_br, *s_sr, *s_mix;
-               gdouble s_drc;
-        // Get the row number
-               treepath = gtk_tree_model_get_path (store, &iter);
-               indices = gtk_tree_path_get_indices (treepath);
-               g_free(treepath);
-               row = indices[0];
-               // find audio settings
-               if (row < 0) return;
-               audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-               if (row >= ghb_array_len(audio_list))
-                       return;
-               asettings = ghb_array_get_nth(audio_list, row);
-
-               track = ghb_settings_get_combo_option(asettings, "audio_track"),
-               codec = ghb_settings_get_combo_option(asettings, "audio_codec"),
-               br = ghb_settings_get_combo_option(asettings, "audio_bitrate"),
-               sr = ghb_settings_get_combo_option(asettings, "audio_rate"),
-               mix = ghb_settings_get_combo_option(asettings, "audio_mix"),
-               drc = ghb_settings_get_string(asettings, "audio_drc");
-
-               s_track = ghb_settings_get_string(asettings, "audio_track"),
-               s_codec = ghb_settings_get_string(asettings, "audio_codec"),
-               s_br = ghb_settings_get_string(asettings, "audio_bitrate"),
-               s_sr = ghb_settings_get_string(asettings, "audio_rate"),
-               s_mix = ghb_settings_get_string(asettings, "audio_mix"),
-               s_drc = ghb_settings_get_double(asettings, "audio_drc"),
-
-               gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
-                       // These are displayed in list
-                       0, track,
-                       1, codec,
-                       2, br,
-                       3, sr,
-                       4, mix,
-                       // These are used to set combo values when a list item is selected
-                       5, drc,
-                       6, s_track,
-                       7, s_codec,
-                       8, s_br,
-                       9, s_sr,
-                       10, s_mix,
-                       11, s_drc,
-                       -1);
-               g_free(track);
-               g_free(codec);
-               g_free(br);
-               g_free(sr);
-               g_free(mix);
-               g_free(drc);
-               g_free(s_track);
-               g_free(s_codec);
-               g_free(s_br);
-               g_free(s_sr);
-               g_free(s_mix);
-       }
-}
-
-static GValue*
-get_selected_asettings(signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreePath *treepath;
-       GtkTreeSelection *selection;
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       gint *indices;
-       gint row;
-       GValue *asettings = NULL;
-       const GValue *audio_list;
-       
-       g_debug("get_selected_asettings ()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
-       selection = gtk_tree_view_get_selection (treeview);
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-        // Get the row number
-               treepath = gtk_tree_model_get_path (store, &iter);
-               indices = gtk_tree_path_get_indices (treepath);
-               g_free(treepath);
-               row = indices[0];
-               // find audio settings
-               if (row < 0) return NULL;
-               audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-               if (row >= ghb_array_len(audio_list))
-                       return NULL;
-               asettings = ghb_array_get_nth(audio_list, row);
-       }
-       return asettings;
-}
-
-void
-audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
-{
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       GtkWidget *widget;
-       
-       g_debug("audio_list_selection_changed_cb ()");
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-               const gchar *track, *codec, *bitrate, *sample_rate, *mix;
-               gdouble drc;
-               gtk_tree_model_get(store, &iter,
-                                                  6, &track,
-                                                  7, &codec,
-                                                  8, &bitrate,
-                                                  9, &sample_rate,
-                                                  10, &mix,
-                                                  11, &drc,
-                                                  -1);
-               ghb_ui_update(ud, "audio_track", ghb_string_value(track));
-               ghb_ui_update(ud, "audio_codec", ghb_string_value(codec));
-               ghb_ui_update(ud, "audio_bitrate", ghb_string_value(bitrate));
-               ghb_ui_update(ud, "audio_rate", ghb_string_value(sample_rate));
-               ghb_ui_update(ud, "audio_mix", ghb_string_value(mix));
-               ghb_ui_update(ud, "audio_drc", ghb_double_value(drc));
-               widget = GHB_WIDGET (ud->builder, "audio_remove");
-               gtk_widget_set_sensitive(widget, TRUE);
-               //widget = GHB_WIDGET (ud->builder, "audio_update");
-               //gtk_widget_set_sensitive(widget, TRUE);
-       }
-       else
-       {
-               widget = GHB_WIDGET (ud->builder, "audio_remove");
-               gtk_widget_set_sensitive(widget, FALSE);
-               //widget = GHB_WIDGET (ud->builder, "audio_update");
-               //gtk_widget_set_sensitive(widget, FALSE);
-       }
-}
-
-void
-audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       // Add the current audio settings to the list.
-       GValue *asettings;
-       GtkWidget *widget;
-       gint count;
-       GValue *audio_list;
-       
-       g_debug("audio_add_clicked_cb ()");
-       asettings = ghb_dict_value_new();
-       // Only allow up to 8 audio entries
-       widget = GHB_WIDGET(ud->builder, "audio_track");
-       ghb_settings_take_value(asettings, "audio_track", ghb_widget_value(widget));
-       widget = GHB_WIDGET(ud->builder, "audio_codec");
-       ghb_settings_take_value(asettings, "audio_codec", ghb_widget_value(widget));
-       widget = GHB_WIDGET(ud->builder, "audio_bitrate");
-       ghb_settings_take_value(asettings, "audio_bitrate", ghb_widget_value(widget));
-       widget = GHB_WIDGET(ud->builder, "audio_rate");
-       ghb_settings_take_value(asettings, "audio_rate", ghb_widget_value(widget));
-       widget = GHB_WIDGET(ud->builder, "audio_mix");
-       ghb_settings_take_value(asettings, "audio_mix", ghb_widget_value(widget));
-       widget = GHB_WIDGET(ud->builder, "audio_drc");
-       ghb_settings_take_value(asettings, "audio_drc", ghb_widget_value(widget));
-
-       audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-       if (audio_list == NULL)
-       {
-               audio_list = ghb_array_value_new(8);
-               ghb_settings_set_value(ud->settings, "audio_list", audio_list);
-       }
-       ghb_array_append(audio_list, asettings);
-       add_to_audio_list(ud, asettings);
-       count = ghb_array_len(audio_list);
-       if (count >= 8)
-       {
-               gtk_widget_set_sensitive(xwidget, FALSE);
-       }
-}
-
-void
-audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreePath *treepath;
-       GtkTreeSelection *selection;
-       GtkTreeModel *store;
-       GtkTreeIter iter, nextIter;
-       gint *indices;
-       gint row;
-       GValue *audio_list;
-
-       g_debug("audio_remove_clicked_cb ()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
-       selection = gtk_tree_view_get_selection (treeview);
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-               nextIter = iter;
-               if (!gtk_tree_model_iter_next(store, &nextIter))
-               {
-                       nextIter = iter;
-                       if (gtk_tree_model_get_iter_first(store, &nextIter))
-                       {
-                               gtk_tree_selection_select_iter (selection, &nextIter);
-                       }
-               }
-               else
-               {
-                       gtk_tree_selection_select_iter (selection, &nextIter);
-               }
-        // Get the row number
-               treepath = gtk_tree_model_get_path (store, &iter);
-               indices = gtk_tree_path_get_indices (treepath);
-               g_free(treepath);
-               row = indices[0];
-               // Remove the selected item
-               gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
-               // remove from audio settings list
-               if (row < 0) return;
-               widget = GHB_WIDGET (ud->builder, "audio_add");
-               gtk_widget_set_sensitive(widget, TRUE);
-               audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-               if (row >= ghb_array_len(audio_list))
-                       return;
-               ghb_array_remove(audio_list, row);
-       }
-}
-
-static void
-audio_list_refresh(signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreeIter iter;
-       GtkListStore *store;
-       gboolean done;
-       gint row = 0;
-       GValue *audio_list;
-
-       g_debug("audio_list_refresh ()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-       if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
-       {
-               do
-               {
-                       gchar *track, *codec, *br, *sr, *mix, *drc;
-                       gchar *s_track, *s_codec, *s_br, *s_sr, *s_mix;
-                       gdouble s_drc;
-                       GValue *asettings;
-
-                       audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-                       if (row >= ghb_array_len(audio_list))
-                               return;
-                       asettings = ghb_array_get_nth(audio_list, row);
-
-                       track = ghb_settings_get_combo_option(asettings, "audio_track"),
-                       codec = ghb_settings_get_combo_option(asettings, "audio_codec"),
-                       br = ghb_settings_get_combo_option(asettings, "audio_bitrate"),
-                       sr = ghb_settings_get_combo_option(asettings, "audio_rate"),
-                       mix = ghb_settings_get_combo_option(asettings, "audio_mix"),
-                       drc = ghb_settings_get_string(asettings, "audio_drc");
-
-                       s_track = ghb_settings_get_string(asettings, "audio_track"),
-                       s_codec = ghb_settings_get_string(asettings, "audio_codec"),
-                       s_br = ghb_settings_get_string(asettings, "audio_bitrate"),
-                       s_sr = ghb_settings_get_string(asettings, "audio_rate"),
-                       s_mix = ghb_settings_get_string(asettings, "audio_mix"),
-                       s_drc = ghb_settings_get_double(asettings, "audio_drc");
-
-                       gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
-                               // These are displayed in list
-                               0, track,
-                               1, codec,
-                               2, br,
-                               3, sr,
-                               4, mix,
-                               // These are used to set combo values when an item is selected
-                               5, drc,
-                               6, s_track,
-                               7, s_codec,
-                               8, s_br,
-                               9, s_sr,
-                               10, s_mix,
-                               11, s_drc,
-                               -1);
-                       g_free(track);
-                       g_free(codec);
-                       g_free(br);
-                       g_free(sr);
-                       g_free(mix);
-                       g_free(drc);
-                       g_free(s_track);
-                       g_free(s_codec);
-                       g_free(s_br);
-                       g_free(s_sr);
-                       g_free(s_mix);
-                       done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
-                       row++;
-               } while (!done);
-       }
-}
-
-void
-ghb_presets_list_update(signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreeIter iter;
-       GtkListStore *store;
-       gboolean done;
-       GList *presets, *plink;
-       gchar *preset, *def_preset;
-       gchar *description;
-       gint flags, custom, def;
-       
-       g_debug("ghb_presets_list_update ()");
-       def_preset = ghb_settings_get_string(ud->settings, "default_preset");
-       plink = presets = ghb_presets_get_names();
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
-       store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-       if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
-       {
-               do
-               {
-                       if (plink)
-                       {
-                               // Update row with settings data
-                               g_debug("Updating row");
-                               preset = (gchar*)plink->data;
-                               def = 0;
-                               if (strcmp(preset, def_preset) == 0)
-                                       def = PRESET_DEFAULT;
-                               
-                               description = ghb_presets_get_description(preset);
-                               flags = ghb_preset_flags(preset);
-                               custom = flags & PRESET_CUSTOM;
-                               gtk_list_store_set(store, &iter, 
-                                                       0, preset, 
-                                                       1, def ? 800 : 400, 
-                                                       2, def ? 2 : 0,
-                                                       3, custom ? "black" : "blue", 
-                                                       4, description,
-                                                       -1);
-                               plink = plink->next;
-                               g_free(description);
-                               done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
-                       }
-                       else
-                       {
-                               // No more settings data, remove row
-                               g_debug("Removing row");
-                               done = !gtk_list_store_remove(store, &iter);
-                       }
-               } while (!done);
-       }
-       while (plink)
-       {
-               // Additional settings, add row
-               g_debug("Adding rows");
-               preset = (gchar*)plink->data;
-               def = 0;
-               if (strcmp(preset, def_preset) == 0)
-                       def = PRESET_DEFAULT;
-
-               description = ghb_presets_get_description(preset);
-               gtk_list_store_append(store, &iter);
-               flags = ghb_preset_flags(preset);
-               custom = flags & PRESET_CUSTOM;
-               gtk_list_store_set(store, &iter, 0, preset, 
-                                                       1, def ? 800 : 400, 
-                                                       2, def ? 2 : 0,
-                                                       3, custom ? "black" : "blue", 
-                                                       4, description,
-                                                       -1);
-               plink = plink->next;
-               g_free(description);
-       }
-       g_free(def_preset);
-       g_list_free (presets);
-}
-
-void
-ghb_select_preset(GtkBuilder *builder, const gchar *preset)
-{
-       GtkTreeView *treeview;
-       GtkTreeSelection *selection;
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       gchar *tpreset;
-       gboolean done;
-       gboolean foundit = FALSE;
-       
-       g_debug("select_preset()");
-       if (preset == NULL) return;
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "presets_list"));
-       selection = gtk_tree_view_get_selection (treeview);
-       store = gtk_tree_view_get_model (treeview);
-       if (gtk_tree_model_get_iter_first(store, &iter))
-       {
-               do
-               {
-                       gtk_tree_model_get(store, &iter, 0, &tpreset, -1);
-                       if (strcmp(preset, tpreset) == 0)
-                       {
-                               gtk_tree_selection_select_iter (selection, &iter);
-                               foundit = TRUE;
-                               break;
-                       }
-                       done = !gtk_tree_model_iter_next(store, &iter);
-               } while (!done);
-       }
-       if (!foundit)
-       {
-               gtk_tree_model_get_iter_first(store, &iter);
-               gtk_tree_selection_select_iter (selection, &iter);
-       }
-}
-
-static void
-update_audio_presets(signal_user_data_t *ud)
-{
-       g_debug("update_audio_presets");
-       const GValue *audio_list;
-
-       audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-       ghb_settings_set_value(ud->settings, "pref_audio_list", audio_list);
-}
-
-void
-presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       GtkWidget *dialog;
-       GtkEntry *entry;
-       GtkTextView *desc;
-       GtkResponseType response;
-       gchar *preset;
-
-       g_debug("presets_save_clicked_cb ()");
-       preset = ghb_settings_get_string (ud->settings, "preset");
-       // Clear the description
-       desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "preset_description"));
-       dialog = GHB_WIDGET(ud->builder, "preset_save_dialog");
-       entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "preset_name"));
-       gtk_entry_set_text(entry, preset);
-       g_free(preset);
-       response = gtk_dialog_run(GTK_DIALOG(dialog));
-       gtk_widget_hide(dialog);
-       if (response == GTK_RESPONSE_OK)
-       {
-               // save the preset
-               const gchar *name = gtk_entry_get_text(entry);
-               g_debug("description to settings");
-               ghb_widget_to_setting(ud->settings, GTK_WIDGET(desc));
-               // Construct the audio settings presets from the current audio list
-               update_audio_presets(ud);
-               ghb_settings_save(ud, name);
-               ghb_presets_list_update(ud);
-               // Make the new preset the selected item
-               ghb_select_preset(ud->builder, name);
-       }
-}
-
-void
-presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       g_debug("presets_restore_clicked_cb ()");
-       // Reload only the standard presets
-       ghb_presets_reload(ud);
-       ghb_presets_list_update(ud);
-       // Updating the presets list shuffles things around
-       // need to make sure the proper preset is selected
-       gchar *preset = ghb_settings_get_string (ud->settings, "preset");
-       ghb_select_preset(ud->builder, preset);
-       g_free(preset);
-}
-
-void
-prefs_dialog_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       GtkWidget *dialog;
-       GtkResponseType response;
-
-       g_debug("prefs_dialog_cb ()");
-       dialog = GHB_WIDGET(ud->builder, "prefs_dialog");
-       response = gtk_dialog_run(GTK_DIALOG(dialog));
-       gtk_widget_hide(dialog);
-}
-
-void
-presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreeSelection *selection;
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       gchar *preset;
-       GtkResponseType response;
-
-       g_debug("presets_remove_clicked_cb ()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
-       selection = gtk_tree_view_get_selection (treeview);
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-               GtkWidget *dialog;
-
-               gtk_tree_model_get(store, &iter, 0, &preset, -1);
-               dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
-                                                               GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
-                                                               "Confirm deletion of preset %s.", preset);
-               response = gtk_dialog_run(GTK_DIALOG(dialog));
-               gtk_widget_destroy (dialog);
-               if (response == GTK_RESPONSE_YES)
-               {
-                       GtkTreeIter nextIter = iter;
-                       gchar *nextPreset = NULL;
-                       if (!gtk_tree_model_iter_next(store, &nextIter))
-                       {
-                               if (gtk_tree_model_get_iter_first(store, &nextIter))
-                               {
-                                       gtk_tree_model_get(store, &nextIter, 0, &nextPreset, -1);
-                               }
-                       }
-                       else
-                       {
-                               gtk_tree_model_get(store, &nextIter, 0, &nextPreset, -1);
-                       }
-                       // Remove the selected item
-                       // First unselect it so that selecting the new item works properly
-                       gtk_tree_selection_unselect_iter (selection, &iter);
-                       ghb_presets_remove(preset);
-                       ghb_presets_list_update(ud);
-                       ghb_select_preset(ud->builder, nextPreset);
-               }
-       }
-}
-
-static void
-preset_update_title_deps(signal_user_data_t *ud, ghb_title_info_t *tinfo)
-{
-       GtkWidget *widget;
-
-       ghb_ui_update(ud, "scale_width", 
-                       ghb_int64_value(tinfo->width - tinfo->crop[2] - tinfo->crop[3]));
-       // If anamorphic or keep_aspect, the hight will be automatically calculated
-       gboolean keep_aspect, anamorphic;
-       keep_aspect = ghb_settings_get_boolean(ud->settings, "keep_aspect");
-       anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
-       if (!(keep_aspect || anamorphic))
-       {
-               ghb_ui_update(ud, "scale_height", 
-                       ghb_int64_value(tinfo->height - tinfo->crop[0] - tinfo->crop[1]));
-       }
-
-       // Set the limits of cropping.  hb_set_anamorphic_size crashes if
-       // you pass it a cropped width or height == 0.
-       gint bound;
-       bound = tinfo->height / 2 - 2;
-       widget = GHB_WIDGET (ud->builder, "crop_top");
-       gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       widget = GHB_WIDGET (ud->builder, "crop_bottom");
-       gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       bound = tinfo->width / 2 - 2;
-       widget = GHB_WIDGET (ud->builder, "crop_left");
-       gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       widget = GHB_WIDGET (ud->builder, "crop_right");
-       gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       if (ghb_settings_get_boolean(ud->settings, "autocrop"))
-       {
-               ghb_ui_update(ud, "crop_top", ghb_int64_value(tinfo->crop[0]));
-               ghb_ui_update(ud, "crop_bottom", ghb_int64_value(tinfo->crop[1]));
-               ghb_ui_update(ud, "crop_left", ghb_int64_value(tinfo->crop[2]));
-               ghb_ui_update(ud, "crop_right", ghb_int64_value(tinfo->crop[3]));
-       }
-}
-
-void
-presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
-{
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       gchar *preset;
-       ghb_title_info_t tinfo;
-       GtkWidget *widget;
-       
-       g_debug("presets_list_selection_changed_cb ()");
-       widget = GHB_WIDGET (ud->builder, "presets_remove");
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-               gtk_tree_model_get(store, &iter, 0, &preset, -1);
-               ud->dont_clear_presets = TRUE;
-               // Temporarily set the video_quality range to (0,100)
-               // This is needed so the video_quality value does not get
-               // truncated when set.  The range will be readjusted below
-               GtkWidget *qp = GHB_WIDGET(ud->builder, "video_quality");
-               gtk_range_set_range (GTK_RANGE(qp), 0, 100);
-               // Clear the audio list prior to changing the preset.  Existing audio
-               // can cause the container extension to be automatically changed when
-               // it shouldn't be
-               clear_audio_list(ud);
-               ghb_set_preset(ud, preset);
-               gint titleindex = ghb_settings_get_int(ud->settings, "title");
-               set_pref_audio(titleindex, ud);
-               ud->dont_clear_presets = FALSE;
-               if (ghb_get_title_info (&tinfo, titleindex))
-               {
-                       preset_update_title_deps(ud, &tinfo);
-               }
-               ghb_set_scale (ud, GHB_SCALE_KEEP_NONE);
-
-               gint vqmin, vqmax;
-               ghb_vquality_range(ud, &vqmin, &vqmax);
-               gtk_range_set_range (GTK_RANGE(qp), vqmin, vqmax);
-               gtk_widget_set_sensitive(widget, TRUE);
-       }
-       else
-       {
-               g_debug("No selection???  Perhaps unselected.");
-               gtk_widget_set_sensitive(widget, FALSE);
-       }
-}
-
-void
-queue_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
-{
-       GtkTreeModel *store;
-       GtkTreeIter iter, piter;
-       
-       g_debug("queue_list_selection_changed_cb ()");
-       // A queue entry is made up of a parent and multiple
-       // children that are visible when expanded.  When and entry
-       // is selected, I want the parent to be selected.
-       // This is purely cosmetic.
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-               if (gtk_tree_model_iter_parent (store, &piter, &iter))
-               {
-                       GtkTreePath *path;
-                       GtkTreeView *treeview;
-                       
-                       gtk_tree_selection_select_iter (selection, &piter);
-                       path = gtk_tree_model_get_path (store, &piter);
-                       treeview = gtk_tree_selection_get_tree_view (selection);
-                       // Make the parent visible in scroll window if it is not.
-                       gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0, 0);
-                       g_free(path);
-               }
-       }
-}
-
-static void
-add_to_queue_list(signal_user_data_t *ud, GValue *settings)
-{
-       GtkTreeView *treeview;
-       GtkTreeIter iter;
-       GtkTreeStore *store;
-       gchar *info;
-       gint num_pass = 1;
-       gint ii;
-       GtkTreeIter citer;
-       gchar *vcodec, *container, *acodec, *dest, *preset, *vol_name;
-       gchar *fps, *vcodec_abbr;
-       gint title, start_chapter, end_chapter, width, height, vqvalue;
-       gboolean pass2, anamorphic, round_dim, keep_aspect, vqtype, turbo;
-       
-       g_debug("update_queue_list ()");
-       if (settings == NULL) return;
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
-       store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
-               
-       title = ghb_settings_get_int(settings, "title");
-       start_chapter = ghb_settings_get_int(settings, "start_chapter");
-       end_chapter = ghb_settings_get_int(settings, "end_chapter");
-       pass2 = ghb_settings_get_boolean(settings, "two_pass");
-       vol_name = ghb_settings_get_string(settings, "volume_label");
-       info = g_strdup_printf 
-       (
-                "<big><b>%s</b></big> (Title %d, Chapters %d through %d, %d Video %s)",
-                vol_name, title+1, start_chapter, end_chapter, 
-                pass2 ? 2:1, pass2 ? "Passes":"Pass"
-       );
-
-       gtk_tree_store_append(store, &iter, NULL);
-       gtk_tree_store_set(store, &iter, 0, "hb-queue-job", 1, info, 2, "hb-queue-delete", -1);
-       g_free(info);
-
-       vcodec = ghb_settings_get_combo_option(settings, "video_codec");
-       container = ghb_settings_get_combo_option(settings, "container");
-       acodec = ghb_settings_get_combo_option(settings, "audio_codec");
-       dest = ghb_settings_get_string(settings, "destination");
-       preset = ghb_settings_get_string(settings, "preset");
-       info = g_strdup_printf 
-               (
-                "<b>Preset:</b> %s\n"
-                "<b>Format:</b> %s Container, %s Video + %s Audio\n"
-                "<b>Destination:</b> %s",
-                preset, container, vcodec, acodec, dest);
-
-       gtk_tree_store_append(store, &citer, &iter);
-       gtk_tree_store_set(store, &citer, 1, info, -1);
-       g_free(info);
-
-       width = ghb_settings_get_int(settings, "scale_width");
-       height = ghb_settings_get_int(settings, "scale_height");
-       anamorphic = ghb_settings_get_boolean(settings, "anamorphic");
-       round_dim = ghb_settings_get_boolean(settings, "round_dimensions");
-       keep_aspect = ghb_settings_get_boolean(settings, "keep_aspect");
-
-       gchar *aspect_desc;
-       if (anamorphic)
-       {
-               if (round_dim)
-               {
-                       aspect_desc = "(Anamorphic)";
-               }
-               else
-               {
-                       aspect_desc = "(Strict Anamorphic)";
-               }
-       }
-       else
-       {
-               if (keep_aspect)
-               {
-                       aspect_desc = "(Aspect Preserved)";
-               }
-               else
-               {
-                       aspect_desc = "(Aspect Lost)";
-               }
-       }
-       vqtype = ghb_settings_get_boolean(settings, "vquality_type_constant");
-       vqvalue = 0;
-
-       gchar *vq_desc = "Error";
-       if (!vqtype)
-       {
-               vqtype = ghb_settings_get_boolean(settings, "vquality_type_target");
-               if (!vqtype)
-               {
-                       // Has to be bitrate
-                       vqvalue = ghb_settings_get_int(settings, "video_bitrate");
-                       vq_desc = "kbps";
-               }
-               else
-               {
-                       // Target file size
-                       vqvalue = ghb_settings_get_int(settings, "video_target");
-                       vq_desc = "MB";
-               }
-       }
-       else
-       {
-               // Constant quality
-               vqvalue = ghb_settings_get_int(settings, "video_quality");
-               vq_desc = "% Constant Quality";
-       }
-       fps = ghb_settings_get_string(settings, "framerate");
-       vcodec_abbr = ghb_settings_get_string(settings, "video_codec");
-       gchar *extra_opts;
-       if (strcmp(vcodec_abbr, "x264") == 0)
-       {
-               gchar *x264opts = ghb_build_x264opts_string(settings);
-               extra_opts = g_strdup_printf ("\n<b>x264 Options:</b> %s", x264opts);
-               g_free(x264opts);
-       }
-       else
-       {
-               extra_opts = g_strdup("");
-       }
-       turbo = ghb_settings_get_boolean(settings, "turbo");
-       gchar *turbo_desc = "\n<b>Turbo:</b> Off";;
-       if (turbo)
-       {
-               turbo_desc = "\n<b>Turbo:</b> On";
-       }
-       num_pass = pass2 ? 2 : 1;
-       for (ii = 0; ii < num_pass; ii++)
-       {
-               gboolean final = (ii == (num_pass - 1));
-               GString *pass = g_string_new("");
-               g_string_append_printf( pass,
-                       "<b>%s Pass</b>\n"
-                       "<b>Picture:</b> %d x %d %s\n"
-                       "<b>Video:</b> %s, %d %s, %s fps"
-                       "%s",
-                        ii ? "2nd":"1st", width, height, aspect_desc,
-                        vcodec, vqvalue, vq_desc, fps, 
-                        final ? extra_opts : turbo_desc);
-
-               if (final)
-               {
-                       // Add the audios
-                       gint count, ii;
-                       const GValue *audio_list;
-
-                       audio_list = ghb_settings_get_value(settings, "audio_list");
-                       count = ghb_array_len(audio_list);
-                       for (ii = 0; ii < count; ii++)
-                       {
-                               gchar *acodec, *bitrate, *samplerate, *mix;
-                               GValue *asettings;
-
-                               asettings = ghb_array_get_nth(audio_list, ii);
-
-                               acodec = ghb_settings_get_combo_option(asettings, "audio_codec");
-                               bitrate = ghb_settings_get_string(asettings, "audio_bitrate");
-                               samplerate = ghb_settings_get_string(asettings, "audio_rate");
-                               gint track = ghb_settings_get_int(asettings, "audio_track");
-                               mix = ghb_settings_get_combo_option(asettings, "audio_mix");
-                               g_string_append_printf(pass,
-                                       "\n<b>Audio:</b> %s, %s kbps, %s kHz, Track %d: %s",
-                                        acodec, bitrate, samplerate, track+1, mix);
-                               g_free(acodec);
-                               g_free(bitrate);
-                               g_free(samplerate);
-                               g_free(mix);
-                       }
-               }
-               info = g_string_free(pass, FALSE);
-               gtk_tree_store_append(store, &citer, &iter);
-               gtk_tree_store_set(store, &citer, 0, ii ? "hb-queue-pass2" : "hb-queue-pass1", 1, info, -1);
-               g_free(info);
-       }
-       g_free(fps);
-       g_free(vcodec_abbr);
-       g_free(vol_name);
-       g_free(vcodec);
-       g_free(container);
-       g_free(acodec);
-       g_free(dest);
-       g_free(preset);
-       g_free(extra_opts);
-}
-
-gboolean
-ghb_message_dialog(GtkMessageType type, const gchar *message, const gchar *no, const gchar *yes)
-{
-       GtkWidget *dialog;
-       GtkResponseType response;
-                       
-       // Toss up a warning dialog
-       dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
-                                                       type, GTK_BUTTONS_NONE,
-                                                       message);
-       gtk_dialog_add_buttons( GTK_DIALOG(dialog), 
-                                                  no, GTK_RESPONSE_NO,
-                                                  yes, GTK_RESPONSE_YES, NULL);
-       response = gtk_dialog_run(GTK_DIALOG(dialog));
-       gtk_widget_destroy (dialog);
-       if (response == GTK_RESPONSE_NO)
-       {
-               return FALSE;
-       }
-       return TRUE;
-}
-
-static gint64
-estimate_file_size(signal_user_data_t *ud)
-{
-       ghb_title_info_t tinfo;
-       gint duration;
-       gint bitrate;
-       gint64 size;
-       gint titleindex = ghb_settings_get_int(ud->settings, "title");
-       if (titleindex < 0) return 0;
-                       
-       if (!ghb_get_title_info(&tinfo, titleindex)) return 0;
-       duration = ((tinfo.hours*60)+tinfo.minutes)*60+tinfo.seconds;
-       bitrate = ghb_guess_bitrate(ud->settings);
-       size = (gint64)duration * (gint64)bitrate/8;
-       return size;
-}
-
-#define DISK_FREE_THRESH       (1024L*1024L*1024L*3)
-
-static gboolean
-validate_settings(signal_user_data_t *ud)
-{
-       // Check to see if the dest file exists or is
-       // already in the queue
-       gchar *message, *dest;
-       gint count, ii;
-       gint titleindex = ghb_settings_get_int(ud->settings, "title");
-
-       if (titleindex < 0) return FALSE;
-       dest = ghb_settings_get_string(ud->settings, "destination");
-       count = ghb_array_len(ud->queue);
-       for (ii = 0; ii < count; ii++)
-       {
-               GValue *js;
-               gchar *filename;
-
-               js = ghb_array_get_nth(ud->queue, ii);
-               filename = ghb_settings_get_string(js, "destination");
-               if (strcmp(dest, filename) == 0)
-               {
-                       message = g_strdup_printf(
-                                               "Destination: %s\n\n"
-                                               "Another queued job has specified the same destination.\n"
-                                               "Do you want to overwrite?",
-                                               dest);
-                       if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
-                       {
-                               g_free(filename);
-                               g_free(dest);
-                               g_free(message);
-                               return FALSE;
-                       }
-                       g_free(message);
-                       break;
-               }
-               g_free(filename);
-       }
-       gchar *destdir = g_path_get_dirname(dest);
-       if (!g_file_test(destdir, G_FILE_TEST_IS_DIR))
-       {
-               message = g_strdup_printf(
-                                       "Destination: %s\n\n"
-                                       "This is not a valid directory.",
-                                       destdir);
-               ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
-               g_free(dest);
-               g_free(message);
-               g_free(destdir);
-               return FALSE;
-       }
-       if (g_access(destdir, R_OK|W_OK) != 0)
-       {
-               message = g_strdup_printf(
-                                       "Destination: %s\n\n"
-                                       "Can not read or write the directory.",
-                                       destdir);
-               ghb_message_dialog(GTK_MESSAGE_ERROR, message, "Cancel", NULL);
-               g_free(dest);
-               g_free(message);
-               g_free(destdir);
-               return FALSE;
-       }
-       GFile *gfile;
-       GFileInfo *info;
-       guint64 size;
-       gchar *resolved = ghb_resolve_symlink(destdir);
-
-       gfile = g_file_new_for_path(resolved);
-       info = g_file_query_filesystem_info(gfile, 
-                                               G_FILE_ATTRIBUTE_FILESYSTEM_FREE, NULL, NULL);
-       if (info != NULL)
-       {
-               if (g_file_info_has_attribute(info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE))
-               {
-                       size = g_file_info_get_attribute_uint64(info, 
-                                                                       G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
-                       
-                       gint64 fsize = estimate_file_size(ud);
-                       if (size < fsize)
-                       {
-                               message = g_strdup_printf(
-                                                       "Destination filesystem is almost full: %uM free\n\n"
-                                                       "Encode may be incomplete if you proceed.\n",
-                                                       (guint)(size / (1024L*1024L)));
-                               if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Proceed"))
-                               {
-                                       g_free(dest);
-                                       g_free(message);
-                                       return FALSE;
-                               }
-                               g_free(message);
-                       }
-               }
-               g_object_unref(info);
-       }
-       g_object_unref(gfile);
-       g_free(resolved);
-       g_free(destdir);
-       if (g_file_test(dest, G_FILE_TEST_EXISTS))
-       {
-               message = g_strdup_printf(
-                                       "Destination: %s\n\n"
-                                       "File already exhists.\n"
-                                       "Do you want to overwrite?",
-                                       dest);
-               if (!ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "Cancel", "Overwrite"))
-               {
-                       g_free(dest);
-                       g_free(message);
-                       return FALSE;
-               }
-               g_free(message);
-               g_unlink(dest);
-       }
-       g_free(dest);
-       // Validate video quality is in a reasonable range
-       if (!ghb_validate_vquality(ud->settings))
-       {
-               return FALSE;
-       }
-       // Validate audio settings
-       if (!ghb_validate_audio(ud))
-       {
-               return FALSE;
-       }
-       // Validate video settings
-       if (!ghb_validate_video(ud))
-       {
-               return FALSE;
-       }
-       // Validate container settings
-       if (!ghb_validate_container(ud))
-       {
-               return FALSE;
-       }
-       // Validate filter settings
-       if (!ghb_validate_filters(ud))
-       {
-               return FALSE;
-       }
-       audio_list_refresh(ud);
-       return TRUE;
-}
-
-static gboolean
-queue_add(signal_user_data_t *ud)
-{
-       // Add settings to the queue
-       GValue *settings;
-       
-       g_debug("queue_add ()");
-       if (!validate_settings(ud))
-       {
-               return FALSE;
-       }
-       if (ud->queue == NULL)
-               ud->queue = ghb_array_value_new(32);
-       // Make a copy of current settings to be used for the new job
-       settings = ghb_value_dup(ud->settings);
-       ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
-       ghb_settings_set_int(settings, "job_unique_id", 0);
-       ghb_array_append(ud->queue, settings);
-       add_to_queue_list(ud, settings);
-       ghb_save_queue(ud->queue);
-
-       return TRUE;
-}
-
-void
-queue_add_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       g_debug("queue_add_clicked_cb ()");
-       queue_add(ud);
-}
-
-static gboolean
-cancel_encode(const gchar *extra_msg)
-{
-       GtkWidget *dialog;
-       GtkResponseType response;
-       
-       if (extra_msg == NULL) extra_msg = "";
-       // Toss up a warning dialog
-       dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
-                               GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
-                               "%sYour movie will be lost if you don't continue encoding.",
-                               extra_msg);
-       gtk_dialog_add_buttons( GTK_DIALOG(dialog), 
-                                                  "Continue Encoding", GTK_RESPONSE_NO,
-                                                  "Stop Encoding", GTK_RESPONSE_YES, NULL);
-       response = gtk_dialog_run(GTK_DIALOG(dialog));
-       gtk_widget_destroy (dialog);
-       if (response == GTK_RESPONSE_NO) return FALSE;
-       ghb_stop_queue();
-       return TRUE;
-}
-
-void
-queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreePath *treepath;
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       gint row;
-       gint *indices;
-       gint unique_id;
-       GValue *settings;
-       gint status;
-
-       g_debug("queue_remove_clicked_cb ()");
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
-       store = gtk_tree_view_get_model(treeview);
-       treepath = gtk_tree_path_new_from_string (path);
-       if (gtk_tree_model_get_iter(store, &iter, treepath))
-       {
-               // Find the entry in the queue
-               indices = gtk_tree_path_get_indices (treepath);
-               row = indices[0];
-               // Can only free the treepath After getting what I need from
-               // indices since this points into treepath somewhere.
-               gtk_tree_path_free (treepath);
-               if (row < 0) return;
-               if (row >= ghb_array_len(ud->queue))
-                       return;
-               settings = ghb_array_get_nth(ud->queue, row);
-               status = ghb_settings_get_int(settings, "job_status");
-               if (status == GHB_QUEUE_RUNNING)
-               {
-                       // Ask if wants to stop encode.
-                       if (!cancel_encode(NULL))
-                       {
-                               return;
-                       }
-                       unique_id = ghb_settings_get_int(settings, "job_unique_id");
-                       ghb_remove_job(unique_id);
-               }
-               // Remove the selected item
-               gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
-               // Remove the corresponding item from the queue list
-               ghb_array_remove(ud->queue, row);
-       }
-       else
-       {       
-               gtk_tree_path_free (treepath);
-       }
-}
-
-static gint
-find_queue_job(GValue *queue, gint unique_id, GValue **job)
-{
-       GValue *js;
-       gint ii, count;
-       gint job_unique_id;
-       
-       *job = NULL;
-       g_debug("find_queue_job");
-       count = ghb_array_len(queue);
-       for (ii = 0; ii < count; ii++)
-       {
-               js = ghb_array_get_nth(queue, ii);
-               job_unique_id = ghb_settings_get_int(js, "job_unique_id");
-               if (job_unique_id == unique_id)
-               {
-                       *job = js;
-                       return ii;
-               }
-       }
-       return -1;
-}
-
-static void
-queue_buttons_grey(signal_user_data_t *ud, gboolean working)
-{
-       GtkWidget *widget;
-       GtkAction *action;
-       gint queue_count;
-       gint titleindex;
-       gboolean title_ok;
-
-       queue_count = ghb_array_len(ud->queue);
-       titleindex = ghb_settings_get_int(ud->settings, "title");
-       title_ok = (titleindex >= 0);
-
-       widget = GHB_WIDGET (ud->builder, "queue_start1");
-       gtk_widget_set_sensitive (widget, !working && (title_ok || queue_count));
-       widget = GHB_WIDGET (ud->builder, "queue_start2");
-       gtk_widget_set_sensitive (widget, !working && (title_ok || queue_count));
-       action = GHB_ACTION (ud->builder, "queue_start_menu");
-       gtk_action_set_sensitive (action, !working && (title_ok || queue_count));
-       widget = GHB_WIDGET (ud->builder, "queue_pause1");
-       gtk_widget_set_sensitive (widget, working);
-       widget = GHB_WIDGET (ud->builder, "queue_pause2");
-       gtk_widget_set_sensitive (widget, working);
-       action = GHB_ACTION (ud->builder, "queue_pause_menu");
-       gtk_action_set_sensitive (action, working);
-       widget = GHB_WIDGET (ud->builder, "queue_stop");
-       gtk_widget_set_sensitive (widget, working);
-       action = GHB_ACTION (ud->builder, "queue_stop_menu");
-       gtk_action_set_sensitive (action, working);
-}
-
-void queue_start_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud);
-
-static void
-submit_job(GValue *settings)
-{
-       static gint unique_id = 1;
-
-       g_debug("submit_job");
-       if (settings == NULL) return;
-       ghb_settings_set_int(settings, "job_unique_id", unique_id);
-       ghb_settings_set_int(settings, "job_status", GHB_QUEUE_RUNNING);
-       ghb_add_job (settings, unique_id);
-       ghb_start_queue();
-       unique_id++;
-}
-
-static void
-queue_scan(GValue *js)
+queue_scan(GValue *js)
 {
        gchar *path;
-       gint titleindex;
+       gint titlenum;
 
        path = ghb_settings_get_string( js, "source");
-       titleindex = ghb_settings_get_int(js, "title");
-       ghb_backend_queue_scan(path, titleindex+1);
+       titlenum = ghb_settings_get_int(js, "titlenum");
+       ghb_backend_queue_scan(path, titlenum);
        g_free(path);
 }
 
-static GValue* 
-start_next_job(signal_user_data_t *ud, gboolean find_first)
+GValue* 
+ghb_start_next_job(signal_user_data_t *ud, gboolean find_first)
 {
        static gint current = 0;
        gint count, ii, jj;
@@ -2953,6 +1487,78 @@ start_next_job(signal_user_data_t *ud, gboolean find_first)
        return NULL;
 }
 
+static gint
+find_queue_job(GValue *queue, gint unique_id, GValue **job)
+{
+       GValue *js;
+       gint ii, count;
+       gint job_unique_id;
+       
+       *job = NULL;
+       g_debug("find_queue_job");
+       count = ghb_array_len(queue);
+       for (ii = 0; ii < count; ii++)
+       {
+               js = ghb_array_get_nth(queue, ii);
+               job_unique_id = ghb_settings_get_int(js, "job_unique_id");
+               if (job_unique_id == unique_id)
+               {
+                       *job = js;
+                       return ii;
+               }
+       }
+       return -1;
+}
+
+gchar*
+working_status_string(signal_user_data_t *ud, ghb_status_t *status)
+{
+       gchar *task_str, *job_str, *status_str;
+       gint qcount;
+       gint index;
+       GValue *js;
+
+       if (status->job_count > 1)
+       {
+               task_str = g_strdup_printf("pass %d of %d, ", 
+                       status->job_cur, status->job_count);
+       }
+       else
+       {
+               task_str = g_strdup("");
+       }
+       qcount = ghb_array_len(ud->queue);
+       if (qcount > 1)
+       {
+               index = find_queue_job(ud->queue, status->unique_id, &js);
+               job_str = g_strdup_printf("job %d of %d, ", index+1, qcount);
+       }
+       else
+       {
+               job_str = g_strdup("");
+       }
+       if(status->seconds > -1)
+       {
+               status_str= g_strdup_printf(
+                       "Encoding: %s%s%.2f %%"
+                       " (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)",
+                       job_str, task_str,
+                       100.0 * status->progress,
+                       status->rate_cur, status->rate_avg, status->hours, 
+                       status->minutes, status->seconds );
+       }
+       else
+       {
+               status_str= g_strdup_printf(
+                       "Encoding: %s%s%.2f %%",
+                       job_str, task_str,
+                       100.0 * status->progress );
+       }
+       g_free(task_str);
+       g_free(job_str);
+       return status_str;
+}
+
 static void
 ghb_backend_events(signal_user_data_t *ud)
 {
@@ -2975,8 +1581,15 @@ ghb_backend_events(signal_user_data_t *ud)
        // Then handle the status of the queue
        if (status.state & GHB_STATE_SCANNING)
        {
-               status_str = g_strdup_printf ("Scanning title %d of %d...", 
+               if (status.title_cur == 0)
+               {
+                       status_str = g_strdup ("Scanning...");
+               }
+               else
+               {
+                       status_str = g_strdup_printf ("Scanning title %d of %d...", 
                                                                  status.title_cur, status.title_count );
+               }
                gtk_progress_bar_set_text (progress, status_str);
                g_free(status_str);
                if (status.title_count > 0)
@@ -3007,7 +1620,20 @@ ghb_backend_events(signal_user_data_t *ud)
                        gtk_progress_bar_set_text (progress, "No Source");
                }
                ghb_clear_state(GHB_STATE_SCANDONE);
-               queue_buttons_grey(ud, (0 != (status.queue_state & GHB_STATE_WORKING)));
+               ghb_queue_buttons_grey(ud, work_started);
+               if (ghb_queue_edit_settings)
+               {
+                       gint jstatus;
+
+                       jstatus = ghb_settings_get_int(ghb_queue_edit_settings, "job_status");
+                       ghb_settings_to_ui(ud, ghb_queue_edit_settings);
+                       ghb_set_audio(ud, ghb_queue_edit_settings);
+                       if (jstatus == GHB_QUEUE_PENDING)
+                       {
+                               ghb_value_free(ghb_queue_edit_settings);
+                       }
+                       ghb_queue_edit_settings = NULL;
+               }
        }
        else if (status.queue_state & GHB_STATE_SCANNING)
        {
@@ -3029,47 +1655,7 @@ ghb_backend_events(signal_user_data_t *ud)
        }
        else if (status.queue_state & GHB_STATE_WORKING)
        {
-               gchar *task_str, *job_str;
-               gint qcount;
-
-               if (status.job_count > 1)
-               {
-                       task_str = g_strdup_printf("pass %d of %d, ", 
-                               status.job_cur, status.job_count);
-               }
-               else
-               {
-                       task_str = g_strdup("");
-               }
-               qcount = ghb_array_len(ud->queue);
-               if (qcount > 1)
-               {
-                       index = find_queue_job(ud->queue, status.unique_id, &js);
-                       job_str = g_strdup_printf("job %d of %d, ", index+1, qcount);
-               }
-               else
-               {
-                       job_str = g_strdup("");
-               }
-               if(status.seconds > -1)
-               {
-                       status_str= g_strdup_printf(
-                               "Encoding: %s%s%.2f %%"
-                               " (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)",
-                               job_str, task_str,
-                               100.0 * status.progress,
-                               status.rate_cur, status.rate_avg, status.hours, 
-                               status.minutes, status.seconds );
-               }
-               else
-               {
-                       status_str= g_strdup_printf(
-                               "Encoding: %s%s%.2f %%",
-                               job_str, task_str,
-                               100.0 * status.progress );
-               }
-               g_free(job_str);
-               g_free(task_str);
+               status_str = working_status_string(ud, &status);
                gtk_progress_bar_set_text (progress, status_str);
                gtk_progress_bar_set_fraction (progress, status.progress);
                g_free(status_str);
@@ -3079,7 +1665,7 @@ ghb_backend_events(signal_user_data_t *ud)
                gint qstatus;
 
                work_started = FALSE;
-               queue_buttons_grey(ud, FALSE);
+               ghb_queue_buttons_grey(ud, FALSE);
                index = find_queue_job(ud->queue, status.unique_id, &js);
                treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
                store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
@@ -3132,7 +1718,7 @@ ghb_backend_events(signal_user_data_t *ud)
                gtk_progress_bar_set_fraction (progress, 1.0);
                ghb_clear_queue_state(GHB_STATE_WORKDONE);
                if (!ud->cancel_encode)
-                       ud->current_job = start_next_job(ud, FALSE);
+                       ud->current_job = ghb_start_next_job(ud, FALSE);
                else
                        ud->current_job = NULL;
                if (js)
@@ -3144,15 +1730,27 @@ ghb_backend_events(signal_user_data_t *ud)
        {
                gtk_progress_bar_set_text(progress, "Muxing: this may take awhile...");
        }
+       if (status.queue_state & GHB_STATE_SCANNING)
+       {
+               // This needs to be in scanning and working since scanning
+               // happens fast enough that it can be missed
+               if (!work_started)
+               {
+                       work_started = TRUE;
+                       ghb_queue_buttons_grey(ud, TRUE);
+               }
+       }
        if (status.queue_state & GHB_STATE_WORKING)
        {
+               // This needs to be in scanning and working since scanning
+               // happens fast enough that it can be missed
                if (!work_started)
                {
                        work_started = TRUE;
-                       queue_buttons_grey(ud, TRUE);
+                       ghb_queue_buttons_grey(ud, TRUE);
                }
                index = find_queue_job(ud->queue, status.unique_id, &js);
-               if (index >= 0)
+               if (status.unique_id != 0 && index >= 0)
                {
                        gchar working_icon[] = "hb-working0";
                        working_icon[10] = '0' + working;
@@ -3167,6 +1765,13 @@ ghb_backend_events(signal_user_data_t *ud)
                        }
                        g_free(path);
                }
+               GtkLabel *label;
+               gchar *status_str;
+
+               status_str = working_status_string(ud, &status);
+               label = GTK_LABEL(GHB_WIDGET(ud->builder, "queue_status"));
+               gtk_label_set_text (label, status_str);
+               g_free(status_str);
        }
 }
 
@@ -3353,26 +1958,6 @@ show_presets_toggled_cb(GtkToggleButton *button, signal_user_data_t *ud)
        ghb_pref_save(ud->settings, "show_presets");
 }
 
-void
-presets_frame_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud)
-{
-       GtkTreeView *treeview;
-       GtkTreeSelection *selection;
-       GtkTreeModel *store;
-       GtkTreeIter iter;
-       
-       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
-       selection = gtk_tree_view_get_selection(treeview);
-       if (gtk_tree_selection_get_selected(selection, &store, &iter))
-       {
-               GtkTreePath *path;
-               path = gtk_tree_model_get_path (store, &iter);
-               // Make the parent visible in scroll window if it is not.
-               gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0, 0);
-               g_free(path);
-       }
-}
-
 static void
 update_chapter_list(signal_user_data_t *ud)
 {
@@ -3385,7 +1970,7 @@ update_chapter_list(signal_user_data_t *ud)
        gint count;
        
        g_debug("update_chapter_list ()");
-       titleindex = ghb_settings_get_combo_index(ud->settings, "title");
+       titleindex = ghb_settings_combo_int(ud->settings, "title");
        chapters = ghb_get_chapters(titleindex);
        count = ghb_array_len(chapters);
        if (chapters)
@@ -3540,24 +2125,11 @@ chapter_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_
 }
 
 void
-queue_list_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, GtkCellRenderer *cell)
-{
-       GtkTreeViewColumn *column;
-       gint width;
-       
-       column = gtk_tree_view_get_column (GTK_TREE_VIEW(widget), 0);
-       width = gtk_tree_view_column_get_width(column);
-       g_debug("col width %d alloc width %d", width, allocation->width);
-       // Set new wrap-width.  Shave a little off to accomidate the icons
-       // that share this column.
-       if (width >= 564) // Don't allow below a certain size
-               g_object_set(cell, "wrap-width", width-70, NULL);
-}
-
-void
 preview_button_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
 {
-       gint titleindex = ghb_settings_get_int(ud->settings, "title");
+       gint titleindex;
+
+       titleindex = ghb_settings_combo_int(ud->settings, "title");
        if (titleindex < 0) return;
        g_debug("titleindex %d", titleindex);
 
@@ -3589,62 +2161,6 @@ preview_button_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, si
 }
 
 void
-queue_start_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       GValue *js;
-       gboolean running = FALSE;
-       gint count, ii;
-       gint status;
-       gint state;
-
-       count = ghb_array_len(ud->queue);
-       for (ii = 0; ii < count; ii++)
-       {
-               js = ghb_array_get_nth(ud->queue, ii);
-               status = ghb_settings_get_int(js, "job_status");
-               if ((status == GHB_QUEUE_RUNNING) || 
-                       (status == GHB_QUEUE_PENDING))
-               {
-                       running = TRUE;
-                       break;
-               }
-       }
-       if (!running)
-       {
-               // The queue has no running or pending jobs.
-               // Add current settings to the queue, then run.
-               if (!queue_add(ud))
-                       return;
-       }
-       state = ghb_get_queue_state();
-       if (state == GHB_STATE_IDLE)
-       {
-               // Add the first pending queue item and start
-               ud->current_job = start_next_job(ud, TRUE);
-       }
-}
-
-void
-queue_stop_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       ud->cancel_encode = TRUE;
-       cancel_encode(NULL);
-}
-
-void
-queue_pause_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       ghb_pause_queue();
-}
-
-void
-presets_default_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
-       ghb_set_preset_default(ud->settings);
-       ghb_presets_list_update(ud);
-}
-
-void
 debug_log_handler(const gchar *domain, GLogLevelFlags flags, const gchar *msg, gpointer data)
 {
        signal_user_data_t *ud = (signal_user_data_t*)data;
@@ -3714,6 +2230,7 @@ pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("pref_changed_cb");
        ghb_widget_to_setting (ud->settings, widget);
+       ghb_check_dependency(ud, widget);
        const gchar *name = gtk_widget_get_name(widget);
        ghb_pref_save(ud->settings, name);
 }
@@ -3727,30 +2244,30 @@ tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        ghb_pref_save(ud->settings, name);
 
        gboolean tweaks = ghb_settings_get_boolean(ud->settings, "allow_tweaks");
-       widget = GHB_WIDGET(ud->builder, "deinterlace");
+       widget = GHB_WIDGET(ud->builder, "PictureDeinterlace");
        tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
-       widget = GHB_WIDGET(ud->builder, "tweak_deinterlace");
+       widget = GHB_WIDGET(ud->builder, "tweak_PictureDeinterlace");
        !tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
 
-       widget = GHB_WIDGET(ud->builder, "denoise");
+       widget = GHB_WIDGET(ud->builder, "PictureDenoise");
        tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
-       widget = GHB_WIDGET(ud->builder, "tweak_denoise");
+       widget = GHB_WIDGET(ud->builder, "tweak_PictureDenoise");
        !tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
        if (tweaks)
        {
                const GValue *value;
-               value = ghb_settings_get_value(ud->settings, "deinterlace");
-               ghb_ui_update(ud, "tweak_deinterlace", value);
-               value = ghb_settings_get_value(ud->settings, "denoise");
-               ghb_ui_update(ud, "tweak_denoise", value);
+               value = ghb_settings_get_value(ud->settings, "PictureDeinterlace");
+               ghb_ui_update(ud, "tweak_PictureDeinterlace", value);
+               value = ghb_settings_get_value(ud->settings, "PictureDenoise");
+               ghb_ui_update(ud, "tweak_PictureDenoise", value);
        }
        else
        {
                const GValue *value;
-               value = ghb_settings_get_value(ud->settings, "tweak_deinterlace");
-               ghb_ui_update(ud, "deinterlace", value);
-               value = ghb_settings_get_value(ud->settings, "tweak_denoise");
-               ghb_ui_update(ud, "denoise", value);
+               value = ghb_settings_get_value(ud->settings, "tweak_PictureDeinterlace");
+               ghb_ui_update(ud, "PictureDeinterlace", value);
+               value = ghb_settings_get_value(ud->settings, "tweak_PictureDenoise");
+               ghb_ui_update(ud, "PictureDenoise", value);
        }
 }
 
@@ -3856,6 +2373,7 @@ ghb_is_cd(GDrive *gd)
        device = g_drive_get_identifier(gd, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
        halDrive = libhal_drive_from_device_file (hal_ctx, device);
        dtype = libhal_drive_get_type(halDrive);
+       libhal_drive_free(halDrive);
        g_free(device);
        return (dtype == LIBHAL_DRIVE_TYPE_CDROM);
 }
@@ -3904,67 +2422,67 @@ drive_changed_cb(GVolumeMonitor *gvm, GDrive *gd, signal_user_data_t *ud)
 static gboolean
 dbus_init (void)
 {
-    DBusError error;
+       DBusError error;
 
-    if (dbus_connection != NULL)
-        return TRUE;
+       if (dbus_connection != NULL)
+               return TRUE;
 
-    dbus_error_init (&error);
-    if (!(dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
-        g_debug ("could not get system bus: %s", error.message);
-        dbus_error_free (&error);
-        return FALSE;
-    }
+       dbus_error_init (&error);
+       if (!(dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
+               g_debug ("could not get system bus: %s", error.message);
+               dbus_error_free (&error);
+               return FALSE;
+       }
 
-    //dbus_connection_setup_with_g_main (dbus_connection, NULL);
-    //dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
-    //dbus_connection_add_filter (dbus_connection, gvm_dbus_filter_function, NULL, NULL);
+       //dbus_connection_setup_with_g_main (dbus_connection, NULL);
+       //dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
+       //dbus_connection_add_filter (dbus_connection, gvm_dbus_filter_function, NULL, NULL);
 
-    return TRUE;
+       return TRUE;
 }
 
 void
 ghb_hal_init()
 {
-    DBusError error;
-    char **devices;
-    int nr;
-
-    if (!dbus_init ())
-        return;
-
-    if (!(hal_ctx = libhal_ctx_new ())) {
-        g_warning ("failed to create a HAL context!");
-        return;
-    }
-
-    libhal_ctx_set_dbus_connection (hal_ctx, dbus_connection);
-    dbus_error_init (&error);
-    if (!libhal_ctx_init (hal_ctx, &error)) {
-        g_warning ("libhal_ctx_init failed: %s", error.message ? error.message : "unknown");
-        dbus_error_free (&error);
-        libhal_ctx_free (hal_ctx);
-        return;
-    }
-
-    /*
-     * Do something to ping the HAL daemon - the above functions will
-     * succeed even if hald is not running, so long as DBUS is.  But we
-     * want to exit silently if hald is not running, to behave on
-     * pre-2.6 systems.
-     */
-    if (!(devices = libhal_get_all_devices (hal_ctx, &nr, &error))) {
-        g_warning ("seems that HAL is not running: %s", error.message ? error.message : "unknown");
-        dbus_error_free (&error);
-
-        libhal_ctx_shutdown (hal_ctx, NULL);
-        libhal_ctx_free (hal_ctx);
-        return;
-    }
-
-    libhal_free_string_array (devices);
-
-    //gvm_hal_claim_branch ("/org/freedesktop/Hal/devices/local");
+       DBusError error;
+       char **devices;
+       int nr;
+
+       if (!dbus_init ())
+               return;
+
+       if (!(hal_ctx = libhal_ctx_new ())) {
+               g_warning ("failed to create a HAL context!");
+               return;
+       }
+
+       libhal_ctx_set_dbus_connection (hal_ctx, dbus_connection);
+       dbus_error_init (&error);
+       if (!libhal_ctx_init (hal_ctx, &error)) {
+               g_warning ("libhal_ctx_init failed: %s", error.message ? error.message : "unknown");
+               dbus_error_free (&error);
+               libhal_ctx_free (hal_ctx);
+               return;
+       }
+
+       /*
+        * Do something to ping the HAL daemon - the above functions will
+        * succeed even if hald is not running, so long as DBUS is.  But we
+        * want to exit silently if hald is not running, to behave on
+        * pre-2.6 systems.
+        */
+       if (!(devices = libhal_get_all_devices (hal_ctx, &nr, &error))) {
+               g_warning ("seems that HAL is not running: %s", error.message ? error.message : "unknown");
+               dbus_error_free (&error);
+
+               libhal_ctx_shutdown (hal_ctx, NULL);
+               libhal_ctx_free (hal_ctx);
+               return;
+       }
+
+       libhal_free_string_array (devices);
+
+       //gvm_hal_claim_branch ("/org/freedesktop/Hal/devices/local");
 }
 
 gboolean 
@@ -4055,68 +2573,36 @@ easter_egg_cb(
        return FALSE;
 }
 
-gboolean
-ghb_reload_queue(signal_user_data_t *ud)
+gchar*
+format_deblock_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
 {
-       GValue *queue;
-       gint unfinished = 0;
-       gint count, ii;
-       gint status;
-       GValue *settings;
-       gchar *message;
-
-       g_debug("ghb_reload_queue");
-       queue = ghb_load_queue();
-       // Look for unfinished entries
-       count = ghb_array_len(queue);
-       for (ii = 0; ii < count; ii++)
+       if (val < 5.0)
        {
-               settings = ghb_array_get_nth(queue, ii);
-               status = ghb_settings_get_int(settings, "job_status");
-               if (status != GHB_QUEUE_DONE && status != GHB_QUEUE_CANCELED)
-               {
-                       unfinished++;
-               }
+               return g_strdup_printf("Off");
        }
-       if (unfinished)
+       else
        {
-               message = g_strdup_printf(
-                                       "You have %d unfinished jobs in a saved queue.\n\n"
-                                       "Would you like to reload them?",
-                                       unfinished);
-               if (ghb_message_dialog(GTK_MESSAGE_QUESTION, message, "No", "Yes"))
-               {
-                       GtkWidget *widget = GHB_WIDGET (ud->builder, "queue_window");
-                       gtk_widget_show (widget);
+               return g_strdup_printf("%d", (gint)val);
+       }
+}
 
-                       ud->queue = queue;
-                       // First get rid of any old items we don't want
-                       for (ii = count-1; ii >= 0; ii--)
-                       {
-                               settings = ghb_array_get_nth(queue, ii);
-                               status = ghb_settings_get_int(settings, "job_status");
-                               if (status == GHB_QUEUE_DONE || status == GHB_QUEUE_CANCELED)
-                               {
-                                       ghb_array_remove(queue, ii);
-                               }
-                       }
-                       count = ghb_array_len(queue);
-                       for (ii = 0; ii < count; ii++)
-                       {
-                               settings = ghb_array_get_nth(queue, ii);
-                               ghb_settings_set_int(settings, "job_unique_id", 0);
-                               ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
-                               add_to_queue_list(ud, settings);
-                       }
-                       queue_buttons_grey(ud, FALSE);
-               }
-               else
+gchar*
+format_vquality_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
+{
+       if (ghb_settings_get_boolean(ud->settings, "directqp"))
+       {
+               gint vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
+               // Only x264 and ffmpeg currently support direct qp/crf entry
+               if (vcodec != HB_VCODEC_X264 && vcodec != HB_VCODEC_FFMPEG)
                {
-                       ghb_value_free(queue);
-                       ghb_remove_queue_file();
+                       val *= 100;
+                       return g_strdup_printf("%.1f", val);
                }
-               g_free(message);
+               return g_strdup_printf("%d", (gint)val);
+       }
+       else
+       {
+               val *= 100;
+               return g_strdup_printf("%.1f", val);
        }
-       return FALSE;
 }
-