OSDN Git Service

LinGui: remove target file size option
[handbrake-jp/handbrake-jp-git.git] / gtk / src / callbacks.c
index eda4628..9355e80 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * callbacks.c
- * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
+ * Copyright (C) John Stebbins 2008-2011 <stebbins@stebbins>
  * 
  * callbacks.c is free software.
  * 
 
 #if !defined(_WIN32)
 #include <poll.h>
-#include <libhal-storage.h>
+#define G_UDEV_API_IS_SUBJECT_TO_CHANGE 1
+#include <gudev/gudev.h>
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
 #include <netinet/in.h>
 #include <netdb.h>
+
+#if !defined(_NO_UPDATE_CHECK)
 #if defined(_OLD_WEBKIT)
 #include <webkit.h>
 #else
 #include <webkit/webkit.h>
 #endif
+#endif
+
 #include <libnotify/notify.h>
 #include <gdk/gdkx.h>
 #else
@@ -62,6 +67,7 @@
 #include "ghb-dvd.h"
 #include "ghbcellrenderertext.h"
 
+static void reset_chapter_list(signal_user_data_t *ud, GValue *settings);
 static void update_chapter_list(signal_user_data_t *ud);
 static GList* dvd_device_list();
 static void prune_logs(signal_user_data_t *ud);
@@ -113,8 +119,7 @@ dep_check(signal_user_data_t *ud, const gchar *name, gboolean *out_hide)
                widget_name = ghb_value_string(ghb_array_get_nth(data, 0));
                widget = GHB_WIDGET(ud->builder, widget_name);
                dep_object = gtk_builder_get_object(ud->builder, name);
-               g_free(widget_name);
-               if (!GTK_WIDGET_SENSITIVE(widget))
+               if (widget != NULL && !GTK_WIDGET_SENSITIVE(widget))
                        continue;
                if (dep_object == NULL)
                {
@@ -137,7 +142,7 @@ dep_check(signal_user_data_t *ud, const gchar *name, gboolean *out_hide)
                        if (widget)
                                value = ghb_widget_string(widget);
                        else
-                               value = ghb_settings_get_string(ud->settings, name);
+                               value = ghb_settings_get_string(ud->settings, widget_name);
                        while (values && values[jj])
                        {
                                if (values[jj][0] == '>')
@@ -176,12 +181,16 @@ dep_check(signal_user_data_t *ud, const gchar *name, gboolean *out_hide)
                        g_strfreev (values);
                        g_free(value);
                }
+               g_free(widget_name);
        }
        return result;
 }
 
 void
