+ 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)
+{
+ 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);
+ combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, "source_device"));
+ 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");
+ while (link != NULL)
+ {
+ gchar *name = get_dvd_device_name(link->data);
+ gtk_combo_box_append_text(combo, name);
+ g_free(name);
+ free_drive(link->data);
+ link = link->next;
+ }
+ g_list_free(drives);
+}
+
+extern GValue *ghb_queue_edit_settings;
+static gchar *last_scan_file = NULL;
+
+static void
+show_scan_progress(signal_user_data_t *ud)
+{
+ GtkProgressBar *progress;
+ GtkLabel *label;
+
+ progress = GTK_PROGRESS_BAR(GHB_WIDGET(ud->builder, "scan_prog"));
+ gtk_progress_bar_set_fraction (progress, 0);
+ gtk_widget_show(GTK_WIDGET(progress));
+
+ label = GTK_LABEL(GHB_WIDGET(ud->builder, "source_title"));
+ gtk_label_set_text( label, "Scanning ..." );
+}
+
+static void
+start_scan(
+ signal_user_data_t *ud,
+ const gchar *path,
+ gint titlenum,
+ gint preview_count)
+{
+ GtkWidget *widget;
+ GtkAction *action;
+ ghb_status_t status;
+
+ ghb_get_status(&status);
+ if (status.scan.state != GHB_STATE_IDLE)
+ return;
+
+ widget = GHB_WIDGET(ud->builder, "sourcetoolbutton");
+ 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);
+}
+
+void
+ghb_do_scan(
+ signal_user_data_t *ud,
+ const gchar *filename,
+ gint titlenum,
+ gboolean force)
+{
+ g_debug("ghb_do_scan()");
+ if (!force && last_scan_file != NULL &&
+ strcmp(last_scan_file, filename) == 0)
+ {
+ if (ghb_queue_edit_settings)
+ {
+ 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);
+ reset_chapter_list(ud, ghb_queue_edit_settings);
+ 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, "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, "scan_source");
+ prune_logs(ud);
+
+ preview_count = ghb_settings_get_int(ud->settings, "preview_count");
+ start_scan(ud, path, titlenum, preview_count);
+ g_free(path);
+ }
+ else
+ {
+ // TODO: error dialog
+ }
+ }
+}
+
+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, "scan_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, "scan_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;
+ }
+ GtkWidget *widget;
+ widget = GHB_WIDGET(ud->builder, "single_title_box");
+ if (single)
+ gtk_widget_show(widget);
+ 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);
+ response = gtk_dialog_run(GTK_DIALOG (dialog));
+ gtk_widget_hide(dialog);
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ gchar *filename;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ if (filename != NULL)
+ {
+ gint titlenum;
+
+ if (single)
+ titlenum = ghb_settings_get_int(ud->settings, "single_title");
+ else
+ titlenum = 0;
+ ghb_do_scan(ud, filename, titlenum, TRUE);
+ if (strcmp(sourcename, filename) != 0)
+ {
+ ghb_settings_set_string (ud->settings,
+ "default_source", filename);
+ ghb_pref_save (ud->settings, "default_source");
+ ghb_dvd_set_current (filename, ud);
+ }
+ g_free(filename);
+ }
+ }
+ g_free(sourcename);
+}
+
+G_MODULE_EXPORT void
+source_button_clicked_cb(GtkButton *button, signal_user_data_t *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
+single_title_source_cb(GtkButton *button, signal_user_data_t *ud)
+{
+ do_source_dialog(button, TRUE, ud);
+}
+
+G_MODULE_EXPORT void
+dvd_source_activate_cb(GtkAction *action, signal_user_data_t *ud)
+{
+ const gchar *filename;
+ gchar *sourcename;
+
+ 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)
+ {
+ ghb_settings_set_string (ud->settings, "default_source", filename);
+ ghb_pref_save (ud->settings, "default_source");
+ ghb_dvd_set_current (filename, ud);
+ }
+ g_free(sourcename);
+}
+
+void
+ghb_update_destination_extension(signal_user_data_t *ud)
+{
+ static gchar *containers[] = {".mkv", ".mp4", ".m4v", NULL};
+ gchar *filename;
+ const gchar *extension;
+ gint ii;
+ GtkEntry *entry;
+ static gboolean busy = FALSE;
+
+ g_debug("ghb_update_destination_extension ()");
+ // Since this function modifies the thing that triggers it's
+ // invocation, check to see if busy to prevent accidental infinite
+ // recursion.
+ if (busy)
+ return;
+ busy = TRUE;
+ extension = get_extension(ud);
+ entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "dest_file"));
+ filename = g_strdup(gtk_entry_get_text(entry));
+ for (ii = 0; containers[ii] != NULL; ii++)
+ {
+ if (g_str_has_suffix(filename, containers[ii]))
+ {
+ gchar *pos;
+ gchar *new_name;
+
+ pos = g_strrstr( filename, "." );
+ if (pos == NULL)
+ {
+ // No period? shouldn't happen
+ break;
+ }
+ *pos = 0;
+ if (strcmp(extension, &pos[1]) == 0)
+ {
+ // Extension is already correct
+ break;
+ }
+ new_name = g_strjoin(".", filename, extension, NULL);
+ ghb_ui_update(ud, "dest_file", ghb_string_value(new_name));
+ g_free(new_name);
+ break;
+ }
+ }
+ g_free(filename);
+ busy = FALSE;
+}
+
+static void
+destination_select_title(GtkEntry *entry)
+{
+ const gchar *dest;
+ gint start, end;
+
+ dest = gtk_entry_get_text(entry);
+ for (end = strlen(dest)-1; end > 0; end--)
+ {
+ if (dest[end] == '.')
+ {
+ break;
+ }
+ }
+ for (start = end; start >= 0; start--)
+ {
+ if (dest[start] == G_DIR_SEPARATOR)
+ {
+ start++;
+ break;
+ }
+ }
+ if (start < 0) start = 0;
+ if (start < end)
+ {
+ gtk_editable_select_region(GTK_EDITABLE(entry), start, end);
+ }
+}
+
+G_MODULE_EXPORT gboolean
+destination_grab_cb(
+ GtkEntry *entry,
+ signal_user_data_t *ud)
+{
+ destination_select_title(entry);
+ return FALSE;
+}
+
+static gboolean update_default_destination = FALSE;
+
+G_MODULE_EXPORT void
+dest_dir_set_cb(GtkFileChooserButton *dest_chooser, signal_user_data_t *ud)
+{
+ gchar *dest_file, *dest_dir, *dest;