-ghb_check_dependency(signal_user_data_t *ud, GtkWidget *widget)
+ghb_check_dependency(
+       signal_user_data_t *ud, 
+       GtkWidget *widget, 
+       const char *alt_name)
 {
        GObject *dep_object;
        const gchar *name;
@@ -190,11 +199,16 @@ ghb_check_dependency(signal_user_data_t *ud, GtkWidget *widget)
        gchar *dep_name;
        GType type;
 
-       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;
+       if (widget != NULL)
+       {
+               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 = ghb_get_setting_key(widget);
+       }
+       else
+               name = alt_name;
 
-       name = gtk_widget_get_name(widget);
        g_debug("ghb_check_dependency () %s", name);
 
        if (dep_map == NULL) return;
@@ -287,7 +301,7 @@ 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 (state & (GHB_STATE_WORKING|GHB_STATE_SEARCHING))
        {
                if (ghb_cancel_encode2(ud, "Closing HandBrake will terminate encoding.\n"))
                {
@@ -521,19 +535,12 @@ get_extension(signal_user_data_t *ud)
 {
        int container;
        const gchar *extension = "error";
-       GValue *audio_list;
-       GValue *subtitle_list;
 
        container = ghb_settings_combo_int(ud->settings, "FileFormat");
        if (container == HB_MUX_MP4)
        {
                extension = "mp4";
-               audio_list = ghb_settings_get_value(ud->settings, "audio_list");
-               subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
-               if (ghb_ac3_in_audio_list(audio_list) ||
-                       ghb_soft_in_subtitle_list(subtitle_list) ||
-                       ghb_settings_get_boolean(ud->settings, "ChapterMarkers") ||
-                       ghb_settings_get_boolean(ud->settings, "UseM4v"))
+               if (ghb_settings_get_boolean(ud->settings, "UseM4v"))
                {
                        extension = "m4v";
                }
@@ -571,7 +578,8 @@ set_destination(signal_user_data_t *ud)
                                title = ghb_settings_combo_int(ud->settings, "title");
                                g_string_append_printf(str, " - %d", title+1);
                        }
-                       if (ghb_settings_get_boolean(
+                       if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0 && 
+                               ghb_settings_get_boolean(
                                        ud->settings, "chapters_in_destination"))
                        {
                                gint start, end;
@@ -581,8 +589,8 @@ set_destination(signal_user_data_t *ud)
                                {
                                        g_string_append_printf(str, " -");
                                }
-                               start = ghb_settings_get_int(ud->settings, "start_chapter");
-                               end = ghb_settings_get_int(ud->settings, "end_chapter");
+                               start = ghb_settings_get_int(ud->settings, "start_point");
+                               end = ghb_settings_get_int(ud->settings, "end_point");
                                if (start == end)
                                        g_string_append_printf(str, " Ch %d", start);
                                else
@@ -657,7 +665,11 @@ update_source_label(signal_user_data_t *ud, const gchar *source, gboolean update
        if (g_file_test(filename, G_FILE_TEST_IS_DIR))
        {
                // Skip dos drive letters
+#if defined(_WIN32)
                start = strchr(filename, ':');
+#else
+               start = filename;
+#endif
                label = resolve_drive_name(filename);
                if (label != NULL)
                {
@@ -749,6 +761,8 @@ chooser_file_selected_cb(GtkFileChooser *dialog, signal_user_data_t *ud)
        gboolean foundit = FALSE;
        GtkComboBox *combo;
        
+       g_debug("chooser_file_selected_cb ()");
+
        if (name == NULL) return;
        combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, "source_device"));
        store = gtk_combo_box_get_model(combo);
@@ -778,6 +792,7 @@ dvd_device_changed_cb(GtkComboBox *combo, signal_user_data_t *ud)
        GtkWidget *dialog;
        gint ii;
 
+       g_debug("dvd_device_changed_cb ()");
        ii = gtk_combo_box_get_active (combo);
        if (ii > 0)
        {
@@ -794,52 +809,17 @@ dvd_device_changed_cb(GtkComboBox *combo, signal_user_data_t *ud)
        }
 }
 
-G_MODULE_EXPORT void
-source_type_changed_cb(GtkToggleButton *toggle, signal_user_data_t *ud)
-{
-       gchar *folder;
-       GtkFileChooser *chooser;
-       GtkWidget *dvd_device_combo;
-       
-       g_debug("source_type_changed_cb ()");
-       chooser = GTK_FILE_CHOOSER(GHB_WIDGET(ud->builder, "source_dialog"));
-       dvd_device_combo = GHB_WIDGET(ud->builder, "source_device");
-       folder = gtk_file_chooser_get_current_folder (chooser);
-       if (gtk_toggle_button_get_active (toggle))
-       {
-               gtk_file_chooser_set_action (chooser, 
-                                                                       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
-               gtk_widget_set_sensitive (dvd_device_combo, FALSE);
-               gtk_combo_box_set_active (GTK_COMBO_BOX(dvd_device_combo), 0);
-       }
-       else
-       {
-               gtk_file_chooser_set_action (chooser, GTK_FILE_CHOOSER_ACTION_OPEN);
-               gtk_widget_set_sensitive (dvd_device_combo, TRUE);
-       }
-       if (folder != NULL)
-       {
-               gtk_file_chooser_set_current_folder(chooser, folder);
-               g_free(folder);
-       }
-}
-
 static void
 source_dialog_extra_widgets(
        signal_user_data_t *ud,
-       GtkWidget *dialog, 
-       gboolean checkbutton_active)
+       GtkWidget *dialog)
 {
-       GtkToggleButton *checkbutton;
        GtkComboBox *combo;
        GList *drives, *link;
        
-       checkbutton = GTK_TOGGLE_BUTTON(
-               GHB_WIDGET(ud->builder, "source_folder_flag"));
-       gtk_toggle_button_set_active(checkbutton, checkbutton_active);
+       g_debug("source_dialog_extra_widgets ()");
        combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, "source_device"));
-       gtk_list_store_clear(GTK_LIST_STORE(
-                                               gtk_combo_box_get_model(combo)));
+       gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(combo)));
 
        link = drives = dvd_device_list();
        gtk_combo_box_append_text (combo, "Not Selected");
@@ -852,6 +832,7 @@ source_dialog_extra_widgets(
                link = link->next;
        }
        g_list_free(drives);
+       gtk_combo_box_set_active (combo, 0);
 }
 
 extern GValue *ghb_queue_edit_settings;
@@ -887,12 +868,33 @@ start_scan(
                return;
 
        widget = GHB_WIDGET(ud->builder, "sourcetoolbutton");
-       gtk_widget_set_sensitive(widget, FALSE);
+       gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-stop");
+       gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Stop Scan");
+       gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Stop Scan");
+       //gtk_widget_set_sensitive(widget, FALSE);
+
        action = GHB_ACTION(ud->builder, "source_action");
        gtk_action_set_sensitive(action, FALSE);
        action = GHB_ACTION(ud->builder, "source_single_action");
        gtk_action_set_sensitive(action, FALSE);
-       ghb_backend_scan(path, titlenum, preview_count);
+       ghb_backend_scan(path, titlenum, preview_count, 
+                       90000L * ghb_settings_get_int64(ud->settings, "MinTitleDuration"));
+}
+
+gboolean
+ghb_idle_scan(signal_user_data_t *ud)
+{
+       gchar *path;
+       gint preview_count;
+
+       show_scan_progress(ud);
+       path = ghb_settings_get_string( ud->settings, "scan_source");
+       prune_logs(ud);
+
+       preview_count = ghb_settings_get_int(ud->settings, "preview_count");
+       start_scan(ud, path, 0, preview_count);
+       g_free(path);
+       return FALSE;
 }
 
 void
@@ -908,16 +910,11 @@ ghb_do_scan(
        {
                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);
                        ghb_reset_subtitles(ud, ghb_queue_edit_settings);
-                       if (jstatus == GHB_QUEUE_PENDING)
-                       {
-                               ghb_value_free(ghb_queue_edit_settings);
-                       }
+                       reset_chapter_list(ud, ghb_queue_edit_settings);
+                       ghb_value_free(ghb_queue_edit_settings);
                        ghb_queue_edit_settings = NULL;
                }
                return;
@@ -928,14 +925,14 @@ ghb_do_scan(
        if (filename != NULL)
        {
                last_scan_file = g_strdup(filename);
-               ghb_settings_set_string(ud->settings, "source", filename);
+               ghb_settings_set_string(ud->settings, "scan_source", filename);
                if (update_source_label(ud, filename, TRUE))
                {
                        gchar *path;
                        gint preview_count;
 
                        show_scan_progress(ud);
-                       path = ghb_settings_get_string( ud->settings, "source");
+                       path = ghb_settings_get_string( ud->settings, "scan_source");
                        prune_logs(ud);
 
                        preview_count = ghb_settings_get_int(ud->settings, "preview_count");
@@ -949,41 +946,15 @@ ghb_do_scan(
        }
 }
 
-static gboolean 
-update_source_name(gpointer data)
-{
-       signal_user_data_t *ud = (signal_user_data_t*)data;
-       GtkWidget *dialog;
-       gchar *sourcename;
-
-       sourcename = ghb_settings_get_string(ud->settings, "source");
-       dialog = GHB_WIDGET(ud->builder, "source_dialog");
-       gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sourcename);
-       g_free(sourcename);
-       return FALSE;
-}
-
 static void
 do_source_dialog(GtkButton *button, gboolean single, signal_user_data_t *ud)
 {
        GtkWidget *dialog;
        gchar *sourcename;
        gint    response;
-       GtkFileChooserAction action;
-       gboolean checkbutton_active;
 
        g_debug("source_browse_clicked_cb ()");
-       sourcename = ghb_settings_get_string(ud->settings, "source");
-       checkbutton_active = FALSE;
-       if (g_file_test(sourcename, G_FILE_TEST_IS_DIR))
-       {
-               action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
-               checkbutton_active = TRUE;
-       }
-       else
-       {
-               action = GTK_FILE_CHOOSER_ACTION_OPEN;
-       }
+       sourcename = ghb_settings_get_string(ud->settings, "scan_source");
        GtkWidget *widget;
        widget = GHB_WIDGET(ud->builder, "single_title_box");
        if (single)
@@ -991,16 +962,11 @@ do_source_dialog(GtkButton *button, gboolean single, signal_user_data_t *ud)
        else
                gtk_widget_hide(widget);
        dialog = GHB_WIDGET(ud->builder, "source_dialog");
-       source_dialog_extra_widgets(ud, dialog, checkbutton_active);
-       gtk_file_chooser_set_action(GTK_FILE_CHOOSER(dialog), action);
-       // Updating the filename in the file chooser dialog doesn't seem
-       // to work unless the dialog is running for some reason.
-       // So handle it in an "idle" event.
-       //gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sourcename);
-       g_idle_add((GSourceFunc)update_source_name, ud);
+       source_dialog_extra_widgets(ud, dialog);
+       gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sourcename);
        response = gtk_dialog_run(GTK_DIALOG (dialog));
        gtk_widget_hide(dialog);
-       if (response == GTK_RESPONSE_ACCEPT)
+       if (response == GTK_RESPONSE_NO)
        {
                gchar *filename;
 
@@ -1030,7 +996,16 @@ do_source_dialog(GtkButton *button, gboolean single, signal_user_data_t *ud)
 G_MODULE_EXPORT void
 source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
 {
-       do_source_dialog(button, FALSE, ud);
+       ghb_status_t status;
+       ghb_get_status(&status);
+       if (status.scan.state & GHB_STATE_SCANNING)
+       {
+               ghb_backend_scan_stop();
+       }
+       else
+       {
+               do_source_dialog(button, FALSE, ud);
+       }
 }
 
 G_MODULE_EXPORT void
@@ -1045,8 +1020,8 @@ dvd_source_activate_cb(GtkAction *action, signal_user_data_t *ud)
        const gchar *filename;
        gchar *sourcename;
 
-       sourcename = ghb_settings_get_string(ud->settings, "source");
-       filename = gtk_action_get_name(action);
+       sourcename = ghb_settings_get_string(ud->settings, "scan_source");
+       filename = gtk_buildable_get_name(GTK_BUILDABLE(action));
        ghb_do_scan(ud, filename, 0, TRUE);
        if (strcmp(sourcename, filename) != 0)
        {
@@ -1238,7 +1213,7 @@ 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 (state & (GHB_STATE_WORKING|GHB_STATE_SEARCHING))
        {
                if (ghb_cancel_encode2(ud, "Closing HandBrake will terminate encoding.\n"))
                {
@@ -1266,12 +1241,13 @@ container_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("container_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        update_acodec_combo(ud);
        ghb_update_destination_extension(ud);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        ghb_subtitle_prune(ud);
+       ghb_audio_list_refresh_selected(ud);
 }
 
 static gchar*
@@ -1300,25 +1276,88 @@ get_rate_string(gint rate_base, gint rate)
        rate_s = g_strdup_printf("%.6g", rate_f);
        return rate_s;
 }
+
 static void
-show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
+update_title_duration(signal_user_data_t *ud)
 {
-       GtkWidget *widget;
+       gint ti;
+       gint hh, mm, ss, start, end;
        gchar *text;
+       GtkWidget *widget;
 
-       ud->dont_clear_presets = TRUE;
+       ti = ghb_settings_combo_int(ud->settings, "title");
        widget = GHB_WIDGET (ud->builder, "title_duration");
-       if (tinfo->duration != 0)
+
+       if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0)
        {
-               text = g_strdup_printf ("%02d:%02d:%02d", tinfo->hours, 
-                               tinfo->minutes, tinfo->seconds);
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               ghb_part_duration(ti, start, end, &hh, &mm, &ss);
        }
-       else
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 1)
        {
-               text = g_strdup_printf ("Unknown");
+               gint duration;
+
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               duration = end - start;
+               hh = duration / (60*60);
+               mm = (duration / 60) % 60;
+               ss = duration % 60;
        }
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 2)
+       {
+               ghb_title_info_t tinfo;
+
+               if (ghb_get_title_info (&tinfo, ti))
+               {
+                       gint64 frames;
+                       gint duration;
+
+                       start = ghb_settings_get_int(ud->settings, "start_point");
+                       end = ghb_settings_get_int(ud->settings, "end_point");
+                       frames = end - start + 1;
+                       duration = frames * tinfo.rate_base / tinfo.rate;
+                       hh = duration / (60*60);
+                       mm = (duration / 60) % 60;
+                       ss = duration % 60;
+               }
+               else
+               {
+                       hh = mm = ss = 0;
+               }
+       }
+       text = g_strdup_printf("%02d:%02d:%02d", hh, mm, ss);
        gtk_label_set_text (GTK_LABEL(widget), text);
        g_free(text);
+}
+
+static void
+show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
+{
+       GtkWidget *widget;
+       gchar *text;
+
+       ghb_settings_set_string(ud->settings, "source", tinfo->path);
+       if (tinfo->type == HB_STREAM_TYPE)
+       {
+               GtkWidget *widget = GHB_WIDGET (ud->builder, "source_title");
+               if (tinfo->name != NULL && tinfo->name[0] != 0)
+               {
+                       gtk_label_set_text (GTK_LABEL(widget), tinfo->name);
+                       ghb_settings_set_string(ud->settings, "volume_label", tinfo->name);
+                       set_destination(ud);
+               }
+               else
+               {
+                       gchar *label = "No Title Found";
+                       gtk_label_set_text (GTK_LABEL(widget), label);
+                       ghb_settings_set_string(ud->settings, "volume_label", label);
+               }
+       }
+       ud->dont_clear_presets = TRUE;
+       ud->scale_busy = TRUE;
+       update_title_duration(ud);
        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);
@@ -1335,6 +1374,9 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        gtk_label_set_text (GTK_LABEL(widget), text);
        g_free(text);
 
+       //widget = GHB_WIDGET (ud->builder, "source_interlaced");
+       //gtk_label_set_text (GTK_LABEL(widget), tinfo->interlaced ? "Yes" : "No");
+
        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
@@ -1351,12 +1393,12 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        // 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;
+       bound = tinfo->height / 2 - 8;
        widget = GHB_WIDGET (ud->builder, "PictureTopCrop");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
        widget = GHB_WIDGET (ud->builder, "PictureBottomCrop");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
-       bound = tinfo->width / 2 - 2;
+       bound = tinfo->width / 2 - 8;
        widget = GHB_WIDGET (ud->builder, "PictureLeftCrop");
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
        widget = GHB_WIDGET (ud->builder, "PictureRightCrop");
@@ -1368,7 +1410,8 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
                ghb_ui_update(ud, "PictureLeftCrop", ghb_int64_value(tinfo->crop[2]));
                ghb_ui_update(ud, "PictureRightCrop", ghb_int64_value(tinfo->crop[3]));
        }
-       ghb_set_scale (ud, GHB_PIC_KEEP_PAR);
+       ud->scale_busy = FALSE;
+       ghb_set_scale (ud, GHB_PIC_KEEP_PAR|GHB_PIC_USE_MAX);
        gint width, height, crop[4];
        crop[0] = ghb_settings_get_int(ud->settings, "PictureTopCrop");
        crop[1] = ghb_settings_get_int(ud->settings, "PictureBottomCrop");
@@ -1381,17 +1424,46 @@ show_title_info(signal_user_data_t *ud, ghb_title_info_t *tinfo)
        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);
-       gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), tinfo->num_chapters);
-       widget = GHB_WIDGET (ud->builder, "start_chapter");
-       gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
-       gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->num_chapters);
+
+       gint duration = tinfo->duration / 90000;
+
+       if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0)
+       {
+               widget = GHB_WIDGET (ud->builder, "start_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->num_chapters);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
+
+               widget = GHB_WIDGET (ud->builder, "end_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->num_chapters);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), tinfo->num_chapters);
+       }
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 1)
+       {
+
+               widget = GHB_WIDGET (ud->builder, "start_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, duration-1);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 0);
+
+               widget = GHB_WIDGET (ud->builder, "end_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, duration);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), duration);
+       }
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 2)
+       {
+               gdouble max_frames = (gdouble)duration * tinfo->rate / tinfo->rate_base;
+               widget = GHB_WIDGET (ud->builder, "start_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, max_frames);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
+
+               widget = GHB_WIDGET (ud->builder, "end_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, max_frames);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), max_frames);
+       }
 
        widget = GHB_WIDGET (ud->builder, "angle");
        gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
        gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo->angle_count);
+       ghb_settings_set_int(ud->settings, "angle_count", tinfo->angle_count);
        ud->dont_clear_presets = FALSE;
 }
 
@@ -1405,7 +1477,6 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        
        g_debug("title_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
 
        titleindex = ghb_settings_combo_int(ud->settings, "title");
        ghb_update_ui_combo_box (ud, "AudioTrack", titleindex, FALSE);
@@ -1415,15 +1486,11 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        {
                show_title_info(ud, &tinfo);
        }
+       ghb_check_dependency(ud, widget, NULL);
        update_chapter_list (ud);
        ghb_adjust_audio_rate_combos(ud);
        ghb_set_pref_audio(titleindex, ud);
        ghb_set_pref_subtitle(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, "VideoAvgBitrate", ghb_int64_value(bitrate));
-       }
 
        // Unfortunately, there is no way to query how many frames were
        // actually generated during the scan.
@@ -1441,13 +1508,96 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        {
                set_destination(ud);
        }
+       ghb_preview_set_visible(ud);
+
+       gint end;
+       widget = GHB_WIDGET (ud->builder, "ChapterMarkers");
+       end = ghb_settings_get_int(ud->settings, "end_point");
+       if (1 == end)
+       {
+               gtk_widget_set_sensitive(widget, FALSE);
+       }
+       else
+       {
+               gtk_widget_set_sensitive(widget, TRUE);
+       }
+}
+
+G_MODULE_EXPORT void
+ptop_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+       gint ti;
+       ghb_title_info_t tinfo;
+
+       ghb_widget_to_setting(ud->settings, widget);
+       ghb_check_dependency(ud, widget, NULL);
+       ghb_live_reset(ud);
+
+       ti = ghb_settings_combo_int(ud->settings, "title");
+       if (!ghb_get_title_info (&tinfo, ti))
+               return;
+
+       gint duration = tinfo.duration / 90000;
+       if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0)
+       {
+               widget = GHB_WIDGET (ud->builder, "start_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo.num_chapters);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
+
+               widget = GHB_WIDGET (ud->builder, "end_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, tinfo.num_chapters);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), tinfo.num_chapters);
+       }
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 1)
+       {
+               widget = GHB_WIDGET (ud->builder, "start_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, duration-1);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 0);
+
+               widget = GHB_WIDGET (ud->builder, "end_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, duration);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), duration);
+       }
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 2)
+       {
+               gdouble max_frames = (gdouble)duration * tinfo.rate / tinfo.rate_base;
+               widget = GHB_WIDGET (ud->builder, "start_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, max_frames);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), 1);
+
+               widget = GHB_WIDGET (ud->builder, "end_point");
+               gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, max_frames);
+               gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), max_frames);
+       }
+}
+
+G_MODULE_EXPORT void
+framerate_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+       ghb_widget_to_setting(ud->settings, widget);
+
+       if (ghb_settings_combo_int(ud->settings, "VideoFramerate") != 0)
+       {
+               if (!ghb_settings_get_boolean(ud->settings, "VideoFrameratePFR"))
+        {
+                   ghb_ui_update(ud, "VideoFramerateCFR", ghb_boolean_value(TRUE));
+        }
+       }
+       if (ghb_settings_combo_int(ud->settings, "VideoFramerate") == 0 &&
+               ghb_settings_get_boolean(ud->settings, "VideoFrameratePFR"))
+       {
+               ghb_ui_update(ud, "VideoFramerateVFR", ghb_boolean_value(TRUE));
+       }
+       ghb_check_dependency(ud, widget, NULL);
+       ghb_clear_presets_selection(ud);
+       ghb_live_reset(ud);
 }
 
 G_MODULE_EXPORT void
 setting_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
 }
@@ -1456,7 +1606,7 @@ G_MODULE_EXPORT void
 chapter_markers_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        ghb_update_destination_extension(ud);
@@ -1466,7 +1616,7 @@ G_MODULE_EXPORT void
 vquality_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
 
@@ -1490,7 +1640,7 @@ G_MODULE_EXPORT void
 http_opt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        // AC3 is not allowed when Web optimized
@@ -1505,7 +1655,7 @@ vcodec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        gint digits;
 
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        ghb_vquality_range(ud, &vqmin, &vqmax, &step, &page, &digits, &inverted);
@@ -1517,80 +1667,106 @@ vcodec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 }
 
 G_MODULE_EXPORT void
-target_size_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
-{
-       const gchar *name = gtk_widget_get_name(widget);
-       g_debug("target_size_changed_cb () %s", name);
-       ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
-       ghb_clear_presets_selection(ud);
-       ghb_live_reset(ud);
-       if (ghb_settings_get_boolean(ud->settings, "vquality_type_target"))
-       {
-               gint titleindex;
-               titleindex = ghb_settings_combo_int(ud->settings, "title");
-               gint bitrate = ghb_calculate_target_bitrate (ud->settings, titleindex);
-               ghb_ui_update(ud, "VideoAvgBitrate", ghb_int64_value(bitrate));
-       }
-}
-
-G_MODULE_EXPORT void
-start_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+start_point_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        gint start, end;
-       const gchar *name = gtk_widget_get_name(widget);
+       const gchar *name = ghb_get_setting_key(widget);
 
-       g_debug("start_chapter_changed_cb () %s", name);
+       g_debug("start_point_changed_cb () %s", name);
        ghb_widget_to_setting(ud->settings, widget);
-       start = ghb_settings_get_int(ud->settings, "start_chapter");
-       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);
+       if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0)
+       {
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               if (start > end)
+                       ghb_ui_update(ud, "end_point", ghb_int_value(start));
+               ghb_check_dependency(ud, widget, NULL);
+               if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+               {
+                       set_destination(ud);
+               }
+               widget = GHB_WIDGET (ud->builder, "ChapterMarkers");
+               // End may have been changed above, get it again
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               if (start == end)
+               {
+                       gtk_widget_set_sensitive(widget, FALSE);
+               }
+               else
+               {
+                       gtk_widget_set_sensitive(widget, TRUE);
+               }
+               update_title_duration(ud);
        }
-       widget = GHB_WIDGET (ud->builder, "chapters_tab");
-       // End may have been changed above, get it again
-       end = ghb_settings_get_int(ud->settings, "end_chapter");
-       if (start == end)
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 1)
        {
-               gtk_widget_hide(widget);
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               if (start >= end)
+                       ghb_ui_update(ud, "end_point", ghb_int_value(start+1));
+               ghb_check_dependency(ud, widget, NULL);
+               update_title_duration(ud);
        }
-       else
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 2)
        {
-               gtk_widget_show(widget);
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               if (start > end)
+                       ghb_ui_update(ud, "end_point", ghb_int_value(start));
+               ghb_check_dependency(ud, widget, NULL);
+               update_title_duration(ud);
        }
 }
 
 G_MODULE_EXPORT void
-end_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+end_point_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        gint start, end;
-       const gchar *name = gtk_widget_get_name(widget);
+       const gchar *name = ghb_get_setting_key(widget);
 
-       g_debug("end_chapter_changed_cb () %s", name);
+       g_debug("end_point_changed_cb () %s", name);
        ghb_widget_to_setting(ud->settings, widget);
-       start = ghb_settings_get_int(ud->settings, "start_chapter");
-       end = ghb_settings_get_int(ud->settings, "end_chapter");
-       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);
+       if (ghb_settings_combo_int(ud->settings, "PtoPType") == 0)
+       {
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               if (start > end)
+                       ghb_ui_update(ud, "start_point", ghb_int_value(end));
+               ghb_check_dependency(ud, widget, NULL);
+               if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+               {
+                       set_destination(ud);
+               }
+               widget = GHB_WIDGET (ud->builder, "ChapterMarkers");
+               // Start may have been changed above, get it again
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               if (start == end)
+               {
+                       gtk_widget_set_sensitive(widget, FALSE);
+               }
+               else
+               {
+                       gtk_widget_set_sensitive(widget, TRUE);
+               }
+               update_title_duration(ud);
        }
-       widget = GHB_WIDGET (ud->builder, "chapters_tab");
-       // Start may have been changed above, get it again
-       start = ghb_settings_get_int(ud->settings, "start_chapter");
-       if (start == end)
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 1)
        {
-               gtk_widget_hide(widget);
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               if (start >= end)
+                       ghb_ui_update(ud, "start_point", ghb_int_value(end-1));
+               ghb_check_dependency(ud, widget, NULL);
+               update_title_duration(ud);
        }
-       else
+       else if (ghb_settings_combo_int(ud->settings, "PtoPType") == 2)
        {
-               gtk_widget_show(widget);
+               start = ghb_settings_get_int(ud->settings, "start_point");
+               end = ghb_settings_get_int(ud->settings, "end_point");
+               if (start > end)
+                       ghb_ui_update(ud, "start_point", ghb_int_value(end));
+               ghb_check_dependency(ud, widget, NULL);
+               update_title_duration(ud);
        }
 }
 
@@ -1599,7 +1775,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);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
                ghb_set_scale (ud, GHB_PIC_KEEP_WIDTH);
@@ -1619,7 +1795,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);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
                ghb_set_scale (ud, GHB_PIC_KEEP_HEIGHT);
@@ -1642,7 +1818,7 @@ crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
        
        g_debug("crop_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
                ghb_set_scale (ud, 0);
@@ -1680,7 +1856,7 @@ display_width_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("display_width_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
@@ -1694,7 +1870,7 @@ display_height_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("display_height_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
@@ -1708,7 +1884,7 @@ par_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("par_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
@@ -1722,7 +1898,7 @@ scale_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("scale_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_clear_presets_selection(ud);
        ghb_live_reset(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
@@ -1764,7 +1940,7 @@ show_crop_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("show_crop_changed_cb ()");
        ghb_widget_to_setting(ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
        ghb_live_reset(ud);
        if (GTK_WIDGET_SENSITIVE(widget))
                ghb_set_scale (ud, 0);
@@ -1806,9 +1982,32 @@ typedef struct
        const gchar *msg;
        const gchar *action;
        gint timeout;
+       signal_user_data_t *ud;
 } countdown_t;
 
 static gboolean
+quit_cb(countdown_t *cd)
+{
+       gchar *str;
+
+       cd->timeout--;
+       if (cd->timeout == 0)
+       {
+               ghb_hb_cleanup(FALSE);
+               prune_logs(cd->ud);
+
+               gtk_widget_destroy (GTK_WIDGET(cd->dlg));
+               gtk_main_quit();
+               return FALSE;
+       }
+       str = g_strdup_printf("%s\n\n%s in %d seconds ...", 
+                                                       cd->msg, cd->action, cd->timeout);
+       gtk_message_dialog_set_markup(cd->dlg, str);
+       g_free(str);
+       return TRUE;
+}
+
+static gboolean
 shutdown_cb(countdown_t *cd)
 {
        gchar *str;
@@ -1816,6 +2015,9 @@ shutdown_cb(countdown_t *cd)
        cd->timeout--;
        if (cd->timeout == 0)
        {
+               ghb_hb_cleanup(FALSE);
+               prune_logs(cd->ud);
+
                ghb_shutdown_gsm();
                gtk_main_quit();
                return FALSE;
@@ -1853,6 +2055,7 @@ ghb_countdown_dialog(
        const gchar *action, 
        const gchar *cancel, 
        GSourceFunc action_func,
+       signal_user_data_t *ud,
        gint timeout)
 {
        GtkWidget *dialog;
@@ -1863,6 +2066,7 @@ ghb_countdown_dialog(
        cd.msg = message;
        cd.action = action;
        cd.timeout = timeout;
+       cd.ud = ud;
 
        // Toss up a warning dialog
        dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
@@ -1947,7 +2151,7 @@ ghb_cancel_encode(signal_user_data_t *ud, const gchar *extra_msg)
                                                   NULL);
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy (dialog);
-       switch (response)
+       switch ((int)response)
        {
                case 1:
                        ghb_stop_queue();
@@ -1985,7 +2189,7 @@ ghb_cancel_encode2(signal_user_data_t *ud, const gchar *extra_msg)
                                                   NULL);
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy (dialog);
-       switch (response)
+       switch ((int)response)
        {
                case 1:
                        ghb_stop_queue();
@@ -2325,6 +2529,46 @@ working_status_string(signal_user_data_t *ud, ghb_instance_status_t *status)
        return status_str;
 }
 
+gchar*
+searching_status_string(signal_user_data_t *ud, ghb_instance_status_t *status)
+{
+       gchar *task_str, *job_str, *status_str;
+       gint qcount;
+       gint index;
+       GValue *js;
+
+       qcount = ghb_array_len(ud->queue);
+       index = find_queue_job(ud->queue, status->unique_id, &js);
+       if (qcount > 1)
+       {
+               job_str = g_strdup_printf("job %d of %d, ", index+1, qcount);
+       }
+       else
+       {
+               job_str = g_strdup("");
+       }
+       task_str = g_strdup_printf("Searching for start time, ");
+       if(status->seconds > -1)
+       {
+               status_str= g_strdup_printf(
+                       "Encoding: %s%s%.2f %%"
+                       " (ETA %02dh%02dm%02ds)",
+                       job_str, task_str,
+                       100.0 * status->progress,
+                       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)
 {
@@ -2400,19 +2644,27 @@ ghb_backend_events(signal_user_data_t *ud)
                GtkAction *action;
 
                widget = GHB_WIDGET(ud->builder, "sourcetoolbutton");
-               gtk_widget_set_sensitive(widget, TRUE);
+               gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(widget), "hb-source");
+               gtk_tool_button_set_label(GTK_TOOL_BUTTON(widget), "Source");
+               gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(widget), "Choose Video Source");
+
                action = GHB_ACTION(ud->builder, "source_action");
                gtk_action_set_sensitive(action, TRUE);
                action = GHB_ACTION(ud->builder, "source_single_action");
                gtk_action_set_sensitive(action, TRUE);
 
-               source = ghb_settings_get_string(ud->settings, "source");
+               source = ghb_settings_get_string(ud->settings, "scan_source");
                update_source_label(ud, source, FALSE);
 
                scan_prog = GTK_PROGRESS_BAR(GHB_WIDGET (ud->builder, "scan_prog"));
                gtk_progress_bar_set_fraction (scan_prog, 1.0);
                gtk_widget_hide(GTK_WIDGET(scan_prog));
 
+               if (!ghb_settings_get_boolean(ud->settings, "preset_modified"))
+               {
+                       ghb_refresh_preset(ud);
+               }
+
                ghb_title_info_t tinfo;
                        
                ghb_update_ui_combo_box(ud, "title", 0, FALSE);
@@ -2428,16 +2680,11 @@ ghb_backend_events(signal_user_data_t *ud)
                ghb_clear_scan_state(GHB_STATE_SCANDONE);
                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);
                        ghb_reset_subtitles(ud, ghb_queue_edit_settings);
-                       if (jstatus == GHB_QUEUE_PENDING)
-                       {
-                               ghb_value_free(ghb_queue_edit_settings);
-                       }
+                       reset_chapter_list(ud, ghb_queue_edit_settings);
+                       ghb_value_free(ghb_queue_edit_settings);
                        ghb_queue_edit_settings = NULL;
                }
        }
@@ -2460,6 +2707,44 @@ ghb_backend_events(signal_user_data_t *ud)
        {
                gtk_label_set_text (work_status, "Paused");
        }
+       else if (status.queue.state & GHB_STATE_SEARCHING)
+       {
+               static gint working = 0;
+
+               // This needs to be in scanning and working since scanning
+               // happens fast enough that it can be missed
+               index = find_queue_job(ud->queue, status.queue.unique_id, &js);
+               if (status.queue.unique_id != 0 && index >= 0)
+               {
+                       gchar working_icon[] = "hb-working0";
+                       working_icon[10] = '0' + working;
+                       working = (working+1) % 6;
+                       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "queue_list"));
+                       store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
+                       gchar *path = g_strdup_printf ("%d", index);
+                       if (gtk_tree_model_get_iter_from_string(
+                                       GTK_TREE_MODEL(store), &iter, path))
+                       {
+                               gtk_tree_store_set(store, &iter, 0, working_icon, -1);
+                       }
+                       g_free(path);
+               }
+               GtkLabel *label;
+               gchar *status_str;
+
+               status_str = searching_status_string(ud, &status.queue);
+               label = GTK_LABEL(GHB_WIDGET(ud->builder, "queue_status"));
+               gtk_label_set_text (label, status_str);
+#if !GTK_CHECK_VERSION(2, 16, 0)
+               GtkStatusIcon *si;
+
+               si = GTK_STATUS_ICON(GHB_OBJECT(ud->builder, "hb_status"));
+               gtk_status_icon_set_tooltip(si, status_str);
+#endif
+               gtk_label_set_text (work_status, status_str);
+               gtk_progress_bar_set_fraction (progress, status.queue.progress);
+               g_free(status_str);
+       }
        else if (status.queue.state & GHB_STATE_WORKING)
        {
                static gint working = 0;
@@ -2627,6 +2912,8 @@ status_icon_query_tooltip_cb(
        ghb_get_status(&status);
        if (status.queue.state & GHB_STATE_WORKING)
                status_str = working_status_string(ud, &status.queue);
+       else if (status.queue.state & GHB_STATE_SEARCHING)
+               status_str = searching_status_string(ud, &status.queue);
        else if (status.queue.state & GHB_STATE_WORKDONE)
                status_str = g_strdup("Encode Complete");
        else
@@ -2669,6 +2956,7 @@ ghb_timer_cb(gpointer data)
                update_preview = FALSE;
        }
 
+#if !defined(_NO_UPDATE_CHECK)
        if (!appcast_busy)
        {
                gchar *updates;
@@ -2699,6 +2987,7 @@ ghb_timer_cb(gpointer data)
                        }
                }
        }
+#endif
        return TRUE;
 }
 
@@ -2727,6 +3016,7 @@ ghb_log_cb(GIOChannel *source, GIOCondition cond, gpointer data)
                gint width, height;
                gint x, y;
                gboolean bottom = FALSE;
+               gchar *utf8_text;
 
                textview = GTK_TEXT_VIEW(GHB_WIDGET (ud->builder, "activity_view"));
                buffer = gtk_text_view_get_buffer (textview);
@@ -2752,34 +3042,40 @@ ghb_log_cb(GIOChannel *source, GIOCondition cond, gpointer data)
                        bottom = TRUE;
                }
                gtk_text_buffer_get_end_iter(buffer, &iter);
-               gtk_text_buffer_insert(buffer, &iter, text, -1);
-               if (bottom)
+               utf8_text = g_convert_with_fallback(text, -1, "UTF-8", "ISO-8859-1",
+                                                                                       "?", NULL, &length, NULL);
+               if (utf8_text != NULL)
                {
-                       gtk_text_buffer_get_end_iter(buffer, &iter);
-                       mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE);
-                       gtk_text_view_scroll_mark_onscreen(textview, mark);
-                       gtk_text_buffer_delete_mark(buffer, mark);
-               }
-#if defined(_WIN32)
-               gsize one = 1;
-               text[length-1] = '\r';
-#endif
-               g_io_channel_write_chars (ud->activity_log, text, 
-                                                               length, &outlength, NULL);
+                       gtk_text_buffer_insert(buffer, &iter, utf8_text, -1);
+                       if (bottom)
+                       {
+                               gtk_text_buffer_get_end_iter(buffer, &iter);
+                               mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE);
+                               gtk_text_view_scroll_mark_onscreen(textview, mark);
+                               gtk_text_buffer_delete_mark(buffer, mark);
+                       }
 #if defined(_WIN32)
-               g_io_channel_write_chars (ud->activity_log, "\n", 
-                                                               one, &one, NULL);
+                       gsize one = 1;
+                       utf8_text[length-1] = '\r';
 #endif
-               g_io_channel_flush(ud->activity_log, NULL);
-               if (ud->job_activity_log)
-               {
-                       g_io_channel_write_chars (ud->job_activity_log, text, 
+                       g_io_channel_write_chars (ud->activity_log, utf8_text, 
                                                                        length, &outlength, NULL);
 #if defined(_WIN32)
                        g_io_channel_write_chars (ud->activity_log, "\n", 
-                                                                       one, &outlength, NULL);
+                                                                       one, &one, NULL);
 #endif
-                       g_io_channel_flush(ud->job_activity_log, NULL);
+                       g_io_channel_flush(ud->activity_log, NULL);
+                       if (ud->job_activity_log)
+                       {
+                               g_io_channel_write_chars (ud->job_activity_log, utf8_text, 
+                                                                               length, &outlength, NULL);
+#if defined(_WIN32)
+                               g_io_channel_write_chars (ud->activity_log, "\n", 
+                                                                               one, &outlength, NULL);
+#endif
+                               g_io_channel_flush(ud->job_activity_log, NULL);
+                       }
+                       g_free(utf8_text);
                }
        }
        if (text != NULL)
@@ -2861,6 +3157,10 @@ ghb_log(gchar *log, ...)
 static void
 browse_url(const gchar *url)
 {
+#if defined(_WIN32)
+       HINSTANCE r;
+       r = ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
+#else
        gboolean result;
        char *argv[] = 
                {"xdg-open",NULL,NULL,NULL};
@@ -2886,6 +3186,7 @@ browse_url(const gchar *url)
        argv[2] = NULL;
        result = g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL,
                                NULL, NULL, NULL);
+#endif
 }
 
 void
@@ -2972,6 +3273,83 @@ show_presets_toggled_cb(GtkWidget *action, signal_user_data_t *ud)
 }
 
 static void
+reset_chapter_list(signal_user_data_t *ud, GValue *settings)
+{
+       GtkTreeView *treeview;
+       GtkTreeIter iter;
+       GtkListStore *store;
+       gboolean done;
+       GValue *chapters;
+       gint titleindex, ii;
+       gint count;
+       
+       g_debug("reset_chapter_list ()");
+       chapters = ghb_value_dup(ghb_settings_get_value(settings, "chapter_list"));
+       count = ghb_array_len(chapters);
+       ghb_settings_set_value(ud->settings, "chapter_list", chapters);
+       titleindex = ghb_settings_combo_int(ud->settings, "title");
+       
+       treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "chapters_list"));
+       store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
+       ii = 0;
+       if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
+       {
+               do
+               {
+
+                       if (ii < count)
+                       {
+                               gchar *chapter, *duration;
+                               gint hh, mm, ss;
+
+                               // Update row with settings data
+                               g_debug("Updating row");
+                               chapter = ghb_value_string(ghb_array_get_nth(chapters, ii));
+                               ghb_get_chapter_duration(titleindex, ii, &hh, &mm, &ss);
+                               duration = g_strdup_printf("%02d:%02d:%02d", hh, mm, ss);
+                               gtk_list_store_set(store, &iter, 
+                                       0, ii+1,
+                                       1, duration,
+                                       2, chapter,
+                                       3, TRUE,
+                                       -1);
+                               g_free(chapter);
+                               g_free(duration);
+                               ii++;
+                               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 (ii < count)
+       {
+               gchar *chapter, *duration;
+               gint hh, mm, ss;
+
+               // Additional settings, add row
+               g_debug("Adding row");
+               chapter = ghb_value_string(ghb_array_get_nth(chapters, ii));
+               ghb_get_chapter_duration(titleindex, ii, &hh, &mm, &ss);
+               duration = g_strdup_printf("%02d:%02d:%02d", hh, mm, ss);
+               gtk_list_store_append(store, &iter);
+               gtk_list_store_set(store, &iter, 
+                       0, ii+1,
+                       1, duration,
+                       2, chapter,
+                       3, TRUE,
+                       -1);
+               g_free(chapter);
+               g_free(duration);
+               ii++;
+       }
+}
+
+static void
 update_chapter_list(signal_user_data_t *ud)
 {
        GtkTreeView *treeview;
@@ -3201,8 +3579,8 @@ 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_check_dependency(ud, widget, NULL);
+       const gchar *name = ghb_get_setting_key(widget);
        ghb_pref_save(ud->settings, name);
 }
 
@@ -3211,8 +3589,8 @@ use_m4v_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("use_m4v_changed_cb");
        ghb_widget_to_setting (ud->settings, widget);
-       ghb_check_dependency(ud, widget);
-       const gchar *name = gtk_widget_get_name(widget);
+       ghb_check_dependency(ud, widget, NULL);
+       const gchar *name = ghb_get_setting_key(widget);
        ghb_pref_save(ud->settings, name);
        ghb_update_destination_extension(ud);
 }
@@ -3222,8 +3600,8 @@ show_status_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("show_status_cb");
        ghb_widget_to_setting (ud->settings, widget);
-       ghb_check_dependency(ud, widget);
-       const gchar *name = gtk_widget_get_name(widget);
+       ghb_check_dependency(ud, widget, NULL);
+       const gchar *name = ghb_get_setting_key(widget);
        ghb_pref_save(ud->settings, name);
 
        GtkStatusIcon *si;
@@ -3238,9 +3616,9 @@ vqual_granularity_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("vqual_granularity_changed_cb");
        ghb_widget_to_setting (ud->settings, widget);
-       ghb_check_dependency(ud, widget);
+       ghb_check_dependency(ud, widget, NULL);
 
-       const gchar *name = gtk_widget_get_name(widget);
+       const gchar *name = ghb_get_setting_key(widget);
        ghb_pref_save(ud->settings, name);
 
        gdouble vqmin, vqmax, step, page;
@@ -3257,7 +3635,7 @@ tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("tweaks_changed_cb");
        ghb_widget_to_setting (ud->settings, widget);
-       const gchar *name = gtk_widget_get_name(widget);
+       const gchar *name = ghb_get_setting_key(widget);
        ghb_pref_save(ud->settings, name);
 }
 
@@ -3266,7 +3644,7 @@ hbfd_feature_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
 {
        g_debug("hbfd_feature_changed_cb");
        ghb_widget_to_setting (ud->settings, widget);
-       const gchar *name = gtk_widget_get_name(widget);
+       const gchar *name = ghb_get_setting_key(widget);
        ghb_pref_save(ud->settings, name);
 
        gboolean hbfd = ghb_settings_get_boolean(ud->settings, "hbfd_feature");
@@ -3399,7 +3777,7 @@ dvd_device_list()
 }
 
 #if !defined(_WIN32)
-static LibHalContext *hal_ctx;
+static GUdevClient *udev_ctx = NULL;
 #endif
 
 gboolean
@@ -3407,24 +3785,43 @@ ghb_is_cd(GDrive *gd)
 {
 #if !defined(_WIN32)
        gchar *device;
-       LibHalDrive *halDrive;
-       LibHalDriveType dtype;
+       GUdevDevice *udd;
+
+       if (udev_ctx == NULL)
+               return FALSE;
 
        device = g_drive_get_identifier(gd, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
        if (device == NULL)
                return FALSE;
-       halDrive = libhal_drive_from_device_file (hal_ctx, device);
+
+       udd = g_udev_client_query_by_device_file(udev_ctx, device);
        g_free(device);
-       if (halDrive == NULL)
+
+       if (udd == NULL)
+       {
+               g_message("udev: Failed to lookup device %s", device);
                return FALSE;
-       dtype = libhal_drive_get_type(halDrive);
-       libhal_drive_free(halDrive);
-       return (dtype == LIBHAL_DRIVE_TYPE_CDROM);
+       }
+
+       gint val;
+       val = g_udev_device_get_property_as_int(udd, "ID_CDROM_DVD");
+       if (val == 1)
+               return TRUE;
+
+       return FALSE;
 #else
        return FALSE;
 #endif
 }
 
+void
+ghb_udev_init()
+{
+#if !defined(_WIN32)
+       udev_ctx = g_udev_client_new(NULL);
+#endif
+}
+
 #if defined(_WIN32)
 static void
 handle_media_change(const gchar *device, gboolean insert, signal_user_data_t *ud)
@@ -3454,7 +3851,7 @@ handle_media_change(const gchar *device, gboolean insert, signal_user_data_t *ud
                                update_source_label(ud, device, TRUE);
                                gint preview_count;
                                preview_count = ghb_settings_get_int(ud->settings, "preview_count");
-                               ghb_settings_set_string(ud->settings, "source", device);
+                               ghb_settings_set_string(ud->settings, "scan_source", device);
                                start_scan(ud, device, 0, preview_count);
                        }
                }
@@ -3471,7 +3868,7 @@ handle_media_change(const gchar *device, gboolean insert, signal_user_data_t *ud
                        {
                                ghb_hb_cleanup(TRUE);
                                prune_logs(ud);
-                               ghb_settings_set_string(ud->settings, "source", "/dev/null");
+                               ghb_settings_set_string(ud->settings, "scan_source", "/dev/null");
                                start_scan(ud, "/dev/null", 0, 1);
                        }
                }
@@ -3558,7 +3955,7 @@ drive_changed_cb(GVolumeMonitor *gvm, GDrive *gd, signal_user_data_t *ud)
                        update_source_label(ud, device, TRUE);
                        gint preview_count;
                        preview_count = ghb_settings_get_int(ud->settings, "preview_count");
-                       ghb_settings_set_string(ud->settings, "source", device);
+                       ghb_settings_set_string(ud->settings, "scan_source", device);
                        start_scan(ud, device, 0, preview_count);
                }
        }
@@ -3566,19 +3963,13 @@ drive_changed_cb(GVolumeMonitor *gvm, GDrive *gd, signal_user_data_t *ud)
        {
                ghb_hb_cleanup(TRUE);
                prune_logs(ud);
-               ghb_settings_set_string(ud->settings, "source", "/dev/null");
+               ghb_settings_set_string(ud->settings, "scan_source", "/dev/null");
                start_scan(ud, "/dev/null", 0, 1);
        }
 }
 #endif
 
 #if !defined(_WIN32)
-static void
-dbus_init (void)
-{
-       dbus_g_thread_init();
-}
-
 #define GPM_DBUS_PM_SERVICE                    "org.freedesktop.PowerManagement"
 #define GPM_DBUS_PM_PATH                       "/org/freedesktop/PowerManagement"
 #define GPM_DBUS_PM_INTERFACE          "org.freedesktop.PowerManagement"
@@ -3681,11 +4072,11 @@ ghb_suspend_gpm()
 #endif
 }
 
+#if !defined(_WIN32)
 static gboolean
 ghb_can_shutdown_gpm()
 {
        gboolean can_shutdown = FALSE;
-#if !defined(_WIN32)
        DBusGConnection *conn;
        DBusGProxy      *proxy;
        GError *error = NULL;
@@ -3726,14 +4117,14 @@ ghb_can_shutdown_gpm()
        }
        g_object_unref(G_OBJECT(proxy));
        dbus_g_connection_unref(conn);
-#endif
        return can_shutdown;
 }
+#endif
 
+#if !defined(_WIN32)
 static void
 ghb_shutdown_gpm()
 {
-#if !defined(_WIN32)
        DBusGConnection *conn;
        DBusGProxy      *proxy;
        GError *error = NULL;
@@ -3771,8 +4162,8 @@ ghb_shutdown_gpm()
        }
        g_object_unref(G_OBJECT(proxy));
        dbus_g_connection_unref(conn);
-#endif
 }
+#endif
 
 void
 ghb_inhibit_gpm()
@@ -4091,63 +4482,6 @@ ghb_uninhibit_gsm()
 #endif
 }
 
-void
-ghb_hal_init()
-{
-#if !defined(_WIN32)
-       DBusGConnection *gconn;
-       DBusConnection *conn;
-       GError *gerror = NULL;
-       DBusError error;
-       char **devices;
-       int nr;
-
-       dbus_init ();
-
-       if (!(hal_ctx = libhal_ctx_new ())) {
-               g_warning ("failed to create a HAL context!");
-               return;
-       }
-
-       gconn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &gerror);
-       if (gerror != NULL)
-       {
-               g_warning("DBUS cannot connect: %s", gerror->message);
-               g_error_free(gerror);
-               return;
-       }
-       conn = dbus_g_connection_get_connection(gconn);
-       libhal_ctx_set_dbus_connection (hal_ctx, conn);
-       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);
-               dbus_g_connection_unref(gconn);
-               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);
-               dbus_g_connection_unref(gconn);
-               return;
-       }
-
-       libhal_free_string_array (devices);
-       dbus_g_connection_unref(gconn);
-#endif
-}
-
 G_MODULE_EXPORT gboolean 
 tweak_setting_cb(
        GtkWidget *widget, 
@@ -4168,7 +4502,7 @@ tweak_setting_cb(
                GtkResponseType response;
                gchar *tweak = NULL;
 
-               name = gtk_widget_get_name(widget);
+               name = ghb_get_setting_key(widget);
                if (g_str_has_prefix(name, "tweak_"))
                {
                        tweak_name = g_strdup(name);
@@ -4265,40 +4599,36 @@ format_drc_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
 G_MODULE_EXPORT gchar*
 format_vquality_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
 {
-       gdouble percent;
-
        gint vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
        switch (vcodec)
        {
                case HB_VCODEC_X264:
                {
-                       gboolean crf;
-                       crf = ghb_settings_get_boolean(ud->settings, "constant_rate_factor");
-                       percent = 100. * (51 - val) / 51.;
-                       if (crf)
-                               return g_strdup_printf("RF: %.4g (%.0f%%)", val, percent);
+                       if (val == 0.0)
+                       {
+                               return g_strdup_printf("RF: %.4g (Warning: lossless)", val);
+                       }
                        else
-                               return g_strdup_printf("QP: %.4g (%.0f%%)", val, percent);
+                       {
+                               return g_strdup_printf("RF: %.4g", val);
+                       }
                } break;
 
                case HB_VCODEC_FFMPEG:
                {
-                       percent = 100. * (30 - (val - 1)) / 30.;
-                       return g_strdup_printf("QP: %d (%.0f%%)", (int)val, percent);
+                       return g_strdup_printf("QP: %d", (int)val);
                } break;
 
                case HB_VCODEC_THEORA:
                {
-                       percent = 100. * val / 63.;
-                       return g_strdup_printf("QP: %d (%.0f%%)", (int)val, percent);
+                       return g_strdup_printf("QP: %d", (int)val);
                } break;
 
                default:
                {
-                       percent = 0;
                } break;
        }
-       return g_strdup_printf("QP: %.1f / %.1f%%", val, percent);
+       return g_strdup_printf("QP: %.4g", val);
 }
 
 static void
@@ -4332,6 +4662,7 @@ process_appcast(signal_user_data_t *ud)
        gtk_label_set_text(GTK_LABEL(label), msg);
 
 #if !defined(_WIN32)
+#if !defined(_NO_UPDATE_CHECK)
        if (html == NULL)
        {
                html = webkit_web_view_new();
@@ -4343,6 +4674,7 @@ process_appcast(signal_user_data_t *ud)
        }
        webkit_web_view_open(WEBKIT_WEB_VIEW(html), description);
 #endif
+#endif
        dialog = GHB_WIDGET(ud->builder, "update_dialog");
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_hide(dialog);
@@ -4398,7 +4730,10 @@ ghb_net_recv_cb(GIOChannel *ioc, GIOCondition cond, gpointer data)
        }
        if (status == G_IO_STATUS_EOF)
        {
-               ud->appcast[ud->appcast_len] = 0;
+               if ( ud->appcast != NULL )
+               {
+                       ud->appcast[ud->appcast_len] = 0;
+               }
                ghb_net_close(ioc);
                process_appcast(ud);
                return FALSE;
@@ -4560,7 +4895,7 @@ ghb_notify_done(signal_user_data_t *ud)
                        ghb_countdown_dialog(GTK_MESSAGE_WARNING, 
                                "Your encode is complete.",
                                "Shutting down the computer", 
-                               "Cancel", (GSourceFunc)shutdown_cb, 60);
+                               "Cancel", (GSourceFunc)shutdown_cb, ud, 60);
                }
        }
        if (ghb_settings_combo_int(ud->settings, "WhenComplete") == 2)
@@ -4570,7 +4905,14 @@ ghb_notify_done(signal_user_data_t *ud)
                        ghb_countdown_dialog(GTK_MESSAGE_WARNING, 
                                "Your encode is complete.",
                                "Putting computer to sleep", 
-                               "Cancel", (GSourceFunc)suspend_cb, 60);
+                               "Cancel", (GSourceFunc)suspend_cb, ud, 60);
                }
        }
+       if (ghb_settings_combo_int(ud->settings, "WhenComplete") == 4)
+       {
+               ghb_countdown_dialog(GTK_MESSAGE_WARNING, 
+                                                       "Your encode is complete.",
+                                                       "Quiting Handbrake", 
+                                                       "Cancel", (GSourceFunc)quit_cb, ud, 60);
+       }
 }