summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gtk/src/audiohandler.c2212
-rw-r--r--gtk/src/audiohandler.h11
-rw-r--r--gtk/src/callbacks.c16
-rw-r--r--gtk/src/ghb.ui2636
-rw-r--r--gtk/src/hb-backend.c1008
-rw-r--r--gtk/src/hb-backend.h25
-rw-r--r--gtk/src/internal_defaults.xml41
-rw-r--r--gtk/src/main.c197
-rw-r--r--gtk/src/makedeps.py27
-rw-r--r--gtk/src/presets.c304
-rw-r--r--gtk/src/queuehandler.c8
-rw-r--r--gtk/src/settings.c47
-rw-r--r--gtk/src/settings.h1
-rw-r--r--gtk/src/subtitlehandler.c2128
-rw-r--r--gtk/src/subtitlehandler.h12
-rw-r--r--gtk/src/values.c1
-rw-r--r--gtk/src/widgetdeps.c10
17 files changed, 5125 insertions, 3559 deletions
diff --git a/gtk/src/audiohandler.c b/gtk/src/audiohandler.c
index 67e979d14..f30b5ee87 100644
--- a/gtk/src/audiohandler.c
+++ b/gtk/src/audiohandler.c
@@ -2,9 +2,9 @@
/*
* audiohandler.c
* Copyright (C) John Stebbins 2008-2013 <stebbins@stebbins>
- *
+ *
* audiohandler.c is free software.
- *
+ *
* You may redistribute it and/or modify it under the terms of the
* GNU General Public License, as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
@@ -20,67 +20,86 @@
#include "callbacks.h"
#include "preview.h"
#include "audiohandler.h"
+#include "presets.h"
-static gboolean ghb_add_audio_to_settings(GValue *settings, GValue *asettings);
-static void ghb_add_audio_to_ui(GtkBuilder *builder, const GValue *settings);
-static GValue* get_selected_asettings(signal_user_data_t *ud);
+static void audio_add_to_settings(GValue *settings, GValue *asettings);
+static void ghb_add_audio_to_ui(signal_user_data_t *ud, const GValue *settings);
+static GValue* audio_get_selected_settings(signal_user_data_t *ud, int *index);
static void ghb_clear_audio_list_settings(GValue *settings);
static void ghb_clear_audio_list_ui(GtkBuilder *builder);
static gboolean block_updates = FALSE;
-static void audio_deps(signal_user_data_t *ud)
+static void enable_quality_widget(signal_user_data_t *ud, int acodec)
+{
+ GtkWidget *widget1, *widget2;
+
+ widget1 = GHB_WIDGET(ud->builder, "AudioTrackQualityEnable");
+ widget2 = GHB_WIDGET(ud->builder, "AudioTrackBitrateEnable");
+ if (hb_audio_quality_get_default(acodec) == HB_INVALID_AUDIO_QUALITY)
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget2), TRUE);
+ gtk_widget_set_sensitive(widget1, FALSE);
+ }
+ else
+ {
+ gtk_widget_set_sensitive(widget1, TRUE);
+ }
+}
+
+static void audio_deps(signal_user_data_t *ud, GValue *asettings, GtkWidget *widget)
{
+ ghb_adjust_audio_rate_combos(ud);
+ ghb_grey_combo_options (ud);
+ if (widget != NULL)
+ ghb_check_dependency(ud, widget, NULL);
+
gint track = -1, encoder = 0;
hb_audio_config_t *aconfig = NULL;
gint titleindex = ghb_settings_combo_int(ud->settings, "title");
- GValue *asettings = get_selected_asettings(ud);
if (asettings != NULL)
{
track = ghb_settings_combo_int(asettings, "AudioTrack");
- encoder = ghb_settings_combo_int(asettings, "AudioEncoderActual");
+ encoder = ghb_settings_combo_int(asettings, "AudioEncoder");
aconfig = ghb_get_scan_audio_info(titleindex, track);
}
+ gboolean is_passthru = (encoder & HB_ACODEC_PASS_FLAG);
gboolean enable_drc = TRUE;
if (aconfig != NULL)
{
enable_drc = hb_audio_can_apply_drc(aconfig->in.codec,
- aconfig->in.codec_param, encoder);
+ aconfig->in.codec_param, encoder) &&
+ !is_passthru;
}
- GtkWidget * widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
+ widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
gtk_widget_set_sensitive(widget, enable_drc);
widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSliderLabel");
gtk_widget_set_sensitive(widget, enable_drc);
widget = GHB_WIDGET(ud->builder, "AudioTrackDRCValue");
gtk_widget_set_sensitive(widget, enable_drc);
-}
-void
-ghb_show_hide_advanced_audio( signal_user_data_t *ud )
-{
- GtkWidget *widget;
-
- g_debug("audio_advanced_clicked_cb ()");
- widget = GHB_WIDGET(ud->builder, "AdvancedAudioPassTable");
- if (!ghb_settings_get_boolean(ud->settings, "AdvancedAutoPassthru"))
- gtk_widget_hide(widget);
- else
- gtk_widget_show(widget);
-}
+ enable_quality_widget(ud, encoder);
-void
-check_list_full(signal_user_data_t *ud)
-{
- GValue *audio_list;
- gint count;
- audio_list = ghb_settings_get_value(ud->settings, "audio_list");
- count = ghb_array_len(audio_list);
- GtkWidget * widget = GHB_WIDGET(ud->builder, "audio_add");
- gtk_widget_set_sensitive(widget, count != 99);
+ widget = GHB_WIDGET(ud->builder, "AudioBitrate");
+ gtk_widget_set_sensitive(widget, !is_passthru);
+ widget = GHB_WIDGET(ud->builder, "AudioTrackQualityEnableBox");
+ gtk_widget_set_sensitive(widget, !is_passthru);
+ widget = GHB_WIDGET(ud->builder, "AudioTrackQualityBox");
+ gtk_widget_set_sensitive(widget, !is_passthru);
+ widget = GHB_WIDGET(ud->builder, "AudioMixdown");
+ gtk_widget_set_sensitive(widget, !is_passthru);
+ widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
+ gtk_widget_set_sensitive(widget, !is_passthru);
+ widget = GHB_WIDGET(ud->builder, "AudioTrackGain");
+ gtk_widget_set_sensitive(widget, !is_passthru);
+ widget = GHB_WIDGET(ud->builder, "AudioTrackGain");
+ gtk_widget_set_sensitive(widget, !is_passthru);
+ widget = GHB_WIDGET(ud->builder, "AudioTrackGainValue");
+ gtk_widget_set_sensitive(widget, !is_passthru);
}
gint
@@ -152,7 +171,7 @@ int ghb_get_copy_mask(GValue *settings)
return mask;
}
-int ghb_select_fallback( GValue *settings, int mux, int acodec )
+int ghb_select_fallback(GValue *settings, int acodec)
{
gint fallback = 0;
@@ -169,6 +188,7 @@ int ghb_select_fallback( GValue *settings, int mux, int acodec )
default:
{
+ int mux = ghb_settings_combo_int(settings, "FileFormat");
fallback = ghb_settings_combo_int(settings, "AudioEncoderFallback");
return hb_autopassthru_get_encoder(acodec, 0, fallback, mux);
}
@@ -176,14 +196,14 @@ int ghb_select_fallback( GValue *settings, int mux, int acodec )
}
void
-ghb_sanitize_audio(GValue *settings, GValue *asettings)
+audio_sanitize_settings(GValue *settings, GValue *asettings)
{
gint titleindex, track, acodec, select_acodec, mix;
hb_audio_config_t *aconfig;
gint mux;
gint bitrate;
gint sr;
-
+
g_debug("ghb_santiize_audio ()");
mux = ghb_settings_combo_int(settings, "FileFormat");
titleindex = ghb_settings_get_int(settings, "title_no");
@@ -198,9 +218,10 @@ ghb_sanitize_audio(GValue *settings, GValue *asettings)
{
sr = aconfig ? aconfig->in.samplerate : 48000;
}
- gint fallback = ghb_select_fallback(settings, mux, acodec);
+ gint fallback = ghb_select_fallback(settings, acodec);
gint copy_mask = ghb_get_copy_mask(settings);
- select_acodec = ghb_select_audio_codec(mux, aconfig, acodec, fallback, copy_mask);
+ select_acodec = ghb_select_audio_codec(mux, aconfig, acodec,
+ fallback, copy_mask);
if (ghb_audio_is_passthru (select_acodec))
{
if (aconfig)
@@ -237,7 +258,7 @@ ghb_sanitize_audio(GValue *settings, GValue *asettings)
ghb_settings_set_string(asettings, "AudioBitrate",
ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate)));
- ghb_settings_take_value(asettings, "AudioEncoderActual",
+ ghb_settings_take_value(asettings, "AudioEncoder",
ghb_lookup_audio_encoder_value(select_acodec));
}
@@ -251,7 +272,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
gint mux;
gint bitrate;
gint sr = 48000;
-
+
g_debug("ghb_adjust_audio_rate_combos ()");
mux = ghb_settings_combo_int(ud->settings, "FileFormat");
titleindex = ghb_settings_combo_int(ud->settings, "title");
@@ -284,7 +305,7 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
{
sr = aconfig ? aconfig->in.samplerate : 48000;
}
- gint fallback = ghb_select_fallback( ud->settings, mux, acodec );
+ gint fallback = ghb_select_fallback(ud->settings, acodec);
gint copy_mask = ghb_get_copy_mask(ud->settings);
select_acodec = ghb_select_audio_codec(mux, aconfig, acodec, fallback, copy_mask);
gboolean codec_defined_bitrate = FALSE;
@@ -327,16 +348,46 @@ ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
}
ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(bitrate));
- ghb_settings_take_value(ud->settings, "AudioEncoderActual",
+ ghb_settings_take_value(ud->settings, "AudioEncoder",
ghb_lookup_audio_encoder_value(select_acodec));
- GValue *asettings = get_selected_asettings(ud);
+ GValue *asettings = audio_get_selected_settings(ud, NULL);
if (asettings)
{
- ghb_settings_take_value(asettings, "AudioEncoderActual",
+ ghb_settings_take_value(asettings, "AudioEncoder",
ghb_lookup_audio_encoder_value(select_acodec));
}
ghb_audio_list_refresh_selected(ud);
- ghb_check_dependency(ud, NULL, "AudioEncoderActual");
+}
+
+static void
+audio_update_dialog_widgets(signal_user_data_t *ud, GValue *asettings)
+{
+ if (asettings != NULL)
+ {
+ block_updates = TRUE;
+ ghb_ui_update(ud, "AudioTrack",
+ ghb_settings_get_value(asettings, "AudioTrack"));
+ ghb_ui_update(ud, "AudioEncoder",
+ ghb_settings_get_value(asettings, "AudioEncoder"));
+ ghb_ui_update(ud, "AudioBitrate",
+ ghb_settings_get_value(asettings, "AudioBitrate"));
+ ghb_ui_update(ud, "AudioTrackName",
+ ghb_settings_get_value(asettings, "AudioTrackName"));
+ ghb_ui_update(ud, "AudioSamplerate",
+ ghb_settings_get_value(asettings, "AudioSamplerate"));
+ ghb_ui_update(ud, "AudioMixdown",
+ ghb_settings_get_value(asettings, "AudioMixdown"));
+ ghb_ui_update(ud, "AudioTrackDRCSlider",
+ ghb_settings_get_value(asettings, "AudioTrackDRCSlider"));
+ ghb_ui_update(ud, "AudioTrackGain",
+ ghb_settings_get_value(asettings, "AudioTrackGain"));
+ ghb_ui_update(ud, "AudioTrackQuality",
+ ghb_settings_get_value(asettings, "AudioTrackQuality"));
+ ghb_ui_update(ud, "AudioTrackQualityEnable",
+ ghb_settings_get_value(asettings, "AudioTrackQualityEnable"));
+ block_updates = FALSE;
+ }
+ audio_deps(ud, asettings, NULL);
}
static void
@@ -346,7 +397,7 @@ free_audio_hash_key_value(gpointer data)
}
const gchar*
-ghb_get_user_audio_lang(GValue *settings, gint titleindex, gint track)
+ghb_get_user_audio_lang(GValue *settings, hb_title_t *title, gint track)
{
GValue *audio_list, *asettings;
const gchar *lang;
@@ -356,125 +407,277 @@ ghb_get_user_audio_lang(GValue *settings, gint titleindex, gint track)
return "und";
asettings = ghb_array_get_nth(audio_list, track);
track = ghb_settings_get_int(asettings, "AudioTrack");
- lang = ghb_get_source_audio_lang(titleindex, track);
+ lang = ghb_get_source_audio_lang(title, track);
return lang;
}
-void
-ghb_set_pref_audio_settings(gint titleindex, GValue *settings)
+static gboolean*
+get_track_used(gint settings, GHashTable *track_indices, gint count)
{
- gint track;
- gchar *source_lang;
- hb_audio_config_t *aconfig;
- GHashTable *track_indices;
- gint mux;
+ gboolean *used;
- const GValue *pref_audio;
- const GValue *audio, *drc, *gain, *enable_qual;
- gint acodec, bitrate, mix;
- gdouble rate, quality;
- gint count, ii, list_count;
-
- g_debug("set_pref_audio");
- mux = ghb_settings_combo_int(settings, "FileFormat");
- track_indices = g_hash_table_new_full(g_int_hash, g_int_equal,
- free_audio_hash_key_value, free_audio_hash_key_value);
- // Clear the audio list
- ghb_clear_audio_list_settings(settings);
+ used = g_hash_table_lookup(track_indices, &settings);
+ if (used == NULL)
+ {
+ gint *key;
- // Find "best" audio based on audio preferences
- if (!ghb_settings_get_boolean(settings, "AudioDUB"))
+ used = g_malloc0(count * sizeof(gboolean));
+ key = g_malloc(sizeof(gint));
+ *key = settings;
+ g_hash_table_insert(track_indices, key, used);
+ }
+ return used;
+}
+
+static GValue*
+audio_add_track(
+ GValue *settings,
+ hb_title_t *title,
+ int track,
+ int encoder,
+ gboolean enable_quality,
+ gdouble quality,
+ int bitrate,
+ int samplerate,
+ int mix,
+ gdouble drc,
+ gdouble gain)
+{
+ GValue *asettings;
+ hb_audio_config_t *aconfig = NULL;
+
+ if (title != NULL)
{
- source_lang = g_strdup(ghb_get_source_audio_lang(titleindex, 0));
+ aconfig = hb_list_audio_config_item(title->list_audio, track);
}
- else
+
+ asettings = ghb_dict_value_new();
+
+ ghb_settings_set_int(asettings, "AudioTrack", track);
+
+ ghb_settings_set_string(asettings, "AudioEncoder",
+ ghb_lookup_combo_string("AudioEncoder", ghb_int_value(encoder)));
+
+ ghb_settings_set_boolean(asettings,
+ "AudioTrackQualityEnable", enable_quality);
+ ghb_settings_set_double(asettings, "AudioTrackQuality", quality);
+
+ ghb_settings_set_string(asettings, "AudioBitrate",
+ ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate)));
+
+ ghb_settings_set_string(asettings, "AudioSamplerate",
+ ghb_lookup_combo_string("AudioSamplerate", ghb_int_value(samplerate)));
+
+ if (aconfig != NULL)
{
- source_lang = ghb_settings_get_string(settings, "PreferredLanguage");
+ mix = ghb_get_best_mix(aconfig, encoder, mix);
}
+ ghb_settings_set_string(asettings, "AudioMixdown",
+ ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix)));
- pref_audio = ghb_settings_get_value(settings, "AudioList");
+ ghb_settings_set_double(asettings, "AudioTrackDRCSlider", drc);
- list_count = 0;
- count = ghb_array_len(pref_audio);
- for (ii = 0; ii < count; ii++)
+ ghb_settings_set_double(asettings, "AudioTrackGain", gain);
+
+ audio_sanitize_settings(settings, asettings);
+ audio_add_to_settings(settings, asettings);
+
+ return asettings;
+}
+
+static GValue*
+audio_select_and_add_track(
+ hb_title_t *title,
+ GValue *settings,
+ GValue *pref_audio,
+ const char *lang,
+ int pref_index,
+ int start_track)
+{
+ GValue *audio, *asettings = NULL;
+ gdouble drc, gain, quality;
+ gboolean enable_quality;
+ gint track, mux, acodec, bitrate, samplerate, mix;
+
+ gint select_acodec;
+ gint fallback;
+
+ mux = ghb_settings_combo_int(settings, "FileFormat");
+ gint copy_mask = ghb_get_copy_mask(settings);
+
+ audio = ghb_array_get_nth(pref_audio, pref_index);
+
+ acodec = ghb_settings_combo_int(audio, "AudioEncoder");
+ fallback = ghb_select_fallback(settings, acodec);
+
+ bitrate = ghb_settings_combo_int(audio, "AudioBitrate");
+ samplerate = ghb_settings_combo_int(audio, "AudioSamplerate");
+ mix = ghb_settings_combo_int(audio, "AudioMixdown");
+ drc = ghb_settings_get_double(audio, "AudioTrackDRCSlider");
+ gain = ghb_settings_get_double(audio, "AudioTrackGain");
+ enable_quality = ghb_settings_get_boolean(audio, "AudioTrackQualityEnable");
+ quality = ghb_settings_get_double(audio, "AudioTrackQuality");
+
+ track = ghb_find_audio_track(title, lang, start_track);
+ if (track >= 0)
{
- gint select_acodec;
- gint fallback;
-
- audio = ghb_array_get_nth(pref_audio, ii);
- acodec = ghb_settings_combo_int(audio, "AudioEncoder");
- fallback = ghb_select_fallback(settings, mux, acodec);
- gint copy_mask = ghb_get_copy_mask(settings);
- select_acodec = ghb_select_audio_codec(mux, NULL, acodec, fallback, copy_mask);
- bitrate = ghb_settings_combo_int(audio, "AudioBitrate");
- rate = ghb_settings_combo_double(audio, "AudioSamplerate");
- mix = ghb_settings_combo_int(audio, "AudioMixdown");
- drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
- gain = ghb_settings_get_value(audio, "AudioTrackGain");
- enable_qual = ghb_settings_get_value(audio, "AudioTrackQualityEnable");
- quality = ghb_settings_get_double(audio, "AudioTrackQuality");
- // If there are multiple audios using the same codec, then
- // select sequential tracks for each. The hash keeps track
- // of the tracks used for each codec.
- track = ghb_find_audio_track(titleindex, source_lang,
- select_acodec, fallback, track_indices);
// Check to see if:
// 1. pref codec is passthru
// 2. source codec is not passthru
// 3. next pref is enabled
- aconfig = ghb_get_scan_audio_info(titleindex, track);
- if (aconfig && ghb_audio_is_passthru (acodec))
+ hb_audio_config_t *aconfig;
+ aconfig = hb_list_audio_config_item(title->list_audio, track);
+ select_acodec = ghb_select_audio_codec(
+ mux, aconfig, acodec, fallback, copy_mask);
+
+ asettings = audio_add_track(settings, title, track, select_acodec,
+ enable_quality, quality, bitrate,
+ samplerate, mix, drc, gain);
+ }
+ return asettings;
+}
+
+static void set_pref_audio_with_lang(
+ hb_title_t *title,
+ GValue *settings,
+ const char *lang,
+ int behavior,
+ gboolean secondary_audio_track_mode,
+ GHashTable *track_used)
+{
+ const GValue *pref_audio, *audio_list;
+ int count, ii, track, track_count, audio_count;
+ gint mux;
+
+ audio_list = ghb_settings_get_value(settings, "audio_list");
+
+ mux = ghb_settings_combo_int(settings, "FileFormat");
+ pref_audio = ghb_settings_get_value(settings, "AudioList");
+ audio_count = hb_list_count(title->list_audio);
+ count = ghb_array_len(pref_audio);
+ int next_track = 0;
+ track = ghb_find_audio_track(title, lang, next_track);
+ while (track >= 0)
+ {
+ track_count = ghb_array_len(audio_list);
+ count = (track_count && secondary_audio_track_mode) ? 1 : count;
+ for (ii = 0; ii < count; ii++)
{
- // HB_ACODEC_* are bit fields. Treat acodec as mask
- if (!(aconfig->in.codec & select_acodec & HB_ACODEC_PASS_MASK))
- {
- if (acodec != HB_ACODEC_AUTO_PASS)
- acodec = fallback;
- // If we can't substitute the passthru with a suitable
- // encoder and
- // If there's more audio to process, or we've already
- // placed one in the list, then we can skip this one
- if (!(select_acodec & fallback) &&
- ((ii + 1 < count) || (list_count != 0)))
- {
- // Skip this audio
- acodec = 0;
- }
- }
- else
+ const GValue *audio;
+ gint acodec, fallback, copy_mask, bitrate, samplerate, mix;
+ gint select_acodec;
+ gdouble drc, gain, quality;
+ gboolean enable_quality;
+
+ audio = ghb_array_get_nth(pref_audio, ii);
+ acodec = ghb_settings_combo_int(audio, "AudioEncoder");
+ fallback = ghb_select_fallback(settings, acodec);
+ copy_mask = ghb_get_copy_mask(settings);
+ bitrate = ghb_settings_combo_int(audio, "AudioBitrate");
+ samplerate = ghb_settings_combo_int(audio, "AudioSamplerate");
+ mix = ghb_settings_combo_int(audio, "AudioMixdown");
+ drc = ghb_settings_get_double(audio, "AudioTrackDRCSlider");
+ gain = ghb_settings_get_double(audio, "AudioTrackGain");
+ enable_quality = ghb_settings_get_boolean(audio,
+ "AudioTrackQualityEnable");
+ quality = ghb_settings_get_double(audio, "AudioTrackQuality");
+
+ // Check to see if:
+ // 1. pref codec is passthru
+ // 2. source codec is not passthru
+ // 3. next pref is enabled
+ hb_audio_config_t *aconfig;
+ aconfig = hb_list_audio_config_item(title->list_audio, track);
+ select_acodec = ghb_select_audio_codec(
+ mux, aconfig, acodec, fallback, copy_mask);
+
+ // Was the source track already encoded
+ // with the selected encode settings.
+ gboolean *used = get_track_used(ii, track_used, audio_count);
+ if (!used[track])
{
- select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG;
+ used[track] = TRUE;
+ audio_add_track(settings, title, track, select_acodec,
+ enable_quality, quality, bitrate,
+ samplerate, mix, drc, gain);
}
}
- if (titleindex >= 0 && track < 0)
- acodec = 0;
- if (acodec != 0)
- {
- GValue *asettings = ghb_dict_value_new();
- ghb_settings_set_int(asettings, "AudioTrack", track);
- ghb_settings_set_string(asettings, "AudioEncoder",
- ghb_lookup_combo_string("AudioEncoder", ghb_int_value(acodec)));
- ghb_settings_set_value(asettings, "AudioEncoderActual",
- ghb_lookup_audio_encoder_value(select_acodec));
- ghb_settings_set_value(asettings, "AudioTrackQualityEnable", enable_qual);
- ghb_settings_set_double(asettings, "AudioTrackQuality", quality);
- // This gets set autimatically if the codec is passthru
- ghb_settings_set_string(asettings, "AudioBitrate",
- ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate)));
- ghb_settings_set_string(asettings, "AudioSamplerate",
- ghb_lookup_combo_string("AudioSamplerate", ghb_int_value(rate)));
- mix = ghb_get_best_mix( aconfig, select_acodec, mix);
- ghb_settings_set_string(asettings, "AudioMixdown",
- ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix)));
- ghb_settings_set_value(asettings, "AudioTrackDRCSlider", drc);
- ghb_settings_set_value(asettings, "AudioTrackGain", gain);
- ghb_sanitize_audio(settings, asettings);
- ghb_add_audio_to_settings(settings, asettings);
+ next_track = track + 1;
+ if (behavior == 2)
+ {
+ track = ghb_find_audio_track(title, lang, next_track);
+ }
+ else
+ {
+ break;
}
}
- g_free(source_lang);
- g_hash_table_destroy(track_indices);
+}
+
+void ghb_audio_title_change(signal_user_data_t *ud, gboolean title_valid)
+{
+ GtkWidget *w = GHB_WIDGET(ud->builder, "audio_add");
+ gtk_widget_set_sensitive(w, title_valid);
+ w = GHB_WIDGET(ud->builder, "audio_add_all");
+ gtk_widget_set_sensitive(w, title_valid);
+ w = GHB_WIDGET(ud->builder, "audio_reset");
+ gtk_widget_set_sensitive(w, title_valid);
+}
+
+void
+ghb_set_pref_audio_settings(gint titleindex, GValue *settings)
+{
+ GHashTable *track_used;
+ hb_title_t *title;
+
+ const GValue *lang_list;
+ gint behavior;
+ gint ii, audio_count, lang_count;
+
+ g_debug("set_pref_audio");
+ behavior = ghb_settings_combo_int(settings, "AudioTrackSelectionBehavior");
+
+ // Clear the audio list
+ ghb_clear_audio_list_settings(settings);
+
+ title = ghb_get_title_info(titleindex);
+ if (behavior == 0 || title == NULL)
+ {
+ // None or no source title
+ return;
+ }
+ audio_count = hb_list_count(title->list_audio);
+ if (audio_count == 0)
+ {
+ // No source audio
+ return;
+ }
+
+ track_used = g_hash_table_new_full(g_int_hash, g_int_equal,
+ free_audio_hash_key_value, free_audio_hash_key_value);
+
+ // Find "best" audio based on audio preset defaults
+ lang_list = ghb_settings_get_value(settings, "AudioLanguageList");
+
+ lang_count = ghb_array_len(lang_list);
+ for (ii = 0; ii < lang_count; ii++)
+ {
+ const gchar *lang;
+ gboolean mode;
+ GValue *glang = ghb_array_get_nth(lang_list, ii);
+ lang = g_value_get_string(glang);
+ mode = ghb_settings_get_boolean(settings, "AudioSecondaryEncoderMode");
+ set_pref_audio_with_lang(title, settings, lang, behavior, mode, track_used);
+ }
+ GValue *audio_list = ghb_settings_get_value(settings, "audio_list");
+ if (audio_list == NULL || ghb_array_len(audio_list) == 0)
+ {
+ // No matching audio tracks found. Add first track matching
+ // any language.
+ set_pref_audio_with_lang(title, settings, "und", 1, FALSE, track_used);
+ }
+ g_hash_table_destroy(track_used);
}
void
@@ -491,234 +694,284 @@ ghb_set_pref_audio_from_settings(signal_user_data_t *ud, GValue *settings)
for (ii = 0; ii < count; ii++)
{
audio = ghb_array_get_nth(audio_list, ii);
- ghb_add_audio_to_ui(ud->builder, audio);
+ ghb_add_audio_to_ui(ud, audio);
ghb_adjust_audio_rate_combos(ud);
}
- check_list_full(ud);
}
static GValue*
-get_selected_asettings(signal_user_data_t *ud)
+audio_get_selected_settings(signal_user_data_t *ud, int *index)
{
- GtkTreeView *treeview;
- GtkTreePath *treepath;
- GtkTreeSelection *selection;
- GtkTreeModel *store;
- GtkTreeIter iter;
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeSelection *ts;
+ GtkTreeModel *tm;
+ GtkTreeIter ti;
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))
+
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
+ ts = gtk_tree_view_get_selection (tv);
+ if (gtk_tree_selection_get_selected(ts, &tm, &ti))
{
// Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
+ tp = gtk_tree_model_get_path (tm, &ti);
+ indices = gtk_tree_path_get_indices (tp);
row = indices[0];
- gtk_tree_path_free(treepath);
+ gtk_tree_path_free(tp);
// 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);
+ if (index != NULL)
+ *index = row;
}
return asettings;
}
-void
-ghb_audio_list_refresh_selected(signal_user_data_t *ud)
+static void
+audio_refresh_list_row_ui(
+ GtkTreeModel *tm,
+ GtkTreeIter *ti,
+ signal_user_data_t *ud,
+ const GValue *settings)
{
- GtkTreeView *treeview;
- GtkTreePath *treepath;
- GtkTreeSelection *selection;
- GtkTreeModel *store;
- GtkTreeIter iter;
- gint *indices;
- gint row;
- GValue *asettings = NULL;
- const GValue *audio_list;
-
- g_debug("ghb_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))
+ GtkTreeIter cti;
+ char *info_src, *info_src_2;
+ char *info_dst, *info_dst_2;
+
+
+ info_src_2 = NULL;
+ info_dst_2 = NULL;
+
+ const gchar *s_track, *s_codec, *s_mix;
+ gchar *s_drc, *s_gain, *s_br_quality, *s_sr, *s_track_name;
+ gdouble drc, gain;
+ hb_audio_config_t *aconfig;
+ int titleindex, track, sr, codec;
+
+ titleindex = ghb_settings_combo_int(ud->settings, "title");
+ track = ghb_settings_combo_int(settings, "AudioTrack");
+ aconfig = ghb_get_scan_audio_info(titleindex, track);
+ if (aconfig == NULL)
{
- const gchar *track, *codec, *br = NULL, *sr, *mix;
- gchar *s_drc, *s_gain, *s_quality = NULL;
- gdouble drc, gain;
- // Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
- row = indices[0];
- gtk_tree_path_free(treepath);
- // 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);
+ return;
+ }
- track = ghb_settings_combo_option(asettings, "AudioTrack");
- codec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
- double quality = ghb_settings_get_double(asettings, "AudioTrackQuality");
- if (ghb_settings_get_boolean(asettings, "AudioTrackQualityEnable") &&
- quality != HB_INVALID_AUDIO_QUALITY)
+
+ s_track = ghb_settings_combo_option(settings, "AudioTrack");
+ codec = ghb_settings_combo_int(settings, "AudioEncoder");
+ s_codec = ghb_settings_combo_option(settings, "AudioEncoder");
+
+ double quality = ghb_settings_get_double(settings, "AudioTrackQuality");
+ if (ghb_settings_get_boolean(settings, "AudioTrackQualityEnable") &&
+ quality != HB_INVALID_AUDIO_QUALITY)
+ {
+ s_br_quality = ghb_format_quality("Quality: ", codec, quality);
+ }
+ else
+ {
+ s_br_quality = g_strdup_printf("Bitrate: %skbps",
+ ghb_settings_combo_option(settings, "AudioBitrate"));
+ }
+
+ sr = ghb_settings_combo_int(settings, "AudioSamplerate");
+ if (sr == 0)
+ {
+ sr = aconfig->in.samplerate;
+ }
+ s_sr = g_strdup_printf("%.4gkHz", (double)sr/1000);
+
+ s_mix = ghb_settings_combo_option(settings, "AudioMixdown");
+ gain = ghb_settings_get_double(settings, "AudioTrackGain");
+ s_gain = g_strdup_printf("%ddB", (int)gain);
+
+ drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
+ if (drc < 1.0)
+ s_drc = g_strdup(_("Off"));
+ else
+ s_drc = g_strdup_printf("%.1f", drc);
+
+ s_track_name = ghb_settings_get_string(settings, "AudioTrackName");
+
+ info_src = g_strdup_printf("%s (%.4gkHz)",
+ s_track,
+ (double)aconfig->in.samplerate / 1000);
+ if (aconfig->in.bitrate > 0)
+ {
+ info_src_2 = g_strdup_printf(
+ "Bitrate: %.4gkbps",
+ (double)aconfig->in.bitrate / 1000);
+ }
+
+ if (ghb_audio_is_passthru(codec))
+ {
+ info_dst = g_strdup_printf("Passthrough");
+ }
+ else
+ {
+ info_dst = g_strdup_printf("%s (%s) (%s)", s_codec, s_mix, s_sr);
+ if (s_track_name && s_track_name[0])
{
- int codec = ghb_settings_combo_int(asettings, "AudioEncoderActual");
- s_quality = ghb_format_quality("Q/", codec, quality);
+ info_dst_2 = g_strdup_printf(
+ "%s\nGain: %s\nDRC: %s\nTrack Name: %s",
+ s_br_quality, s_gain, s_drc, s_track_name);
}
else
{
- br = ghb_settings_combo_option(asettings, "AudioBitrate");
+ info_dst_2 = g_strdup_printf("%s\nGain: %s\nDRC: %s",
+ s_br_quality, s_gain, s_drc);
}
- sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
- mix = ghb_settings_combo_option(asettings, "AudioMixdown");
- gain = ghb_settings_get_double(asettings, "AudioTrackGain");
- s_gain = g_strdup_printf("%ddB", (int)gain);
+ }
+ gtk_tree_store_set(GTK_TREE_STORE(tm), ti,
+ // These are displayed in list
+ 0, info_src,
+ 1, "-->",
+ 2, info_dst,
+ 3, "hb-edit",
+ 4, "hb-queue-delete",
+ 5, 0.5,
+ -1);
- drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
- if (drc < 1.0)
- s_drc = g_strdup(_("Off"));
- else
- s_drc = g_strdup_printf("%.1f", drc);
+ if (info_src_2 != NULL || info_dst_2 != NULL)
+ {
+ if (info_src_2 == NULL)
+ info_src_2 = g_strdup("");
+ if (info_dst_2 == NULL)
+ info_dst_2 = g_strdup("");
- gtk_list_store_set(GTK_LIST_STORE(store), &iter,
+ // Get the child of the selection
+ if (!gtk_tree_model_iter_children(tm, &cti, ti))
+ {
+ gtk_tree_store_append(GTK_TREE_STORE(tm), &cti, ti);
+ }
+ gtk_tree_store_set(GTK_TREE_STORE(tm), &cti,
// These are displayed in list
- 0, track,
- 1, codec,
- 2, s_quality ? s_quality : br,
- 3, sr,
- 4, mix,
- 5, s_gain,
- 6, s_drc,
+ 0, info_src_2,
+ 2, info_dst_2,
+ 5, 0.0,
-1);
- g_free(s_drc);
- g_free(s_gain);
- g_free(s_quality);
}
+ else
+ {
+ if(gtk_tree_model_iter_children(tm, &cti, ti))
+ {
+ gtk_tree_store_remove(GTK_TREE_STORE(tm), &cti);
+ }
+ }
+
+ g_free(info_src);
+ g_free(info_src_2);
+ g_free(info_dst);
+ g_free(info_dst_2);
+
+ g_free(s_sr);
+ g_free(s_drc);
+ g_free(s_gain);
+ g_free(s_br_quality);
+ g_free(s_track_name);
}
void
-ghb_audio_list_refresh(signal_user_data_t *ud)
+ghb_audio_list_refresh_selected(signal_user_data_t *ud)
{
- GtkTreeView *treeview;
- GtkTreeIter iter;
- GtkListStore *store;
- gboolean done;
- gint row = 0;
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeSelection *ts;
+ GtkTreeModel *tm;
+ GtkTreeIter ti;
+ gint *indices;
+ gint row;
+ GValue *asettings = NULL;
const GValue *audio_list;
- g_debug("ghb_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))
+ g_debug("ghb_audio_list_refresh_selected ()");
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
+ ts = gtk_tree_view_get_selection (tv);
+ if (gtk_tree_selection_get_selected(ts, &tm, &ti))
{
- do
- {
- const gchar *track, *codec, *br = NULL, *sr, *mix;
- gchar *s_drc, *s_gain, *s_quality = NULL;
- gdouble drc, gain;
- 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);
+ // Get the row number
+ tp = gtk_tree_model_get_path (tm, &ti);
+ indices = gtk_tree_path_get_indices (tp);
+ row = indices[0];
+ gtk_tree_path_free(tp);
+ if (row < 0) return;
- track = ghb_settings_combo_option(asettings, "AudioTrack");
- codec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
- double quality = ghb_settings_get_double(asettings, "AudioTrackQuality");
- if (ghb_settings_get_boolean(asettings, "AudioTrackQualityEnable") &&
- quality != HB_INVALID_AUDIO_QUALITY)
- {
- int codec = ghb_settings_combo_int(asettings, "AudioEncoderActual");
- s_quality = ghb_format_quality("Q/", codec, quality);
- }
- else
- {
- br = ghb_settings_get_string(asettings, "AudioBitrate");
- }
- sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
- mix = ghb_settings_combo_option(asettings, "AudioMixdown");
- gain = ghb_settings_get_double(asettings, "AudioTrackGain");
- s_gain = g_strdup_printf("%.fdB", gain);
-
- drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
- if (drc < 1.0)
- s_drc = g_strdup(_("Off"));
- else
- s_drc = g_strdup_printf("%.1f", drc);
-
- gtk_list_store_set(GTK_LIST_STORE(store), &iter,
- // These are displayed in list
- 0, track,
- 1, codec,
- 2, s_quality ? s_quality : br,
- 3, sr,
- 4, mix,
- 5, s_gain,
- 6, s_drc,
- -1);
- g_free(s_drc);
- g_free(s_gain);
- done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
- row++;
- } while (!done);
+ 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);
+ audio_refresh_list_row_ui(tm, &ti, ud, asettings);
}
}
-static void enable_quality_widget(signal_user_data_t *ud, int acodec)
+static void
+audio_refresh_list_ui(signal_user_data_t *ud)
{
- GtkWidget *widget1, *widget2, *widget3;
+ GValue *audio_list;
+ GValue *asettings;
+ gint ii, count, tm_count;
+ GtkTreeView *tv;
+ GtkTreeModel *tm;
+ GtkTreeIter ti;
- widget1 = GHB_WIDGET(ud->builder, "AudioTrackQualityEnable");
- widget2 = GHB_WIDGET(ud->builder, "AudioTrackQualityValue");
- widget3 = GHB_WIDGET(ud->builder, "AudioTrackQuality");
- if (hb_audio_quality_get_default(acodec) == HB_INVALID_AUDIO_QUALITY)
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
+ tm = gtk_tree_view_get_model(tv);
+
+ tm_count = gtk_tree_model_iter_n_children(tm, NULL);
+
+ audio_list = ghb_settings_get_value(ud->settings, "audio_list");
+ count = ghb_array_len(audio_list);
+ if (count != tm_count)
{
- gtk_widget_hide(widget1);
- gtk_widget_hide(widget2);
- gtk_widget_hide(widget3);
+ ghb_clear_audio_list_ui(ud->builder);
+ for (ii = 0; ii < count; ii++)
+ {
+ gtk_tree_store_append(GTK_TREE_STORE(tm), &ti, NULL);
+ }
}
- else
+ for (ii = 0; ii < count; ii++)
{
- gtk_widget_show(widget1);
- gtk_widget_show(widget2);
- gtk_widget_show(widget3);
+ gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
+ asettings = ghb_array_get_nth(audio_list, ii);
+ audio_refresh_list_row_ui(tm, &ti, ud, asettings);
}
}
+void
+ghb_audio_list_refresh_all(signal_user_data_t *ud)
+{
+ audio_refresh_list_ui(ud);
+}
+
G_MODULE_EXPORT void
audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
static gint prev_acodec = 0;
gint acodec_code;
- GValue *asettings, *gval;
-
- g_debug("audio_codec_changed_cb ()");
- gval = ghb_widget_value(widget);
- acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
- ghb_value_free(gval);
+ GValue *asettings;
+
+ ghb_widget_to_setting(ud->settings, widget);
+ acodec_code = ghb_settings_combo_int(ud->settings, "AudioEncoder");
- enable_quality_widget(ud, acodec_code);
if (block_updates)
{
prev_acodec = acodec_code;
- ghb_grey_combo_options (ud);
- ghb_check_dependency(ud, widget, NULL);
return;
}
- asettings = get_selected_asettings(ud);
- if (ghb_audio_is_passthru (prev_acodec) &&
+ asettings = audio_get_selected_settings(ud, NULL);
+ if (ghb_audio_is_passthru (prev_acodec) &&
!ghb_audio_is_passthru (acodec_code))
{
- // Transition from passthru to not, put some audio settings back to
+ // Transition from passthru to not, put some audio settings back to
// pref settings
gint titleindex;
gint track;
@@ -757,18 +1010,14 @@ audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
}
- ghb_adjust_audio_rate_combos(ud);
- ghb_grey_combo_options (ud);
- ghb_check_dependency(ud, widget, NULL);
- audio_deps(ud);
prev_acodec = acodec_code;
if (asettings != NULL)
{
ghb_widget_to_setting(asettings, widget);
- ghb_settings_set_value(asettings, "AudioEncoderActual", ghb_settings_get_value(ud->settings, "AudioEncoderActual"));
+ audio_deps(ud, asettings, widget);
ghb_audio_list_refresh_selected(ud);
+ ghb_live_reset(ud);
}
- ghb_live_reset(ud);
float low, high, gran, defval;
int dir;
@@ -792,28 +1041,24 @@ audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
GValue *asettings;
g_debug("audio_track_changed_cb ()");
+ ghb_widget_to_setting(ud->settings, widget);
if (block_updates)
{
- ghb_check_dependency(ud, widget, NULL);
- ghb_grey_combo_options (ud);
return;
}
- ghb_adjust_audio_rate_combos(ud);
- ghb_check_dependency(ud, widget, NULL);
- audio_deps(ud);
- ghb_grey_combo_options(ud);
- asettings = get_selected_asettings(ud);
+ asettings = audio_get_selected_settings(ud, NULL);
if (asettings != NULL)
{
const gchar *track;
ghb_widget_to_setting(asettings, widget);
+ audio_deps(ud, asettings, widget);
ghb_audio_list_refresh_selected(ud);
track = ghb_settings_combo_option(asettings, "AudioTrack");
ghb_settings_set_string(asettings, "AudioTrackDescription", track);
+ ghb_live_reset(ud);
}
- ghb_live_reset(ud);
}
G_MODULE_EXPORT void
@@ -821,22 +1066,20 @@ audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
GValue *asettings;
- g_debug("audio_mix_changed_cb ()");
+ ghb_widget_to_setting(ud->settings, widget);
if (block_updates)
{
- ghb_check_dependency(ud, widget, NULL);
return;
}
- ghb_adjust_audio_rate_combos(ud);
- ghb_check_dependency(ud, widget, NULL);
- asettings = get_selected_asettings(ud);
+ asettings = audio_get_selected_settings(ud, NULL);
if (asettings != NULL)
{
ghb_widget_to_setting(asettings, widget);
+ audio_deps(ud, asettings, widget);
ghb_audio_list_refresh_selected(ud);
+ ghb_live_reset(ud);
}
- ghb_live_reset(ud);
}
G_MODULE_EXPORT void
@@ -844,39 +1087,34 @@ audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
GValue *asettings;
- g_debug("audio_widget_changed_cb ()");
+ ghb_widget_to_setting(ud->settings, widget);
if (block_updates)
{
- ghb_check_dependency(ud, widget, NULL);
return;
}
- ghb_adjust_audio_rate_combos(ud);
- asettings = get_selected_asettings(ud);
+ asettings = audio_get_selected_settings(ud, NULL);
if (asettings != NULL)
{
ghb_widget_to_setting(asettings, widget);
+ audio_deps(ud, asettings, widget);
ghb_audio_list_refresh_selected(ud);
+ ghb_live_reset(ud);
}
- ghb_live_reset(ud);
}
G_MODULE_EXPORT void
-global_audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+audio_quality_radio_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("global_audio_widget_changed_cb ()");
- if (block_updates)
- {
- ghb_check_dependency(ud, widget, NULL);
- return;
- }
-
ghb_check_dependency(ud, widget, NULL);
+ audio_widget_changed_cb(widget, ud);
+}
+
+G_MODULE_EXPORT void
+audio_passthru_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
ghb_widget_to_setting(ud->settings, widget);
- ghb_adjust_audio_rate_combos(ud);
- ghb_grey_combo_options (ud);
- ghb_audio_list_refresh_selected(ud);
- ghb_live_reset(ud);
+ ghb_clear_presets_selection(ud);
}
G_MODULE_EXPORT gchar*
@@ -923,7 +1161,7 @@ quality_widget_changed_cb(GtkWidget *widget, gdouble quality, signal_user_data_t
ghb_check_dependency(ud, widget, NULL);
float low, high, gran;
int dir;
- int codec = ghb_settings_combo_int(ud->settings, "AudioEncoderActual");
+ int codec = ghb_settings_combo_int(ud->settings, "AudioEncoder");
hb_audio_quality_get_limits(codec, &low, &high, &gran, &dir);
if (dir)
{
@@ -936,7 +1174,7 @@ quality_widget_changed_cb(GtkWidget *widget, gdouble quality, signal_user_data_t
if (block_updates) return;
- asettings = get_selected_asettings(ud);
+ asettings = audio_get_selected_settings(ud, NULL);
if (asettings != NULL)
{
ghb_settings_set_double(asettings, "AudioTrackQuality", quality);
@@ -952,8 +1190,11 @@ drc_widget_changed_cb(GtkWidget *widget, gdouble drc, signal_user_data_t *ud)
g_debug("drc_widget_changed_cb ()");
- ghb_check_dependency(ud, widget, NULL);
- if (block_updates) return;
+ ghb_widget_to_setting(ud->settings, widget);
+ if (block_updates)
+ {
+ return;
+ }
char *s_drc;
if (drc < 0.99)
@@ -963,13 +1204,14 @@ drc_widget_changed_cb(GtkWidget *widget, gdouble drc, signal_user_data_t *ud)
ghb_ui_update( ud, "AudioTrackDRCValue", ghb_string_value(s_drc));
g_free(s_drc);
- asettings = get_selected_asettings(ud);
+ asettings = audio_get_selected_settings(ud, NULL);
if (asettings != NULL)
{
ghb_widget_to_setting(asettings, widget);
+ audio_deps(ud, asettings, widget);
ghb_audio_list_refresh_selected(ud);
+ ghb_live_reset(ud);
}
- ghb_live_reset(ud);
}
G_MODULE_EXPORT gchar*
@@ -987,9 +1229,11 @@ gain_widget_changed_cb(GtkWidget *widget, gdouble gain, signal_user_data_t *ud)
g_debug("gain_widget_changed_cb ()");
- ghb_check_dependency(ud, widget, NULL);
- if (block_updates) return;
- asettings = get_selected_asettings(ud);
+ ghb_widget_to_setting(ud->settings, widget);
+ if (block_updates)
+ {
+ return;
+ }
char *s_gain;
if ( gain >= 21.0 )
@@ -999,19 +1243,21 @@ gain_widget_changed_cb(GtkWidget *widget, gdouble gain, signal_user_data_t *ud)
ghb_ui_update( ud, "AudioTrackGainValue", ghb_string_value(s_gain));
g_free(s_gain);
+ asettings = audio_get_selected_settings(ud, NULL);
if (asettings != NULL)
{
ghb_widget_to_setting(asettings, widget);
+ audio_deps(ud, asettings, widget);
ghb_audio_list_refresh_selected(ud);
+ ghb_live_reset(ud);
}
- ghb_live_reset(ud);
}
void
ghb_clear_audio_list_settings(GValue *settings)
{
GValue *audio_list;
-
+
g_debug("clear_audio_list_settings ()");
audio_list = ghb_settings_get_value(settings, "audio_list");
if (audio_list == NULL)
@@ -1026,137 +1272,86 @@ ghb_clear_audio_list_settings(GValue *settings)
void
ghb_clear_audio_list_ui(GtkBuilder *builder)
{
- GtkTreeView *treeview;
- GtkListStore *store;
-
+ GtkTreeView *tv;
+ GtkTreeStore *ts;
+
g_debug("clear_audio_list_ui ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "audio_list"));
- store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
- gtk_list_store_clear (store);
+ tv = GTK_TREE_VIEW(GHB_WIDGET(builder, "audio_list"));
+ ts = GTK_TREE_STORE(gtk_tree_view_get_model(tv));
+ gtk_tree_store_clear(ts);
}
static void
-ghb_add_audio_to_ui(GtkBuilder *builder, const GValue *settings)
-{
- GtkTreeView *treeview;
- GtkTreeIter iter;
- GtkListStore *store;
- GtkTreeSelection *selection;
- const gchar *track, *codec, *br = NULL, *sr, *mix;
- gchar *s_drc, *s_gain, *s_quality = NULL;
- gdouble drc;
- gdouble gain;
-
- g_debug("ghb_add_audio_to_ui ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "audio_list"));
- selection = gtk_tree_view_get_selection (treeview);
- store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-
- track = ghb_settings_combo_option(settings, "AudioTrack");
- codec = ghb_settings_combo_option(settings, "AudioEncoderActual");
- double quality = ghb_settings_get_double(settings, "AudioTrackQuality");
- if (ghb_settings_get_boolean(settings, "AudioTrackQualityEnable") &&
- quality != HB_INVALID_AUDIO_QUALITY)
- {
- int codec = ghb_settings_combo_int(settings, "AudioEncoderActual");
- s_quality = ghb_format_quality("Q/", codec, quality);
- }
- else
- {
- br = ghb_settings_combo_option(settings, "AudioBitrate");
- }
- sr = ghb_settings_combo_option(settings, "AudioSamplerate");
- mix = ghb_settings_combo_option(settings, "AudioMixdown");
- gain = ghb_settings_get_double(settings, "AudioTrackGain");
- s_gain = g_strdup_printf("%ddB", (int)gain);
+ghb_add_audio_to_ui(signal_user_data_t *ud, const GValue *asettings)
+{
+ GtkTreeView *tv;
+ GtkTreeIter ti;
+ GtkTreeModel *tm;
+ GtkTreeSelection *ts;
- drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
- if (drc < 1.0)
- s_drc = g_strdup(_("Off"));
- else
- s_drc = g_strdup_printf("%.1f", drc);
+ if (asettings == NULL)
+ return;
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- // These are displayed in list
- 0, track,
- 1, codec,
- 2, s_quality ? s_quality : br,
- 3, sr,
- 4, mix,
- 5, s_gain,
- 6, s_drc,
- -1);
- gtk_tree_selection_select_iter(selection, &iter);
- g_free(s_drc);
- g_free(s_gain);
- g_free(s_quality);
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
+ ts = gtk_tree_view_get_selection (tv);
+ tm = gtk_tree_view_get_model(tv);
+
+ gtk_tree_store_append(GTK_TREE_STORE(tm), &ti, NULL);
+ gtk_tree_selection_select_iter(ts, &ti);
+
+ audio_refresh_list_row_ui(tm, &ti, ud, asettings);
}
G_MODULE_EXPORT void
-audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
+audio_list_selection_changed_cb(GtkTreeSelection *ts, signal_user_data_t *ud)
{
- GtkTreeModel *store;
- GtkTreeIter iter;
- GtkWidget *widget;
-
- GtkTreePath *treepath;
- gint *indices;
- gint row;
+ GtkTreeModel *tm;
+ GtkTreeIter ti;
GValue *asettings = NULL;
+ gint row;
- const GValue *audio_list;
g_debug("audio_list_selection_changed_cb ()");
- if (gtk_tree_selection_get_selected(selection, &store, &iter))
+ if (gtk_tree_selection_get_selected(ts, &tm, &ti))
{
- //const gchar *actual_codec, *track, *codec, *bitrate, *sample_rate, *mix;
- //gdouble drc;
+ GtkTreeIter pti;
+
+ if (gtk_tree_model_iter_parent(tm, &pti, &ti))
+ {
+ GtkTreePath *path;
+ GtkTreeView *tv;
+
+ gtk_tree_selection_select_iter(ts, &pti);
+ path = gtk_tree_model_get_path(tm, &pti);
+ tv = gtk_tree_selection_get_tree_view(ts);
+ // Make the parent visible in scroll window if it is not.
+ gtk_tree_view_scroll_to_cell(tv, path, NULL, FALSE, 0, 0);
+ gtk_tree_path_free(path);
+ return;
+ }
+
+ GtkTreePath *tp;
+ gint *indices;
+ GValue *audio_list;
// Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
+ tp = gtk_tree_model_get_path (tm, &ti);
+ indices = gtk_tree_path_get_indices (tp);
row = indices[0];
- gtk_tree_path_free(treepath);
- // find audio settings
+ gtk_tree_path_free(tp);
+
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);
-
- block_updates = TRUE;
- ghb_ui_update(ud, "AudioTrack", ghb_settings_get_value(asettings, "AudioTrack"));
- ghb_ui_update(ud, "AudioEncoder", ghb_settings_get_value(asettings, "AudioEncoder"));
- ghb_settings_set_value(ud->settings, "AudioEncoderActual", ghb_settings_get_value(asettings, "AudioEncoderActual"));
- ghb_check_dependency(ud, NULL, "AudioEncoderActual");
- ghb_ui_update(ud, "AudioBitrate", ghb_settings_get_value(asettings, "AudioBitrate"));
- ghb_ui_update(ud, "AudioTrackName", ghb_settings_get_value(asettings, "AudioTrackName"));
- ghb_ui_update(ud, "AudioSamplerate", ghb_settings_get_value(asettings, "AudioSamplerate"));
- ghb_ui_update(ud, "AudioMixdown", ghb_settings_get_value(asettings, "AudioMixdown"));
- ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_settings_get_value(asettings, "AudioTrackDRCSlider"));
- ghb_ui_update(ud, "AudioTrackGain", ghb_settings_get_value(asettings, "AudioTrackGain"));
- ghb_ui_update(ud, "AudioTrackQuality", ghb_settings_get_value(asettings, "AudioTrackQuality"));
- ghb_ui_update(ud, "AudioTrackQualityEnable", ghb_settings_get_value(asettings, "AudioTrackQualityEnable"));
- block_updates = FALSE;
- widget = GHB_WIDGET (ud->builder, "audio_remove");
- gtk_widget_set_sensitive(widget, TRUE);
-
- ghb_adjust_audio_rate_combos(ud);
- }
- else
- {
- widget = GHB_WIDGET (ud->builder, "audio_remove");
- gtk_widget_set_sensitive(widget, FALSE);
+ if (row >= 0 && row < ghb_array_len(audio_list))
+ asettings = ghb_array_get_nth(audio_list, row);
}
- audio_deps(ud);
+ audio_update_dialog_widgets(ud, asettings);
}
-static gboolean
-ghb_add_audio_to_settings(GValue *settings, GValue *asettings)
+static void
+audio_add_to_settings(GValue *settings, GValue *asettings)
{
GValue *audio_list;
const gchar * track;
- int count;
audio_list = ghb_settings_get_value(settings, "audio_list");
if (audio_list == NULL)
@@ -1164,14 +1359,6 @@ ghb_add_audio_to_settings(GValue *settings, GValue *asettings)
audio_list = ghb_array_value_new(8);
ghb_settings_set_value(settings, "audio_list", audio_list);
}
- count = ghb_array_len(audio_list);
- // Don't allow more than 99
- // This is a hard limit imposed by libhb/reader.c:GetFifoForId()
- if (count >= 99)
- {
- ghb_value_free(asettings);
- return FALSE;
- }
int title_no = ghb_settings_get_int(settings, "title_no");
int track_no = ghb_settings_get_int(asettings, "AudioTrack");
@@ -1184,92 +1371,175 @@ ghb_add_audio_to_settings(GValue *settings, GValue *asettings)
{
ghb_settings_set_string(asettings, "AudioTrackName", "");
}
- if (ghb_array_len(audio_list) >= 99)
- {
- ghb_value_free(asettings);
- return FALSE;
- }
ghb_array_append(audio_list, asettings);
- return TRUE;
}
G_MODULE_EXPORT void
audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
// Add the current audio settings to the list.
- GValue *asettings;
- GtkWidget *widget;
-
- g_debug("audio_add_clicked_cb ()");
- asettings = ghb_dict_value_new();
- widget = GHB_WIDGET(ud->builder, "AudioTrack");
- ghb_settings_take_value(asettings, "AudioTrack", ghb_widget_value(widget));
- widget = GHB_WIDGET(ud->builder, "AudioEncoder");
- ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
- ghb_settings_set_value(asettings, "AudioEncoderActual",
- ghb_settings_get_value(ud->settings, "AudioEncoderActual"));
- widget = GHB_WIDGET(ud->builder, "AudioTrackQualityEnable");
- ghb_settings_take_value(asettings, "AudioTrackQualityEnable", ghb_widget_value(widget));
- widget = GHB_WIDGET(ud->builder, "AudioTrackQuality");
- ghb_settings_take_value(asettings, "AudioTrackQuality", ghb_widget_value(widget));
- widget = GHB_WIDGET(ud->builder, "AudioBitrate");
- ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
- widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
- ghb_settings_take_value(asettings, "AudioSamplerate", ghb_widget_value(widget));
- widget = GHB_WIDGET(ud->builder, "AudioMixdown");
- ghb_settings_take_value(asettings, "AudioMixdown", ghb_widget_value(widget));
- widget = GHB_WIDGET(ud->builder, "AudioTrackGain");
- ghb_settings_take_value(asettings, "AudioTrackGain", ghb_widget_value(widget));
- widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
- ghb_settings_take_value(asettings, "AudioTrackDRCSlider", ghb_widget_value(widget));
+ GValue *asettings, *backup;
- if (!ghb_add_audio_to_settings(ud->settings, asettings))
- return;
+ // Back up settings in case we need to revert.
+ backup = ghb_value_dup(
+ ghb_settings_get_value(ud->settings, "audio_list"));
+
+ int titleindex = ghb_settings_combo_int(ud->settings, "title");
+ hb_title_t *title = ghb_get_title_info(titleindex);
+ GValue *pref_audio = ghb_settings_get_value(ud->settings, "AudioList");
- ghb_add_audio_to_ui(ud->builder, asettings);
- check_list_full(ud);
+ asettings = audio_select_and_add_track(title, ud->settings, pref_audio,
+ "und", 0, 0);
+ ghb_add_audio_to_ui(ud, asettings);
+
+ if (asettings != NULL)
+ {
+ // Pop up the edit dialog
+ GtkResponseType response;
+ GtkWidget *dialog = GHB_WIDGET(ud->builder, "audio_dialog");
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_hide(dialog);
+ if (response != GTK_RESPONSE_OK)
+ {
+ ghb_settings_take_value(ud->settings, "audio_list", backup);
+ asettings = audio_get_selected_settings(ud, NULL);
+ if (asettings != NULL)
+ {
+ audio_update_dialog_widgets(ud, asettings);
+ }
+ audio_refresh_list_ui(ud);
+ }
+ else
+ {
+ ghb_value_free(backup);
+ }
+ }
}
G_MODULE_EXPORT void
-audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
+audio_add_all_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
- GtkTreeView *treeview;
- GtkTreePath *treepath;
- GtkTreeSelection *selection;
- GtkTreeModel *store;
- GtkTreeIter iter, nextIter;
- gint *indices;
+ // Add the current audio settings to the list.
+
+ ghb_clear_audio_list_settings(ud->settings);
+ ghb_clear_audio_list_ui(ud->builder);
+
+ int titleindex = ghb_settings_combo_int(ud->settings, "title");
+ hb_title_t *title = ghb_get_title_info(titleindex);
+ GValue *pref_audio = ghb_settings_get_value(ud->settings, "AudioList");
+
+ int pref_count = ghb_array_len(pref_audio);
+
+ int ii;
+ for (ii = 0; ii < pref_count; ii++)
+ {
+ GValue *asettings;
+ int track = 0;
+
+ do
+ {
+
+ asettings = audio_select_and_add_track(title, ud->settings,
+ pref_audio, "und", ii,
+ track);
+ ghb_add_audio_to_ui(ud, asettings);
+ if (asettings != NULL)
+ {
+ track = ghb_settings_combo_int(asettings, "AudioTrack") + 1;
+ }
+ } while (asettings != NULL);
+ }
+}
+
+G_MODULE_EXPORT void
+audio_edit_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
+{
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeModel *tm;
+ GtkTreeSelection *ts;
+ GtkTreeIter ti;
+
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ tm = gtk_tree_view_get_model(tv);
+ tp = gtk_tree_path_new_from_string (path);
+ if (gtk_tree_path_get_depth(tp) > 1) return;
+ if (gtk_tree_model_get_iter(tm, &ti, tp))
+ {
+ GValue *asettings, *backup;
+
+ gtk_tree_selection_select_iter(ts, &ti);
+
+ // Back up settings in case we need to revert.
+ backup = ghb_value_dup(
+ ghb_settings_get_value(ud->settings, "audio_list"));
+
+ // Pop up the edit dialog
+ GtkResponseType response;
+ GtkWidget *dialog = GHB_WIDGET(ud->builder, "audio_dialog");
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_hide(dialog);
+ if (response != GTK_RESPONSE_OK)
+ {
+ ghb_settings_take_value(ud->settings, "audio_list", backup);
+ asettings = audio_get_selected_settings(ud, NULL);
+ if (asettings != NULL)
+ {
+ audio_update_dialog_widgets(ud, asettings);
+ }
+ audio_refresh_list_ui(ud);
+ }
+ else
+ {
+ ghb_value_free(backup);
+ }
+ }
+}
+
+G_MODULE_EXPORT void
+audio_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
+{
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeModel *tm;
+ GtkTreeSelection *ts;
+ GtkTreeIter ti, nextIter;
gint row;
+ gint *indices;
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))
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ tm = gtk_tree_view_get_model(tv);
+ tp = gtk_tree_path_new_from_string (path);
+ if (gtk_tree_path_get_depth(tp) > 1) return;
+ if (gtk_tree_model_get_iter(tm, &ti, tp))
{
- nextIter = iter;
- if (!gtk_tree_model_iter_next(store, &nextIter))
+ nextIter = ti;
+ if (!gtk_tree_model_iter_next(tm, &nextIter))
{
- nextIter = iter;
- if (gtk_tree_model_get_iter_first(store, &nextIter))
+ nextIter = ti;
+ if (gtk_tree_model_get_iter_first(tm, &nextIter))
{
- gtk_tree_selection_select_iter (selection, &nextIter);
+ gtk_tree_selection_select_iter(ts, &nextIter);
}
}
else
{
- gtk_tree_selection_select_iter (selection, &nextIter);
+ gtk_tree_selection_select_iter(ts, &nextIter);
}
- // Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
- row = indices[0];
- gtk_tree_path_free(treepath);
- if (row < 0) return;
audio_list = ghb_settings_get_value(ud->settings, "audio_list");
- if (row >= ghb_array_len(audio_list))
+
+ // Get the row number
+ indices = gtk_tree_path_get_indices (tp);
+ row = indices[0];
+ if (row < 0 || row >= ghb_array_len(audio_list))
+ {
+ gtk_tree_path_free(tp);
return;
+ }
// Update our settings list before removing the row from the
// treeview. Removing from the treeview sometimes provokes an
@@ -1280,11 +1550,19 @@ audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_array_remove(audio_list, row);
// Remove the selected item
- gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
- // remove from audio settings list
- widget = GHB_WIDGET (ud->builder, "audio_add");
- gtk_widget_set_sensitive(widget, TRUE);
+ gtk_tree_store_remove(GTK_TREE_STORE(tm), &ti);
+
+ ghb_live_reset(ud);
}
+ gtk_tree_path_free(tp);
+}
+
+G_MODULE_EXPORT void
+audio_reset_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ int titleindex = ghb_settings_combo_int(ud->settings, "title");
+ ghb_set_pref_audio_settings(titleindex, ud->settings);
+ ghb_set_pref_audio_from_settings(ud, ud->settings);
}
void
@@ -1293,10 +1571,10 @@ ghb_set_audio(signal_user_data_t *ud, GValue *settings)
gint acodec_code;
GValue *alist;
- GValue *track, *audio, *acodec, *acodec_actual, *bitrate, *rate,
+ GValue *track, *audio, *acodec, *bitrate, *rate,
*mix, *drc, *gain, *quality, *enable_quality;
gint count, ii;
-
+
g_debug("set_audio");
// Clear the audio list
ghb_clear_audio_list_settings(ud->settings);
@@ -1309,7 +1587,6 @@ ghb_set_audio(signal_user_data_t *ud, GValue *settings)
audio = ghb_array_get_nth(alist, ii);
track = ghb_settings_get_value(audio, "AudioTrack");
acodec = ghb_settings_get_value(audio, "AudioEncoder");
- acodec_actual = ghb_settings_get_value(audio, "AudioEncoderActual");
enable_quality = ghb_settings_get_value(audio, "AudioTrackQualityEnable");
quality = ghb_settings_get_value(audio, "AudioTrackQuality");
bitrate = ghb_settings_get_value(audio, "AudioBitrate");
@@ -1324,7 +1601,6 @@ ghb_set_audio(signal_user_data_t *ud, GValue *settings)
GValue *asettings = ghb_dict_value_new();
ghb_settings_set_value(asettings, "AudioTrack", track);
ghb_settings_set_value(asettings, "AudioEncoder", acodec);
- ghb_settings_set_value(asettings, "AudioEncoderActual", acodec_actual);
ghb_settings_set_value(asettings, "AudioTrackQualityEnable", enable_quality);
ghb_settings_set_value(asettings, "AudioTrackQuality", quality);
@@ -1335,12 +1611,884 @@ ghb_set_audio(signal_user_data_t *ud, GValue *settings)
ghb_settings_set_value(asettings, "AudioTrackGain", gain);
ghb_settings_set_value(asettings, "AudioTrackDRCSlider", drc);
- ghb_add_audio_to_settings(ud->settings, asettings);
-
- ghb_add_audio_to_ui(ud->builder, asettings);
+ audio_add_to_settings(ud->settings, asettings);
+ ghb_add_audio_to_ui(ud, asettings);
ghb_adjust_audio_rate_combos(ud);
}
}
- check_list_full(ud);
}
+static GtkWidget *find_widget(GtkWidget *widget, gchar *name)
+{
+ const char *wname;
+ GtkWidget *result = NULL;
+
+ if (widget == NULL || name == NULL)
+ return NULL;
+
+ wname = gtk_widget_get_name(widget);
+ if (wname != NULL && !strncmp(wname, name, 80))
+ {
+ return widget;
+ }
+ if (GTK_IS_CONTAINER(widget))
+ {
+ GList *list, *link;
+ link = list = gtk_container_get_children(GTK_CONTAINER(widget));
+ while (link)
+ {
+ result = find_widget(GTK_WIDGET(link->data), name);
+ if (result != NULL)
+ break;
+ link = link->next;
+ }
+ g_list_free(list);
+ }
+ return result;
+}
+
+static void audio_def_update_widgets(GtkWidget *row, GValue *adict)
+{
+ GHashTableIter ti;
+ gchar *key;
+ GValue *gval;
+ GtkWidget *widget;
+
+ ghb_dict_iter_init(&ti, adict);
+
+ block_updates = TRUE;
+ while (g_hash_table_iter_next(&ti, (gpointer*)&key, (gpointer*)&gval))
+ {
+ widget = find_widget(row, key);
+ if (widget != NULL)
+ {
+ ghb_update_widget(widget, gval);
+ }
+ }
+ block_updates = FALSE;
+}
+
+GtkListBoxRow * ghb_audio_settings_get_row(GtkWidget *widget)
+{
+ while (widget != NULL && G_OBJECT_TYPE(widget) != GTK_TYPE_LIST_BOX_ROW)
+ {
+ widget = gtk_widget_get_parent(widget);
+ }
+ return GTK_LIST_BOX_ROW(widget);
+}
+
+static void audio_def_settings_bitrate_show(GtkWidget *widget, gboolean show)
+{
+ GtkWidget *bitrate_widget;
+ GtkWidget *quality_widget;
+
+ bitrate_widget = find_widget(widget, "AudioBitrate");
+ quality_widget = find_widget(widget, "AudioTrackQualityBox");
+
+ if (show)
+ {
+ gtk_widget_hide(quality_widget);
+ gtk_widget_show(bitrate_widget);
+ }
+ else
+ {
+ gtk_widget_hide(bitrate_widget);
+ gtk_widget_show(quality_widget);
+ }
+}
+
+static void audio_def_settings_quality_set_sensitive(GtkWidget *w, gboolean s)
+{
+ GtkWidget *bitrate_widget;
+ GtkWidget *quality_widget;
+
+ bitrate_widget = find_widget(w, "AudioTrackBitrateEnable");
+ quality_widget = find_widget(w, "AudioTrackQualityEnable");
+ if (!s)
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bitrate_widget), TRUE);
+ }
+ gtk_widget_set_sensitive(GTK_WIDGET(quality_widget), s);
+}
+
+static void audio_def_settings_show(GtkWidget *widget, gboolean show)
+{
+ GtkWidget *settings_box;
+ GtkWidget *add_button;
+
+ settings_box = find_widget(widget, "settings_box");
+ add_button = find_widget(widget, "add_button");
+
+ if (show)
+ {
+ gtk_widget_hide(add_button);
+ gtk_widget_show(settings_box);
+ }
+ else
+ {
+ gtk_widget_hide(settings_box);
+ gtk_widget_show(add_button);
+ }
+}
+
+static void
+audio_def_settings_init_row(GValue *adict, GtkWidget *row)
+{
+ GtkWidget *widget;
+
+ widget = find_widget(row, "AudioEncoder");
+ ghb_widget_to_setting(adict, widget);
+ widget = find_widget(row, "AudioBitrate");
+ ghb_widget_to_setting(adict, widget);
+ widget = find_widget(row, "AudioMixdown");
+ ghb_widget_to_setting(adict, widget);
+ widget = find_widget(row, "AudioSamplerate");
+ ghb_widget_to_setting(adict, widget);
+ widget = find_widget(row, "AudioTrackGain");
+ ghb_widget_to_setting(adict, widget);
+ widget = find_widget(row, "AudioTrackDRCSlider");
+ ghb_widget_to_setting(adict, widget);
+ widget = find_widget(row, "AudioTrackQuality");
+ ghb_widget_to_setting(adict, widget);
+ widget = find_widget(row, "AudioTrackQualityEnable");
+ ghb_widget_to_setting(adict, widget);
+}
+
+G_MODULE_EXPORT void
+audio_def_setting_add_cb(GtkWidget *w, signal_user_data_t *ud);
+G_MODULE_EXPORT void
+audio_def_setting_remove_cb(GtkWidget *w, signal_user_data_t *ud);
+G_MODULE_EXPORT void
+audio_def_encode_setting_changed_cb(GtkWidget *w, signal_user_data_t *ud);
+G_MODULE_EXPORT void
+audio_def_drc_changed_cb(GtkWidget *w, gdouble drc, signal_user_data_t *ud);
+G_MODULE_EXPORT void
+audio_def_gain_changed_cb(GtkWidget *w, gdouble gain, signal_user_data_t *ud);
+G_MODULE_EXPORT void
+audio_def_quality_changed_cb(GtkWidget *w, gdouble quality, signal_user_data_t *ud);
+G_MODULE_EXPORT void
+audio_def_quality_enable_changed_cb(GtkWidget *w, signal_user_data_t *ud);
+
+GtkWidget * ghb_create_audio_settings_row(signal_user_data_t *ud)
+{
+ GtkBox *box, *box2, *box3;
+ GtkComboBox *combo;
+ GtkScaleButton *scale;
+ GtkLabel *label;
+ GtkRadioButton *radio;
+ GtkButton *button;
+ GtkImage *image;
+
+ box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
+
+ // Add Button
+ button = GTK_BUTTON(gtk_button_new_with_label("Add"));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(button),
+ "Add an audio encoder.\n"
+ "Each selected source track will be encoded with all selected encoders.");
+ gtk_widget_set_valign(GTK_WIDGET(button), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(button), "add_button");
+ gtk_widget_hide(GTK_WIDGET(button));
+ g_signal_connect(button, "clicked", (GCallback)audio_def_setting_add_cb, ud);
+ gtk_box_pack_start(box, GTK_WIDGET(button), FALSE, FALSE, 0);
+
+ // Hidden widgets box
+ box2 = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
+ gtk_widget_set_name(GTK_WIDGET(box2), "settings_box");
+
+ // Audio Encoder ComboBox
+ combo = GTK_COMBO_BOX(gtk_combo_box_new());
+ ghb_init_combo_box(combo);
+ ghb_audio_encoder_opts_set(combo);
+ // Init to first audio encoder
+ const hb_encoder_t *aud_enc = hb_audio_encoder_get_next(NULL);
+ ghb_update_widget(GTK_WIDGET(combo), ghb_int64_value(aud_enc->codec));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(combo),
+ "Set the audio codec to encode this track with.");
+ gtk_widget_set_valign(GTK_WIDGET(combo), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(combo), "AudioEncoder");
+ gtk_widget_show(GTK_WIDGET(combo));
+ g_signal_connect(combo, "changed", (GCallback)audio_def_encode_setting_changed_cb, ud);
+ gtk_box_pack_start(box2, GTK_WIDGET(combo), FALSE, FALSE, 0);
+
+ box3 = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
+ gtk_widget_set_name(GTK_WIDGET(box3), "br_q_box");
+ gtk_widget_show(GTK_WIDGET(box3));
+
+ // Bitrate vs Quality RadioButton
+ GtkBox *vbox;
+ vbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0));
+ radio = GTK_RADIO_BUTTON(gtk_radio_button_new_with_label(NULL, "Bitrate"));
+ gtk_widget_set_name(GTK_WIDGET(radio), "AudioTrackBitrateEnable");
+ gtk_widget_show(GTK_WIDGET(radio));
+ gtk_box_pack_start(vbox, GTK_WIDGET(radio), FALSE, FALSE, 0);
+ radio = GTK_RADIO_BUTTON(
+ gtk_radio_button_new_with_label_from_widget(radio, "Quality"));
+ gtk_widget_set_name(GTK_WIDGET(radio), "AudioTrackQualityEnable");
+ g_signal_connect(radio, "toggled", (GCallback)audio_def_quality_enable_changed_cb, ud);
+ gtk_widget_show(GTK_WIDGET(radio));
+ gtk_box_pack_start(vbox, GTK_WIDGET(radio), FALSE, FALSE, 0);
+ gtk_widget_show(GTK_WIDGET(vbox));
+ gtk_box_pack_start(box3, GTK_WIDGET(vbox), FALSE, FALSE, 0);
+
+ // Audio Bitrate ComboBox
+ combo = GTK_COMBO_BOX(gtk_combo_box_new());
+ ghb_init_combo_box(combo);
+ ghb_audio_bitrate_opts_set(combo, FALSE);
+ ghb_update_widget(GTK_WIDGET(combo), ghb_int64_value(192));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(combo),
+ "Set the bitrate to encode this track with.");
+ gtk_widget_set_valign(GTK_WIDGET(combo), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(combo), "AudioBitrate");
+ gtk_widget_show(GTK_WIDGET(combo));
+ g_signal_connect(combo, "changed", (GCallback)audio_def_encode_setting_changed_cb, ud);
+ gtk_box_pack_start(box3, GTK_WIDGET(combo), FALSE, FALSE, 0);
+
+ GtkBox *qbox;
+ qbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
+ gtk_widget_set_name(GTK_WIDGET(qbox), "AudioTrackQualityBox");
+
+ // Audio Quality ScaleButton
+ const gchar *quality_icons[] = {
+ "weather-storm",
+ "weather-clear",
+ "weather-storm",
+ "weather-showers-scattered",
+ "weather-showers",
+ "weather-overcast",
+ "weather-few-clouds",
+ "weather-clear",
+ NULL
+ };
+ scale = GTK_SCALE_BUTTON(gtk_scale_button_new(GTK_ICON_SIZE_BUTTON,
+ 0, 10, 0.1, quality_icons));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(scale),
+ "<b>Audio Quality:</b>\n"
+ "For encoders that support it, adjust the quality of the output.");
+
+ gtk_widget_set_valign(GTK_WIDGET(scale), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(scale), "AudioTrackQuality");
+ gtk_widget_show(GTK_WIDGET(scale));
+ g_signal_connect(scale, "value-changed", (GCallback)audio_def_quality_changed_cb, ud);
+ gtk_box_pack_start(qbox, GTK_WIDGET(scale), FALSE, FALSE, 0);
+
+ // Audio Quality Label
+ label = GTK_LABEL(gtk_label_new("0.00"));
+ gtk_label_set_width_chars(label, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_widget_set_name(GTK_WIDGET(label), "AudioTrackQualityValue");
+ gtk_widget_show(GTK_WIDGET(label));
+ gtk_box_pack_start(qbox, GTK_WIDGET(label), FALSE, FALSE, 0);
+ gtk_widget_hide(GTK_WIDGET(qbox));
+ gtk_box_pack_start(box3, GTK_WIDGET(qbox), FALSE, FALSE, 0);
+ gtk_box_pack_start(box2, GTK_WIDGET(box3), FALSE, FALSE, 0);
+
+ // Audio Mix ComboBox
+ combo = GTK_COMBO_BOX(gtk_combo_box_new());
+ ghb_init_combo_box(combo);
+ ghb_mix_opts_set(combo);
+ ghb_update_widget(GTK_WIDGET(combo), ghb_int64_value(HB_AMIXDOWN_5POINT1));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(combo),
+ "Set the mixdown of the output audio track.");
+ gtk_widget_set_valign(GTK_WIDGET(combo), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(combo), "AudioMixdown");
+ gtk_widget_show(GTK_WIDGET(combo));
+ g_signal_connect(combo, "changed", (GCallback)audio_def_encode_setting_changed_cb, ud);
+ gtk_box_pack_start(box2, GTK_WIDGET(combo), FALSE, FALSE, 0);
+
+ // Audio Sample Rate ComboBox
+ combo = GTK_COMBO_BOX(gtk_combo_box_new());
+ ghb_init_combo_box(combo);
+ ghb_audio_samplerate_opts_set(combo);
+ ghb_update_widget(GTK_WIDGET(combo), ghb_int64_value(0));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(combo),
+ "Set the sample rate of the output audio track.");
+ gtk_widget_set_valign(GTK_WIDGET(combo), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(combo), "AudioSamplerate");
+ gtk_widget_show(GTK_WIDGET(combo));
+ g_signal_connect(combo, "changed", (GCallback)audio_def_encode_setting_changed_cb, ud);
+ gtk_box_pack_start(box2, GTK_WIDGET(combo), FALSE, FALSE, 0);
+
+ box3 = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
+ gtk_widget_set_name(GTK_WIDGET(box3), "gain_box");
+ gtk_widget_show(GTK_WIDGET(box3));
+
+ // Audio Gain ScaleButton
+ const gchar *gain_icons[] = {
+ "audio-volume-muted",
+ "audio-volume-high",
+ "audio-volume-low",
+ "audio-volume-medium",
+ NULL
+ };
+ scale = GTK_SCALE_BUTTON(gtk_scale_button_new(GTK_ICON_SIZE_BUTTON,
+ -20, 21, 1, gain_icons));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(scale),
+ "<b>Audio Gain:</b>\n"
+ "Adjust the amplification or attenuation of the output audio track.");
+
+ gtk_widget_set_valign(GTK_WIDGET(scale), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(scale), "AudioTrackGain");
+ gtk_widget_show(GTK_WIDGET(scale));
+ g_signal_connect(scale, "value-changed", (GCallback)audio_def_gain_changed_cb, ud);
+ gtk_box_pack_start(box3, GTK_WIDGET(scale), FALSE, FALSE, 0);
+
+ // Audio Gain Label
+ label = GTK_LABEL(gtk_label_new("0dB"));
+ gtk_label_set_width_chars(label, 6);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_widget_set_name(GTK_WIDGET(label), "AudioTrackGainValue");
+ gtk_widget_show(GTK_WIDGET(label));
+ gtk_box_pack_start(box3, GTK_WIDGET(label), FALSE, FALSE, 0);
+ gtk_box_pack_start(box2, GTK_WIDGET(box3), FALSE, FALSE, 0);
+
+ box3 = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
+ gtk_widget_set_name(GTK_WIDGET(box3), "drc_box");
+ gtk_widget_show(GTK_WIDGET(box3));
+
+ // Audio DRC ComboBox
+ const gchar *drc_icons[] = {
+ "audio-input-microphone",
+ NULL
+ };
+ scale = GTK_SCALE_BUTTON(gtk_scale_button_new(GTK_ICON_SIZE_BUTTON,
+ 0.9, 4, 0.1, drc_icons));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(scale),
+ "<b>Dynamic Range Compression:</b>\n"
+ "Adjust the dynamic range of the output audio track.\n"
+ "For source audio that has a wide dynamic range,\n"
+ "very loud and very soft sequences, DRC allows you\n"
+ "to 'compress' the range by making loud sounds\n"
+ "softer and soft sounds louder.\n");
+
+ gtk_widget_set_valign(GTK_WIDGET(scale), GTK_ALIGN_CENTER);
+ gtk_widget_set_name(GTK_WIDGET(scale), "AudioTrackDRCSlider");
+ gtk_widget_show(GTK_WIDGET(scale));
+ g_signal_connect(scale, "value-changed", (GCallback)audio_def_drc_changed_cb, ud);
+ gtk_box_pack_start(box3, GTK_WIDGET(scale), FALSE, FALSE, 0);
+
+ // Audio DRC Label
+ label = GTK_LABEL(gtk_label_new("Off"));
+ gtk_label_set_width_chars(label, 4);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_widget_set_name(GTK_WIDGET(label), "AudioTrackDRCValue");
+ gtk_widget_show(GTK_WIDGET(label));
+ gtk_box_pack_start(box3, GTK_WIDGET(label), FALSE, FALSE, 0);
+ gtk_box_pack_start(box2, GTK_WIDGET(box3), FALSE, FALSE, 0);
+
+ // Remove button
+ image = GTK_IMAGE(gtk_image_new_from_icon_name("hb-remove",
+ GTK_ICON_SIZE_BUTTON));
+ button = GTK_BUTTON(gtk_button_new());
+ gtk_button_set_image(button, GTK_WIDGET(image));
+ gtk_widget_set_tooltip_markup(GTK_WIDGET(button),
+ "Remove this audio encoder");
+ gtk_button_set_relief(button, GTK_RELIEF_NONE);
+ gtk_widget_set_valign(GTK_WIDGET(button), GTK_ALIGN_CENTER);
+ gtk_widget_set_halign(GTK_WIDGET(button), GTK_ALIGN_END);
+ gtk_widget_set_name(GTK_WIDGET(button), "remove_button");
+ gtk_widget_show(GTK_WIDGET(button));
+ g_signal_connect(button, "clicked", (GCallback)audio_def_setting_remove_cb, ud);
+ gtk_box_pack_start(box2, GTK_WIDGET(button), TRUE, TRUE, 0);
+
+ gtk_widget_show(GTK_WIDGET(box2));
+ gtk_box_pack_start(box, GTK_WIDGET(box2), TRUE, TRUE, 0);
+
+ gtk_widget_show(GTK_WIDGET(box));
+
+ GtkWidget *widget;
+
+ int width;
+ widget = find_widget(GTK_WIDGET(box), "AudioEncoder");
+ gtk_widget_get_preferred_width(widget, NULL, &width);
+
+ widget = GHB_WIDGET(ud->builder, "audio_defaults_encoder_label");
+ gtk_widget_set_size_request(widget, width, -1);
+ widget = find_widget(GTK_WIDGET(box), "br_q_box");
+ gtk_widget_get_preferred_width(widget, NULL, &width);
+ widget = GHB_WIDGET(ud->builder, "audio_defaults_bitrate_label");
+ gtk_widget_set_size_request(widget, width, -1);
+ widget = find_widget(GTK_WIDGET(box), "AudioMixdown");
+ gtk_widget_get_preferred_width(widget, NULL, &width);
+ widget = GHB_WIDGET(ud->builder, "audio_defaults_mixdown_label");
+ gtk_widget_set_size_request(widget, width, -1);
+ widget = find_widget(GTK_WIDGET(box), "AudioSamplerate");
+ gtk_widget_get_preferred_width(widget, NULL, &width);
+ widget = GHB_WIDGET(ud->builder, "audio_defaults_samplerate_label");
+ gtk_widget_set_size_request(widget, width, -1);
+ widget = find_widget(GTK_WIDGET(box), "gain_box");
+ gtk_widget_get_preferred_width(widget, NULL, &width);
+ widget = GHB_WIDGET(ud->builder, "audio_defaults_gain_label");
+ gtk_widget_set_size_request(widget, width, -1);
+ widget = find_widget(GTK_WIDGET(box), "drc_box");
+ gtk_widget_get_preferred_width(widget, NULL, &width);
+ widget = GHB_WIDGET(ud->builder, "audio_defaults_drc_label");
+ gtk_widget_set_size_request(widget, width, -1);
+
+ return GTK_WIDGET(box);
+}
+
+static void
+audio_def_setting_update(signal_user_data_t *ud, GtkWidget *widget)
+{
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+ gint index = gtk_list_box_row_get_index(row);
+
+ GValue *alist = ghb_settings_get_value(ud->settings, "AudioList");
+ int count = ghb_array_len(alist);
+ if (!block_updates && index >= 0 && index < count)
+ {
+ GValue *adict = ghb_array_get_nth(alist, index);
+ ghb_widget_to_setting(adict, widget);
+ }
+}
+
+G_MODULE_EXPORT void
+audio_add_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GtkListBox *avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang"));
+ GtkListBox *selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang"));
+ GtkListBoxRow *row;
+ GtkWidget *label;
+
+ row = gtk_list_box_get_selected_row(avail);
+ if (row != NULL)
+ {
+ int idx;
+ const iso639_lang_t *lang;
+ GValue *glang, *alang_list;
+
+ // Remove from UI available language list box
+ label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ // Add to UI selected language list box
+ gtk_list_box_insert(selected, label, -1);
+
+ // Add to preset language list
+ idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx");
+ lang = ghb_iso639_lookup_by_int(idx);
+ glang = ghb_string_value_new(lang->iso639_2);
+ alang_list = ghb_settings_get_value(ud->settings, "AudioLanguageList");
+ ghb_array_append(alang_list, glang);
+ ghb_clear_presets_selection(ud);
+ }
+}
+
+G_MODULE_EXPORT void
+audio_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+
+ GtkListBox *avail, *selected;
+ GtkListBoxRow *row;
+ GtkWidget *label;
+
+ avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang"));
+ selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang"));
+ row = gtk_list_box_get_selected_row(selected);
+ if (row != NULL)
+ {
+ gint index;
+ GValue *alang_list;
+
+ index = gtk_list_box_row_get_index(row);
+
+ // Remove from UI selected language list box
+ label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx");
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ // Add to UI available language list box
+ gtk_list_box_insert(avail, label, idx);
+
+ // Remove from preset language list
+ alang_list = ghb_settings_get_value(ud->settings, "AudioLanguageList");
+ ghb_array_remove(alang_list, index);
+ ghb_clear_presets_selection(ud);
+ }
+}
+
+static void audio_quality_update_limits(GtkWidget *widget, int encoder)
+{
+ float low, high, gran, defval;
+ int dir;
+
+ hb_audio_quality_get_limits(encoder, &low, &high, &gran, &dir);
+ defval = hb_audio_quality_get_default(encoder);
+ GtkScaleButton *sb;
+ GtkAdjustment *adj;
+ sb = GTK_SCALE_BUTTON(widget);
+ adj = gtk_scale_button_get_adjustment(sb);
+ if (dir)
+ {
+ // Quality values are inverted
+ defval = high - defval + low;
+ }
+ gtk_adjustment_configure (adj, defval, low, high, gran, gran * 10, 0);
+}
+
+void audio_def_set_limits(signal_user_data_t *ud, GtkWidget *widget)
+{
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+ gint index = gtk_list_box_row_get_index(row);
+
+ GValue *alist = ghb_settings_get_value(ud->settings, "AudioList");
+ int count = ghb_array_len(alist);
+ if (index < 0 || index >= count)
+ return;
+
+ GValue *adict = ghb_array_get_nth(alist, index);
+
+ int encoder = ghb_settings_combo_int(adict, "AudioEncoder");
+ int fallback = ghb_settings_combo_int(ud->settings, "AudioEncoderFallback");
+ // Allow quality settings if the current encoder supports quality
+ // or if the encoder is auto-passthru and the fallback encoder
+ // supports quality.
+ gboolean sensitive =
+ hb_audio_quality_get_default(encoder) != HB_INVALID_AUDIO_QUALITY ||
+ (encoder == HB_ACODEC_AUTO_PASS &&
+ hb_audio_quality_get_default(fallback) != HB_INVALID_AUDIO_QUALITY);
+ audio_def_settings_quality_set_sensitive(GTK_WIDGET(row), sensitive);
+
+ int enc;
+ if (sensitive)
+ {
+ enc = encoder;
+ if (hb_audio_quality_get_default(encoder) == HB_INVALID_AUDIO_QUALITY)
+ {
+ enc = fallback;
+ }
+ audio_quality_update_limits(find_widget(GTK_WIDGET(row),
+ "AudioTrackQuality"), enc);
+ }
+
+ enc = encoder;
+ if (enc & HB_ACODEC_PASS_FLAG)
+ {
+ enc = ghb_select_fallback(ud->settings, enc);
+ }
+ int sr = ghb_settings_combo_int(adict, "AudioSamplerate");
+ if (sr == 0)
+ {
+ sr = 48000;
+ }
+ int mix = ghb_settings_combo_int(adict, "AudioMixdown");
+ int low, high;
+ hb_audio_bitrate_get_limits(enc, sr, mix, &low, &high);
+ GtkWidget *w = find_widget(GTK_WIDGET(row), "AudioBitrate");
+ ghb_audio_bitrate_opts_filter(GTK_COMBO_BOX(w), low, high);
+ w = find_widget(GTK_WIDGET(row), "AudioMixdown");
+ ghb_mix_opts_filter(GTK_COMBO_BOX(w), enc);
+}
+
+void audio_def_set_all_limits_cb(GtkWidget *widget, gpointer data)
+{
+ signal_user_data_t *ud = (signal_user_data_t*)data;
+ audio_def_set_limits(ud, widget);
+}
+
+void audio_def_set_all_limits(signal_user_data_t *ud)
+{
+ GtkListBox *list_box;
+
+ list_box = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_list_default"));
+ gtk_container_foreach(GTK_CONTAINER(list_box),
+ audio_def_set_all_limits_cb, (gpointer)ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ ghb_widget_to_setting(ud->settings, widget);
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_fallback_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ ghb_widget_to_setting(ud->settings, widget);
+ audio_def_set_all_limits(ud);
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_quality_enable_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ audio_def_setting_update(ud, widget);
+
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+ gint index = gtk_list_box_row_get_index(row);
+
+ GValue *alist = ghb_settings_get_value(ud->settings, "AudioList");
+ GValue *adict = ghb_array_get_nth(alist, index);
+
+ audio_def_settings_bitrate_show(GTK_WIDGET(row),
+ !ghb_settings_get_boolean(adict, "AudioTrackQualityEnable"));
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_quality_changed_cb(GtkWidget *widget, gdouble quality, signal_user_data_t *ud)
+{
+ audio_def_setting_update(ud, widget);
+
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+ GtkWidget *quality_label = find_widget(GTK_WIDGET(row),
+ "AudioTrackQualityValue");
+ gint index = gtk_list_box_row_get_index(row);
+
+ GValue *alist = ghb_settings_get_value(ud->settings, "AudioList");
+ GValue *adict = ghb_array_get_nth(alist, index);
+ int codec = ghb_settings_combo_int(adict, "AudioEncoder");
+
+ float low, high, gran;
+ int dir;
+ hb_audio_quality_get_limits(codec, &low, &high, &gran, &dir);
+ if (dir)
+ {
+ // Quality values are inverted
+ quality = high - quality + low;
+ }
+ char *s_quality = ghb_format_quality("", codec, quality);
+ ghb_update_widget(quality_label, ghb_string_value(s_quality));
+ g_free(s_quality);
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_gain_changed_cb(GtkWidget *widget, gdouble gain, signal_user_data_t *ud)
+{
+ audio_def_setting_update(ud, widget);
+
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+ GtkWidget *gain_label = find_widget(GTK_WIDGET(row), "AudioTrackGainValue");
+ char *s_gain;
+ if ( gain >= 21.0 )
+ s_gain = g_strdup_printf("*11*");
+ else
+ s_gain = g_strdup_printf("%ddB", (int)gain);
+ ghb_update_widget(gain_label, ghb_string_value(s_gain));
+ g_free(s_gain);
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_drc_changed_cb(GtkWidget *widget, gdouble drc, signal_user_data_t *ud)
+{
+ audio_def_setting_update(ud, widget);
+
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+ GtkWidget *drc_label = find_widget(GTK_WIDGET(row), "AudioTrackDRCValue");
+
+ char *s_drc;
+ if (drc < 0.99)
+ s_drc = g_strdup(_("Off"));
+ else
+ s_drc = g_strdup_printf("%.1f", drc);
+ ghb_update_widget(drc_label, ghb_string_value(s_drc));
+ g_free(s_drc);
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_setting_add_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+
+ GValue *adict;
+ GValue *alist = ghb_settings_get_value(ud->settings, "AudioList");
+ int count = ghb_array_len(alist);
+ if (count > 0)
+ {
+ // Use first item in list as defaults for new entries.
+ adict = ghb_value_dup(ghb_array_get_nth(alist, 0));
+ audio_def_update_widgets(GTK_WIDGET(row), adict);
+ }
+ else
+ {
+ // Use hard coded defaults
+ adict = ghb_dict_value_new();
+ audio_def_settings_init_row(adict, GTK_WIDGET(row));
+ }
+ ghb_array_append(alist, adict);
+ audio_def_settings_show(GTK_WIDGET(row), TRUE);
+
+ // Add new "Add" button
+ widget = ghb_create_audio_settings_row(ud);
+ audio_def_settings_show(widget, FALSE);
+ GtkListBox *list_box;
+ list_box = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_list_default"));
+ gtk_list_box_insert(list_box, widget, -1);
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_setting_remove_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GtkListBoxRow *row = ghb_audio_settings_get_row(widget);
+ gint index = gtk_list_box_row_get_index(row);
+
+ GValue *alist = ghb_settings_get_value(ud->settings, "AudioList");
+ int count = ghb_array_len(alist);
+ if (index < 0 || index >= count)
+ {
+ return;
+ }
+ gtk_widget_destroy(GTK_WIDGET(row));
+ ghb_array_remove(alist, index);
+ ghb_clear_presets_selection(ud);
+}
+
+G_MODULE_EXPORT void
+audio_def_encode_setting_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ audio_def_setting_update(ud, widget);
+ audio_def_set_limits(ud, widget);
+ ghb_clear_presets_selection(ud);
+}
+
+static void container_empty_cb(GtkWidget *widget, gpointer data)
+{
+ gtk_widget_destroy(widget);
+}
+
+void ghb_container_empty(GtkContainer *c)
+{
+ gtk_container_foreach(c, container_empty_cb, NULL);
+}
+
+GtkListBoxRow* ghb_find_lang_row(GtkListBox *list_box, int lang_idx)
+{
+ GList *list, *link;
+ GtkListBoxRow *result = NULL;
+
+ list = link = gtk_container_get_children(GTK_CONTAINER(list_box));
+ while (link != NULL)
+ {
+ GtkListBoxRow *row = (GtkListBoxRow*)link->data;
+ GtkWidget *label = gtk_bin_get_child(GTK_BIN(row));
+ int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx");
+ if (idx == lang_idx)
+ {
+ result = row;
+ break;
+ }
+ link = link->next;
+ }
+ g_list_free(list);
+
+ return result;
+}
+
+static void audio_def_lang_list_clear_cb(GtkWidget *row, gpointer data)
+{
+ GtkListBox *avail = (GtkListBox*)data;
+ GtkWidget *label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx");
+ gtk_list_box_insert(avail, label, idx);
+}
+
+static void audio_def_selected_lang_list_clear(signal_user_data_t *ud)
+{
+ GtkListBox *avail, *selected;
+ avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang"));
+ selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang"));
+ gtk_container_foreach(GTK_CONTAINER(selected),
+ audio_def_lang_list_clear_cb, (gpointer)avail);
+}
+
+static void audio_def_lang_list_init(signal_user_data_t *ud)
+{
+ GValue *lang_list;
+
+ // Clear selected languages.
+ audio_def_selected_lang_list_clear(ud);
+
+ lang_list = ghb_settings_get_value(ud->settings, "AudioLanguageList");
+ if (lang_list == NULL)
+ {
+ lang_list = ghb_array_value_new(8);
+ ghb_settings_set_value(ud->settings, "AudioLanguageList", lang_list);
+ }
+
+ int ii, count;
+ count = ghb_array_len(lang_list);
+ for (ii = 0; ii < count; )
+ {
+ GValue *lang_val = ghb_array_get_nth(lang_list, ii);
+ int idx = ghb_lookup_audio_lang(lang_val);
+
+ GtkListBox *avail, *selected;
+ GtkListBoxRow *row;
+ avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang"));
+ selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_selected_lang"));
+ row = ghb_find_lang_row(avail, idx);
+ if (row)
+ {
+ GtkWidget *label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ gtk_list_box_insert(selected, label, -1);
+ ii++;
+ }
+ else
+ {
+ // Error in list. Probably duplicate languages. Remove
+ // this item from the list.
+ ghb_array_remove(lang_list, ii);
+ count--;
+ }
+ }
+}
+
+void ghb_audio_def_settings_init(signal_user_data_t *ud)
+{
+ GtkListBox *list_box;
+ GValue *alist;
+ int count, ii;
+
+ audio_def_lang_list_init(ud);
+
+ // Init the AudioList settings if necessary
+ alist = ghb_settings_get_value(ud->settings, "AudioList");
+ if (alist == NULL)
+ {
+ alist = ghb_array_value_new(8);
+ ghb_settings_set_value(ud->settings, "AudioList", alist);
+ }
+
+ // Empty the current list
+ list_box = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_list_default"));
+ ghb_container_empty(GTK_CONTAINER(list_box));
+
+ GtkWidget *widget;
+ // Populate with new values
+ count = ghb_array_len(alist);
+ for (ii = 0; ii < count; ii++)
+ {
+ GValue *adict;
+
+ adict = ghb_array_get_nth(alist, ii);
+ widget = ghb_create_audio_settings_row(ud);
+ gtk_list_box_insert(list_box, widget, -1);
+ audio_def_update_widgets(widget, adict);
+ }
+ // Add row with "Add" button
+ widget = ghb_create_audio_settings_row(ud);
+ audio_def_settings_show(widget, FALSE);
+ gtk_list_box_insert(list_box, widget, -1);
+}
+
+void ghb_init_audio_defaults_ui(signal_user_data_t *ud)
+{
+ GtkListBox *list_box;
+
+ list_box = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "audio_avail_lang"));
+ ghb_init_lang_list_box(list_box);
+}
diff --git a/gtk/src/audiohandler.h b/gtk/src/audiohandler.h
index aaaddc89d..f1c7e8072 100644
--- a/gtk/src/audiohandler.h
+++ b/gtk/src/audiohandler.h
@@ -31,13 +31,16 @@ void ghb_adjust_audio_rate_combos(signal_user_data_t *ud);
void ghb_set_pref_audio_settings(gint titleindex, GValue *settings);
void ghb_set_pref_audio_from_settings(signal_user_data_t *ud, GValue *settings);
void ghb_set_audio(signal_user_data_t *ud, GValue *settings);
-const gchar* ghb_get_user_audio_lang(GValue *settings, gint titleindex, gint track);
+const gchar* ghb_get_user_audio_lang(GValue *settings, hb_title_t *title, gint track);
void ghb_audio_list_refresh_selected(signal_user_data_t *ud);
gint ghb_select_audio_codec(gint mux, hb_audio_config_t *aconfig, gint acodec, gint fallback_acodec, gint copy_mask);
-int ghb_select_fallback( GValue *settings, int mux, int acodec );
+int ghb_select_fallback( GValue *settings, int acodec );
int ghb_get_copy_mask(GValue *settings);
-void ghb_audio_list_refresh(signal_user_data_t *ud);
+void ghb_audio_list_refresh_all(signal_user_data_t *ud);
char * ghb_format_quality( const char *prefix, int codec, double quality );
-void ghb_show_hide_advanced_audio( signal_user_data_t *ud );
+void ghb_init_audio_defaults_ui(signal_user_data_t *ud);
+void ghb_audio_def_settings_init(signal_user_data_t *ud);
+GtkListBoxRow* ghb_find_lang_row(GtkListBox *list_box, int lang_idx);
+void ghb_audio_title_change(signal_user_data_t *ud, gboolean title_valid);
#endif // _AUDIOHANDLER_H_
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index bfb67bf6f..9d2253431 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -56,7 +56,6 @@
#define NOTIFY_CHECK_VERSION(x,y,z) 0
#endif
#else
-#define WINVER 0x0500
#include <winsock2.h>
#include <dbt.h>
#endif
@@ -889,7 +888,6 @@ start_scan(
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);
widget = GHB_WIDGET(ud->builder, "source_open");
gtk_widget_set_sensitive(widget, FALSE);
@@ -1258,7 +1256,7 @@ window_delete_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *u
}
static void
-update_acodec_combo(signal_user_data_t *ud)
+update_acodec(signal_user_data_t *ud)
{
ghb_adjust_audio_rate_combos(ud);
ghb_grey_combo_options (ud);
@@ -1299,12 +1297,12 @@ container_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget, NULL);
show_container_options(ud);
- update_acodec_combo(ud);
+ update_acodec(ud);
ghb_update_destination_extension(ud);
ghb_clear_presets_selection(ud);
ghb_live_reset(ud);
ghb_subtitle_prune(ud);
- ghb_subtitle_list_refresh_selected(ud);
+ ghb_subtitle_list_refresh_all(ud);
ghb_audio_list_refresh_selected(ud);
}
@@ -1641,10 +1639,10 @@ set_title_settings(GValue *settings, gint titleindex)
ghb_settings_set_string(settings, "MetaLongDescription",
title->metadata->long_description);
}
+ ghb_set_pref_subtitle_settings(title, settings);
}
update_chapter_list_settings(settings);
ghb_set_pref_audio_settings(titleindex, settings);
- ghb_set_pref_subtitle_settings(titleindex, settings);
set_destination_settings(settings);
char *dest_file, *dest_dir, *dest;
@@ -1705,8 +1703,10 @@ title_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_check_dependency(ud, widget, NULL);
update_chapter_list_settings(ud->settings);
update_chapter_list_from_settings(ud->builder, ud->settings);
+ ghb_audio_title_change(ud, title != NULL);
ghb_set_pref_audio_settings(titleindex, ud->settings);
ghb_set_pref_audio_from_settings(ud, ud->settings);
+ ghb_subtitle_title_change(ud, title != NULL);
ghb_set_pref_subtitle(titleindex, ud);
ghb_grey_combo_options (ud);
@@ -3424,8 +3424,7 @@ static void
browse_url(const gchar *url)
{
#if defined(_WIN32)
- HINSTANCE r;
- r = ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
+ ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
#else
gboolean result;
char *argv[] =
@@ -3895,7 +3894,6 @@ advanced_audio_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
ghb_check_dependency(ud, widget, NULL);
const gchar *name = ghb_get_setting_key(widget);
ghb_pref_save(ud->settings, name);
- ghb_show_hide_advanced_audio( ud );
}
G_MODULE_EXPORT void
diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui
index acbea7cf9..6fda5cea4 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -2802,795 +2802,608 @@ Colon separated list of x264 options.</property>
</packing>
</child>
<child>
- <object class="GtkBox" id="audio_tab">
- <property name="orientation">vertical</property>
+ <object class="GtkBox" id="audio_defaults">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="orientation">vertical</property>
+ <property name="margin_left">12</property>
+ <property name="margin_right">12</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="hexpand">True</property>
<child>
- <object class="GtkAlignment" id="alignment18">
+ <object class="GtkBox" id="audio_defaults_box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="top_padding">6</property>
- <property name="bottom_padding">2</property>
- <property name="left_padding">12</property>
- <property name="right_padding">2</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkBox" id="vbox17">
- <property name="orientation">vertical</property>
+ <object class="GtkBox" id="audio_defaults_box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">2</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkGrid" id="table16">
+ <object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="column_spacing">5</property>
<property name="row_spacing">2</property>
<child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment47">
+ <object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="yalign">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkButton" id="audio_add">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Add new audio settings to the list</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="audio_add_clicked_cb" swapped="no"/>
- <child>
- <object class="GtkImage" id="image4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="stock">gtk-add</property>
- </object>
- </child>
- </object>
- </child>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Selection Behavior:</property>
+ <property name="justify">right</property>
</object>
<packing>
- <property name="top_attach">0</property>
<property name="left_attach">0</property>
+ <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkAlignment" id="alignment37">
+ <object class="GtkComboBox" id="AudioTrackSelectionBehavior">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="yalign">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkButton" id="audio_remove">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Remove the selected audio settings</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="audio_remove_clicked_cb" swapped="no"/>
- <child>
- <object class="GtkImage" id="image8">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="stock">gtk-remove</property>
- </object>
- </child>
- </object>
- </child>
+ <signal name="changed" handler="audio_def_widget_changed_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">0</property>
<property name="left_attach">1</property>
+ <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
- <property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkExpander" id="AdvancedAudioExpander">
+ <object class="GtkGrid" id="grid3">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="column_spacing">5</property>
+ <property name="row_spacing">2</property>
+ <property name="halign">GTK_ALIGN_END</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
<child>
- <object class="GtkBox" id="vbox44">
- <property name="orientation">vertical</property>
+ <object class="GtkScrolledWindow" id="scrolledwindow10">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">5</property>
+ <property name="min_content_height">108</property>
<child>
- <object class="GtkGrid" id="AdvancedAudioPassTable">
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="column_spacing">5</property>
- <property name="row_spacing">2</property>
- <child>
- <object class="GtkBox" id="hbox40">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkLabel" id="labela3">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Auto Passthru:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="AudioAllowMP3Pass">
- <property name="label" translatable="yes">MP3</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Enable this if your playback device supports MP3.
-This permits MP3 passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="global_audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="AudioAllowAACPass">
- <property name="label" translatable="yes">AAC</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Enable this if your playback device supports AAC.
-This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="global_audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="AudioAllowAC3Pass">
- <property name="label" translatable="yes">AC-3</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Enable this if your playback device supports AC-3.
-This permits AC-3 passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="global_audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="AudioAllowDTSPass">
- <property name="label" translatable="yes">DTS</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Enable this if your playback device supports DTS.
-This permits DTS passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="global_audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="AudioAllowDTSHDPass">
- <property name="label" translatable="yes">DTS-HD</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Enable this if your playback device supports DTS-HD.
-This permits DTS-HD passthru to be selected when automatic passthru selection is enabled.</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="global_audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">5</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- <property name="width">4</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="labela4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="xalign">1</property>
- <property name="hexpand">True</property>
- <property name="label" translatable="yes">Passthru Fallback:</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">4</property>
- <property name="width">3</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="AudioEncoderFallback">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the audio codec to encode with when a suitable track can not be found for audio passthru.</property>
- <signal name="changed" handler="global_audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">7</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator" id="separator1">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
- <property name="width">8</property>
- <property name="height">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkGrid" id="table14">
+ <object class="GtkListBox" id="audio_avail_lang">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="column_spacing">5</property>
- <property name="row_spacing">2</property>
- <child>
- <object class="GtkLabel" id="audio_name_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Track Name:</property>
- <property name="use_markup">True</property>
- <property name="halign">center</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="AudioSamplerateLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Sample Rate:</property>
- <property name="use_markup">True</property>
- <property name="halign">center</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="AudioTrackGainLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Gain:</property>
- <property name="use_markup">True</property>
- <property name="halign">center</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="AudioTrackDRCSliderLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tooltip_markup">&lt;b&gt;Dynamic Range Compression:&lt;/b&gt; Adjust the dynamic range of the output audio track.
-
-For source audio that has a wide dynamic range (very loud and very soft sequences),
-DRC allows you to 'compress' the range by making loud sounds softer and soft sounds louder.</property>
- <property name="label" translatable="yes">DRC:</property>
- <property name="use_markup">True</property>
- <property name="halign">center</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="AudioTrackQualityEnable">
- <property name="label" translatable="yes">Quality:</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_markup">&lt;b&gt;Quality:&lt;/b&gt; For output codec's that support it, adjust the quality of the output.</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="AudioTrackName">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the audio track name.
-
-Players may use this in the audio selection list.</property>
- <property name="max_length">40</property>
- <property name="activates_default">True</property>
- <property name="width_chars">20</property>
- <property name="truncate_multiline">True</property>
- <property name="primary_icon_activatable">False</property>
- <property name="secondary_icon_activatable">False</property>
- <signal name="changed" handler="audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="AudioSamplerate">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the sample rate of the output audio track.</property>
- <signal name="changed" handler="audio_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox34">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <object class="GtkScaleButton" id="AudioTrackGain">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_markup">&lt;b&gt;Audio Gain:&lt;/b&gt; Adjust the amplification or attenuation of the output audio track.</property>
- <property name="orientation">vertical</property>
- <property name="adjustment">adjustment35</property>
- <property name="icons">audio-volume-muted
-audio-volume-high
-audio-volume-low
-audio-volume-medium</property>
- <signal name="value-changed" handler="gain_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="AudioTrackGainValue">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">0dB</property>
- <property name="use_markup">True</property>
- <property name="width_chars">6</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox33">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <object class="GtkScaleButton" id="AudioTrackDRCSlider">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_markup">&lt;b&gt;Dynamic Range Compression:&lt;/b&gt; Adjust the dynamic range of the output audio track.
-
-For source audio that has a wide dynamic range (very loud and very soft sequences),
-DRC allows you to 'compress' the range by making loud sounds softer and soft sounds louder.</property>
- <property name="orientation">vertical</property>
- <property name="adjustment">adjustment28</property>
- <property name="icons">audio-input-microphone</property>
- <signal name="value-changed" handler="drc_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="AudioTrackDRCValue">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Off</property>
- <property name="use_markup">True</property>
- <property name="width_chars">4</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="hbox32">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <object class="GtkScaleButton" id="AudioTrackQuality">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="receives_default">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_markup">&lt;b&gt;Quality:&lt;/b&gt; For output codec's that support it, adjust the quality of the output.</property>
- <property name="orientation">vertical</property>
- <property name="adjustment">audio_quality_adj</property>
- <property name="icons">weather-storm
-weather-clear
-weather-storm
-weather-showers-scattered
-weather-showers
-weather-overcast
-weather-few-clouds
-weather-clear</property>
- <signal name="value-changed" handler="quality_widget_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="AudioTrackQualityValue">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">00.0</property>
- <property name="use_markup">True</property>
- <property name="width_chars">4</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="filler_label0">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="left_attach">5</property>
- <property name="width">3</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="filler_label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="top_attach">0</property>
- <property name="left_attach">5</property>
- <property name="width">3</property>
- <property name="height">1</property>
- </packing>
- </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">4</property>
+ </packing>
</child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkGrid" id="table1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
- <object class="GtkLabel" id="label35">
+ <object class="GtkScrolledWindow" id="scrolledwindow11">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Track</property>
+ <child>
+ <object class="GtkListBox" id="audio_selected_lang">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
</object>
<packing>
- <property name="top_attach">0</property>
- <property name="left_attach">0</property>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
<property name="width">1</property>
- <property name="height">1</property>
+ <property name="height">4</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="label68">
+ <object class="GtkButton" id="audio_lang_add">
+ <property name="label" translatable="yes">Add</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Encoder</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <signal name="clicked" handler="audio_add_lang_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">0</property>
<property name="left_attach">1</property>
+ <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="AudioBitrateLabel">
+ <object class="GtkButton" id="audio_lang_remove">
+ <property name="label" translatable="yes">Remove</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Bitrate</property>
- <property name="justify">center</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <signal name="clicked" handler="audio_remove_lang_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">0</property>
- <property name="left_attach">2</property>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="AudioMixdownLabel">
+ <object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Mix</property>
+ <property name="label" translatable="yes">Available Languages</property>
</object>
<packing>
+ <property name="left_attach">0</property>
<property name="top_attach">0</property>
- <property name="left_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="AudioTrack">
- <property name="width_request">180</property>
+ <object class="GtkLabel" id="label24">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">List of audio tracks available from your source.</property>
- <signal name="changed" handler="audio_track_changed_cb" swapped="no"/>
+ <property name="label" translatable="yes">Selected Languages</property>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">5</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <object class="GtkLabel" id="labela3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Auto Passthru Options:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowMP3Pass">
+ <property name="label" translatable="yes">MP3</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable this if your playback device supports MP3.
+This permits MP3 passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="audio_passthru_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowAACPass">
+ <property name="label" translatable="yes">AAC</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable this if your playback device supports AAC.
+This permits AAC passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="audio_passthru_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowAC3Pass">
+ <property name="label" translatable="yes">AC-3</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable this if your playback device supports AC-3.
+This permits AC-3 passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="audio_passthru_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowDTSPass">
+ <property name="label" translatable="yes">DTS</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable this if your playback device supports DTS.
+This permits DTS passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="audio_passthru_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioAllowDTSHDPass">
+ <property name="label" translatable="yes">DTS-HD</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable this if your playback device supports DTS-HD.
+This permits DTS-HD passthru to be selected when automatic passthru selection is enabled.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="audio_passthru_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="labela4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="xalign">1</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Passthru Fallback:</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="AudioEncoderFallback">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the audio codec to encode with when a suitable track can not be found for audio passthru.</property>
+ <signal name="changed" handler="audio_fallback_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="AudioSecondaryEncoderMode">
+ <property name="label" translatable="yes">Use only first encoder for secondary audio</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Only the primary audio track will be encoded with the full encoder list.
+All other secondary audio output tracks will be encoded with first encoder only.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="audio_def_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="audio_def_settings_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">12</property>
+ <property name="xalign">0</property>
+ <property name="use_markup">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Audio Encoder Settings:&lt;/b&gt;</property>
+ <property name="tooltip_markup">Each selected source track will be encoded with all selected encoders</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="sep1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="audio_list_default_header">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkLabel" id="audio_defaults_encoder_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Encoder</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="audio_defaults_bitrate_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Bitrate/Quality</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="audio_defaults_mixdown_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Mixdown</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="audio_defaults_samplerate_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Samplerate</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="audio_defaults_gain_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Gain</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="audio_defaults_drc_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">DRC</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow12">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkListBox" id="audio_list_default">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="audio_defaults_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Audio Defaults</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="audio_tab">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkAlignment" id="alignment18">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <property name="left_padding">6</property>
+ <property name="right_padding">6</property>
+ <child>
+ <object class="GtkBox" id="vbox17">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkToolbar" id="audio_toolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
- <object class="GtkComboBox" id="AudioEncoder">
+ <object class="GtkToolButton" id="audio_add">
<property name="visible">True</property>
+ <property name="sensitive">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the audio codec to encode this track with.</property>
- <signal name="changed" handler="audio_codec_changed_cb" swapped="no"/>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Add</property>
+ <property name="icon_name">list-add</property>
+ <property name="tooltip_text" translatable="yes">Add new audio settings to the list</property>
+ <signal name="clicked" handler="audio_add_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="AudioBitrate">
+ <object class="GtkToolButton" id="audio_add_all">
<property name="visible">True</property>
+ <property name="sensitive">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the bitrate to encode this track with.</property>
- <signal name="changed" handler="audio_widget_changed_cb" swapped="no"/>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Add All</property>
+ <property name="icon_name">list-add</property>
+ <property name="tooltip_text" translatable="yes">Add all audio tracks to the list</property>
+ <signal name="clicked" handler="audio_add_all_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="AudioMixdown">
+ <object class="GtkToolButton" id="audio_reset">
<property name="visible">True</property>
+ <property name="sensitive">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the mixdown of the output audio track.</property>
- <signal name="changed" handler="audio_mix_changed_cb" swapped="no"/>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Reload Defaults</property>
+ <property name="icon_name">emblem-default</property>
+ <property name="tooltip_text" translatable="yes">Reload all audio settings from defaults</property>
+ <signal name="clicked" handler="audio_reset_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <property name="expand">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">2</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow5">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTreeView" id="audio_list">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
@@ -3600,7 +3413,7 @@ weather-clear</property>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
@@ -3614,301 +3427,380 @@ weather-clear</property>
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label48">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">Audio</property>
+ <property name="label" translatable="yes">Audio List</property>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
- <object class="GtkBox" id="subtitle_tab">
- <property name="orientation">vertical</property>
+ <object class="GtkBox" id="subtitle_defaults">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="orientation">vertical</property>
+ <property name="margin_left">12</property>
+ <property name="margin_right">12</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="hexpand">True</property>
<child>
- <object class="GtkAlignment" id="alignment23">
+ <object class="GtkBox" id="subtitle_defaults_box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="top_padding">12</property>
- <property name="bottom_padding">2</property>
- <property name="left_padding">12</property>
- <property name="right_padding">2</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkBox" id="vbox12">
- <property name="orientation">vertical</property>
+ <object class="GtkBox" id="subtitle_defaults_box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">2</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkBox" id="hbox45">
- <property name="orientation">horizontal</property>
+ <object class="GtkGrid" id="sub_grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkButton" id="subtitle_add">
- <property name="label" translatable="yes">Subtitle</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Add new subtitle to the list</property>
- <property name="image">subtitle_add_image</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="subtitle_add_clicked_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
+ <property name="column_spacing">5</property>
+ <property name="row_spacing">2</property>
<child>
- <object class="GtkButton" id="srt_add">
- <property name="label" translatable="yes">Import SRT</property>
+ <object class="GtkLabel" id="sub_label4">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Add new SRT subtitle to the list</property>
- <property name="image">srt_add_image</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="srt_add_clicked_cb" swapped="no"/>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Selection Behavior:</property>
+ <property name="justify">right</property>
</object>
<packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkButton" id="subtitle_remove">
+ <object class="GtkComboBox" id="SubtitleTrackSelectionBehavior">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Remove the selected subtitle settings</property>
- <property name="relief">none</property>
- <signal name="clicked" handler="subtitle_remove_clicked_cb" swapped="no"/>
- <child>
- <object class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="stock">gtk-remove</property>
- </object>
- </child>
+ <property name="can_focus">False</property>
+ <signal name="changed" handler="subtitle_def_widget_changed_cb" swapped="no"/>
</object>
<packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
</object>
<packing>
- <property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkGrid" id="subtitle_table">
+ <object class="GtkGrid" id="sub_grid3">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="column_spacing">4</property>
+ <property name="column_spacing">5</property>
+ <property name="row_spacing">2</property>
+ <property name="halign">GTK_ALIGN_END</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
<child>
- <object class="GtkLabel" id="subtitle_track_label">
+ <object class="GtkScrolledWindow" id="sub_scrolledwindow10">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Track</property>
+ <property name="min_content_height">108</property>
+ <child>
+ <object class="GtkListBox" id="subtitle_avail_lang">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
</object>
<packing>
- <property name="top_attach">0</property>
<property name="left_attach">0</property>
+ <property name="top_attach">1</property>
<property name="width">1</property>
- <property name="height">1</property>
+ <property name="height">4</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="srt_lang_label">
+ <object class="GtkScrolledWindow" id="sub_scrolledwindow11">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Language</property>
+ <child>
+ <object class="GtkListBox" id="subtitle_selected_lang">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
</object>
<packing>
- <property name="top_attach">0</property>
- <property name="left_attach">1</property>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
<property name="width">1</property>
- <property name="height">1</property>
+ <property name="height">4</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="srt_code_label">
+ <object class="GtkButton" id="subtitle_lang_add">
+ <property name="label" translatable="yes">Add</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Character Code</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <signal name="clicked" handler="subtitle_add_lang_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">0</property>
- <property name="left_attach">2</property>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="srt_file_label">
+ <object class="GtkButton" id="subtitle_lang_remove">
+ <property name="label" translatable="yes">Remove</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">File</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <signal name="clicked" handler="subtitle_remove_lang_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">0</property>
- <property name="left_attach">3</property>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="srt_offset_label">
+ <object class="GtkLabel" id="sub_label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Offset (ms)</property>
+ <property name="label" translatable="yes">Available Languages</property>
</object>
<packing>
+ <property name="left_attach">0</property>
<property name="top_attach">0</property>
- <property name="left_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="SubtitleTrack">
+ <object class="GtkLabel" id="sub_label24">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">List of subtitle tracks available from your source.</property>
- <signal name="changed" handler="subtitle_track_changed_cb" swapped="no"/>
+ <property name="label" translatable="yes">Selected Languages</property>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">0</property>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
- <object class="GtkComboBox" id="SrtLanguage">
+ <object class="GtkLabel" id="subtitle_preferred_language">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the language of this subtitle.
-This value will be used by players in subtitle menus.</property>
- <signal name="changed" handler="srt_lang_changed_cb" swapped="no"/>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Preferred Language: None</property>
+ <property name="justify">right</property>
</object>
<packing>
+ <property name="left_attach">3</property>
<property name="top_attach">1</property>
- <property name="left_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="SubtitleAddForeignAudioSearch">
+ <property name="label" translatable="yes">Add Foreign Audio Search Pass</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Add "Foreign Audio Search" when the default audio track is your preferred language.
+This search pass finds short sequences of foreign audio and provides subtitles for them.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="subtitle_def_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="SubtitleAddForeignAudioSubtitle">
+ <property name="label" translatable="yes">Add subtitle track if default audio is foreign</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">When the default audio track is not your preferred language, add a subtitle track.</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="subtitle_def_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="SubtitleAddCC">
+ <property name="label" translatable="yes">Add Closed Captions when available</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Closed captions are text subtitles that can be added to any container as a soft subtitle track (not burned)</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="subtitle_def_widget_changed_cb" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="subtitle_defaults_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Subtitle Defaults</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="subtitle_tab">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkAlignment" id="alignment23">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <property name="left_padding">6</property>
+ <property name="right_padding">6</property>
+ <child>
+ <object class="GtkBox" id="vbox12">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkToolbar" id="subtitle_toolbar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
- <object class="GtkComboBox" id="SrtCodeset">
- <property name="width_request">150</property>
+ <object class="GtkToolButton" id="subtitle_add">
<property name="visible">True</property>
+ <property name="sensitive">True</property>
<property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Set the character code used by the SRT file you are importing.
-
-SRTs come in all flavours of character sets.
-We translate the character set to UTF-8.
-The source's character code is needed in order to perform this translation.</property>
- <property name="has_entry">True</property>
- <signal name="changed" handler="srt_changed_cb" swapped="no"/>
- <child internal-child="entry">
- <object class="GtkEntry" id="combobox-entry1">
- <property name="can_focus">True</property>
- </object>
- </child>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Add</property>
+ <property name="icon_name">list-add</property>
+ <property name="tooltip_text" translatable="yes">Add new subtitle settings to the list</property>
+ <signal name="clicked" handler="subtitle_add_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
- <object class="GtkFileChooserButton" id="SrtFile">
+ <object class="GtkToolButton" id="subtitle_add_all">
<property name="visible">True</property>
+ <property name="sensitive">True</property>
<property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Select the SRT file to import.</property>
- <property name="local_only">False</property>
- <property name="hexpand">True</property>
- <property name="title" translatable="yes">Srt File</property>
- <signal name="selection-changed" handler="srt_file_changed_cb" swapped="no"/>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Add All</property>
+ <property name="icon_name">list-add</property>
+ <property name="tooltip_text" translatable="yes">Add all subtitle tracks to the list</property>
+ <signal name="clicked" handler="subtitle_add_all_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
- <object class="GtkSpinButton" id="SrtOffset">
+ <object class="GtkToolButton" id="subtitle_reset">
<property name="visible">True</property>
- <property name="can_focus">True</property>
+ <property name="sensitive">True</property>
+ <property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip_text" translatable="yes">Adjust the offset in milliseconds between video and SRT timestamps</property>
- <property name="primary_icon_activatable">False</property>
- <property name="secondary_icon_activatable">False</property>
- <property name="adjustment">adjustment31</property>
- <signal name="value-changed" handler="srt_changed_cb" swapped="no"/>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Reload Defaults</property>
+ <property name="icon_name">emblem-default</property>
+ <property name="tooltip_text" translatable="yes">Reload all subtitle settings from defaults</property>
+ <signal name="clicked" handler="subtitle_reset_clicked_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">1</property>
- <property name="left_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
+ <property name="expand">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow4">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTreeView" id="subtitle_list">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="headers_visible">False</property>
+ <property name="headers_clickable">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection2"/>
</child>
@@ -3918,7 +3810,7 @@ The source's character code is needed in order to perform this translation.</pro
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">2</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
@@ -3932,17 +3824,17 @@ The source's character code is needed in order to perform this translation.</pro
</child>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">5</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">Subtitles</property>
+ <property name="label" translatable="yes">Subtitle List</property>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">5</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -5015,7 +4907,7 @@ You can edit these and add additional options.</property>
</child>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">6</property>
</packing>
</child>
<child type="tab">
@@ -5025,7 +4917,7 @@ You can edit these and add additional options.</property>
<property name="label" translatable="yes">Advanced</property>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">6</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -5096,7 +4988,7 @@ You can edit these and add additional options.</property>
</child>
</object>
<packing>
- <property name="position">5</property>
+ <property name="position">7</property>
</packing>
</child>
<child type="tab">
@@ -5107,7 +4999,7 @@ You can edit these and add additional options.</property>
<property name="label" translatable="yes">Chapters</property>
</object>
<packing>
- <property name="position">5</property>
+ <property name="position">7</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -5430,7 +5322,7 @@ You can edit these and add additional options.</property>
</child>
</object>
<packing>
- <property name="position">6</property>
+ <property name="position">8</property>
</packing>
</child>
<child type="tab">
@@ -5441,7 +5333,7 @@ You can edit these and add additional options.</property>
<property name="label" translatable="yes">Tags</property>
</object>
<packing>
- <property name="position">6</property>
+ <property name="position">8</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -6149,173 +6041,6 @@ You can edit these and add additional options.</property>
</packing>
</child>
<child>
- <object class="GtkBox" id="vbox18">
- <property name="orientation">vertical</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkAlignment" id="alignment61">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="yscale">0</property>
- <property name="top_padding">6</property>
- <property name="bottom_padding">6</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkBox" id="vbox7">
- <property name="orientation">vertical</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkBox" id="hbox81">
- <property name="orientation">horizontal</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">4</property>
- <child>
- <object class="GtkLabel" id="label87">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Preferred Language:</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="PreferredLanguage">
- <property name="width_request">150</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <signal name="changed" handler="pref_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment8">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">17</property>
- <child>
- <object class="GtkBox" id="vbox49">
- <property name="orientation">vertical</property>
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <object class="GtkRadioButton" id="AudioDUB">
- <property name="label" translatable="yes">DUB Foreign language audio</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="xalign">0</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="pref_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkRadioButton" id="NotAudioDUB">
- <property name="label" translatable="yes">Use foreign language audio and add subtitles</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- <property name="group">AudioDUB</property>
- <signal name="toggled" handler="pref_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment70">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="yscale">0</property>
- <property name="top_padding">6</property>
- <property name="bottom_padding">6</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkCheckButton" id="AddCC">
- <property name="label" translatable="yes">Add Closed Captions when available</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="pref_changed_cb" swapped="no"/>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child type="tab">
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Audio/Subtitles</property>
- </object>
- <packing>
- <property name="position">1</property>
- <property name="tab_fill">False</property>
- </packing>
- </child>
- <child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -6579,26 +6304,6 @@ You can edit these and add additional options.</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="AdvancedAutoPassthru">
- <property name="label" translatable="yes">Enable Advanced Auto-Passthru options</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip_text" translatable="yes">Enabling this adds extra widgets to the audio panel that allow
-you to specify which particular codecs shall be passed
-and which codec to use when passthru is not possible</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="advanced_audio_changed_cb" swapped="no"/>
- </object>
- <packing>
- <property name="top_attach">5</property>
- <property name="left_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
<object class="GtkCheckButton" id="HideAdvancedVideoSettings">
<property name="label" translatable="yes">Hide Advanced Video Options Tab</property>
<property name="visible">True</property>
@@ -6612,7 +6317,7 @@ on the Video tab instead.</property>
<signal name="toggled" handler="advanced_video_changed_cb" swapped="no"/>
</object>
<packing>
- <property name="top_attach">6</property>
+ <property name="top_attach">5</property>
<property name="left_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
@@ -6838,7 +6543,7 @@ on the Video tab instead.</property>
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">1</property>
</packing>
</child>
<child type="tab">
@@ -6848,7 +6553,7 @@ on the Video tab instead.</property>
<property name="label" translatable="yes">Advanced</property>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -7470,7 +7175,7 @@ Setting this to 0 means there is no maximum height.</property>
<object class="GtkImage" id="live_preview_play_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="stock">gtk-media-play</property>
+ <property name="icon_name">gtk-media-play</property>
</object>
</child>
</object>
@@ -9434,13 +9139,13 @@ YadifMode:YadifParity:McdintMode:McdeintQp</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="stock">gtk-add</property>
+ <property name="icon_name">gtk-add</property>
</object>
<object class="GtkImage" id="subtitle_add_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="stock">gtk-add</property>
+ <property name="icon_name">gtk-add</property>
</object>
<object class="GtkDialog" id="tweak_dialog">
<property name="can_focus">False</property>
@@ -9553,6 +9258,915 @@ YadifMode:YadifParity:McdintMode:McdeintQp</property>
<action-widget response="-5">tweak_ok</action-widget>
</action-widgets>
</object>
+ <object class="GtkDialog" id="subtitle_dialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="modal">True</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="skip_pager_hint">True</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-subtitle-vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-subtitle-action_area">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="subtitle_cancel">
+ <property name="label" translatable="yes">Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="subtitle_ok">
+ <property name="label" translatable="yes">Ok</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="subtitle_srt_switch_box">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">24</property>
+ <child>
+ <object class="GtkRadioButton" id="SubtitleSrtEnable">
+ <property name="label" translatable="yes">Import SRT</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable settings to import an SRT subtitle file</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="subtitle_srt_radio_toggled_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="SubtitleSrtDisable">
+ <property name="label" translatable="yes">Embedded Subtitle List</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable settings to select embedded subtitles</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">SubtitleSrtEnable</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="subtitle_settings_box">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkGrid" id="subtitle_srt_grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="column_spacing">4</property>
+ <child>
+ <object class="GtkLabel" id="srt_lang_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Language</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="srt_code_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Character Code</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="srt_file_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">File:</property>
+ <property name="halign">end</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="left_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="srt_offset_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Offset (ms)</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="SrtLanguage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the language of this subtitle.
+ This value will be used by players in subtitle menus.</property>
+ <signal name="changed" handler="srt_lang_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="SrtCodeset">
+ <property name="width_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the character code used by the SRT file you are importing.
+
+ SRTs come in all flavours of character sets.
+ We translate the character set to UTF-8.
+ The source's character code is needed in order to perform this translation.</property>
+ <property name="has_entry">True</property>
+ <signal name="changed" handler="srt_changed_cb" swapped="no"/>
+ <child internal-child="entry">
+ <object class="GtkEntry" id="combobox-entry1">
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserButton" id="SrtFile">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Select the SRT file to import.</property>
+ <property name="local_only">False</property>
+ <property name="hexpand">True</property>
+ <property name="title" translatable="yes">Srt File</property>
+ <signal name="selection-changed" handler="srt_file_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="left_attach">1</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="SrtOffset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Adjust the offset in milliseconds between video and SRT timestamps</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="secondary_icon_activatable">False</property>
+ <property name="adjustment">adjustment31</property>
+ <signal name="value-changed" handler="srt_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="subtitle_track_box">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="subtitle_track_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Track</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="SubtitleTrack">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">List of subtitle tracks available from your source.</property>
+ <signal name="changed" handler="subtitle_track_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="subtitle_options_box">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkCheckButton" id="SubtitleForced">
+ <property name="label" translatable="yes">Forced Subtitles Only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Use only subtitles that have been flagged
+as forced in the source subtitle track
+
+"Forced" subtitles are usually used to show
+subtitles during scenes where someone is speaking
+a foreign language.</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="subtitle_forced_toggled_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="SubtitleBurned">
+ <property name="label" translatable="yes">Burn into video</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Render the subtitle over the video.
+The subtitle will be part of the video and can not be disabled.</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="subtitle_burned_toggled_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="SubtitleDefaultTrack">
+ <property name="label" translatable="yes">Set Default Track</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the default output subtitle track.
+
+Most players will automatically display this
+subtitle track whenever the video is played.
+
+This is usefule for creating a "forced" track
+in your output.</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="subtitle_default_toggled_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">subtitle_cancel</action-widget>
+ <action-widget response="-5">subtitle_ok</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkDialog" id="audio_dialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="modal">True</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="type_hint">dialog</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="skip_pager_hint">True</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-audio-vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-audio-action_area">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="audio_cancel">
+ <property name="label" translatable="yes">Cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="audio_ok">
+ <property name="label" translatable="yes">Ok</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="audio_dialog_grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="column_spacing">5</property>
+ <child>
+ <object class="GtkLabel" id="label35">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Source Track</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="AudioTrack">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">List of audio tracks available from your source.</property>
+ <signal name="changed" handler="audio_track_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="audio_name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Track Name:</property>
+ <property name="use_markup">True</property>
+ <property name="halign">center</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="AudioTrackName">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the audio track name.
+
+Players may use this in the audio selection list.</property>
+ <property name="max_length">40</property>
+ <property name="hexpand">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="primary_icon_activatable">False</property>
+ <property name="secondary_icon_activatable">False</property>
+ <signal name="changed" handler="audio_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="audio_dialog_grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">24</property>
+ <child>
+ <object class="GtkLabel" id="AudioEncoderLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Encoder</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioBitrateLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Bitrate/Quality</property>
+ <property name="use_markup">True</property>
+ <property name="halign">center</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioMixdownLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Mix</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioSamplerateLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Sample Rate</property>
+ <property name="use_markup">True</property>
+ <property name="halign">center</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioTrackGainLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Gain</property>
+ <property name="use_markup">True</property>
+ <property name="halign">center</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioTrackDRCSliderLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_markup">&lt;b&gt;Dynamic Range Compression:&lt;/b&gt; Adjust the dynamic range of the output audio track.
+
+For source audio that has a wide dynamic range (very loud and very soft sequences),
+DRC allows you to 'compress' the range by making loud sounds softer and soft sounds louder.</property>
+ <property name="label" translatable="yes">DRC</property>
+ <property name="use_markup">True</property>
+ <property name="halign">center</property>
+ </object>
+ <packing>
+ <property name="top_attach">0</property>
+ <property name="left_attach">5</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="AudioEncoder">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the audio codec to encode this track with.</property>
+ <signal name="changed" handler="audio_codec_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="audio_dialog_hbox24">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox" id="AudioTrackQualityEnableBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkRadioButton" id="AudioTrackBitrateEnable">
+ <property name="label" translatable="yes">Bitrate</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable bitrate setting</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="audio_quality_radio_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="AudioTrackQualityEnable">
+ <property name="label" translatable="yes">Quality</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Enable quality setting</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">AudioTrackBitrateEnable</property>
+ <signal name="toggled" handler="audio_quality_radio_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="AudioBitrate">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the bitrate to encode this track with.</property>
+ <signal name="changed" handler="audio_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="AudioTrackQualityBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkScaleButton" id="AudioTrackQuality">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_markup">&lt;b&gt;Quality:&lt;/b&gt; For output codec's that support it, adjust the quality of the output.</property>
+ <property name="orientation">vertical</property>
+ <property name="adjustment">audio_quality_adj</property>
+ <property name="icons">weather-storm
+weather-clear
+weather-storm
+weather-showers-scattered
+weather-showers
+weather-overcast
+weather-few-clouds
+weather-clear</property>
+ <signal name="value-changed" handler="quality_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioTrackQualityValue">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">00.0</property>
+ <property name="use_markup">True</property>
+ <property name="width_chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="AudioMixdown">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the mixdown of the output audio track.</property>
+ <signal name="changed" handler="audio_mix_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="AudioSamplerate">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_text" translatable="yes">Set the sample rate of the output audio track.</property>
+ <signal name="changed" handler="audio_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="hbox34">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkScaleButton" id="AudioTrackGain">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_markup">&lt;b&gt;Audio Gain:&lt;/b&gt; Adjust the amplification or attenuation of the output audio track.</property>
+ <property name="orientation">vertical</property>
+ <property name="adjustment">adjustment35</property>
+ <property name="icons">audio-volume-muted
+audio-volume-high
+audio-volume-low
+audio-volume-medium</property>
+ <signal name="value-changed" handler="gain_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioTrackGainValue">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">0dB</property>
+ <property name="use_markup">True</property>
+ <property name="width_chars">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">4</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="hbox33">
+ <property name="orientation">horizontal</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <object class="GtkScaleButton" id="AudioTrackDRCSlider">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">GTK_ALIGN_CENTER</property>
+ <property name="receives_default">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip_markup">&lt;b&gt;Dynamic Range Compression:&lt;/b&gt; Adjust the dynamic range of the output audio track.
+
+For source audio that has a wide dynamic range (very loud and very soft sequences),
+DRC allows you to 'compress' the range by making loud sounds softer and soft sounds louder.</property>
+ <property name="orientation">vertical</property>
+ <property name="adjustment">adjustment28</property>
+ <property name="icons">audio-input-microphone</property>
+ <signal name="value-changed" handler="drc_widget_changed_cb" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="AudioTrackDRCValue">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Off</property>
+ <property name="use_markup">True</property>
+ <property name="width_chars">4</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="left_attach">5</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">audio_cancel</action-widget>
+ <action-widget response="-5">audio_ok</action-widget>
+ </action-widgets>
+ </object>
<object class="GtkDialog" id="update_dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 393aad0e5..c857884e4 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -71,6 +71,30 @@ index_str_init(gint max_index)
}
}
+static options_map_t d_subtitle_track_sel_opts[] =
+{
+ {N_("None"), "none", 0, "0"},
+ {N_("First Track Matching Selected Languages"), "first", 1, "1"},
+ {N_("All Tracks Matching Selected Languages"), "all", 2, "2"},
+};
+combo_opts_t subtitle_track_sel_opts =
+{
+ sizeof(d_subtitle_track_sel_opts)/sizeof(options_map_t),
+ d_subtitle_track_sel_opts
+};
+
+static options_map_t d_audio_track_sel_opts[] =
+{
+ {N_("None"), "none", 0, "0"},
+ {N_("First Track Matching Selected Languages"), "first", 1, "1"},
+ {N_("All Tracks Matching Selected Languages"), "all", 2, "2"},
+};
+combo_opts_t audio_track_sel_opts =
+{
+ sizeof(d_audio_track_sel_opts)/sizeof(options_map_t),
+ d_audio_track_sel_opts
+};
+
static options_map_t d_point_to_point_opts[] =
{
{N_("Chapters:"), "chapter", 0, "0"},
@@ -365,6 +389,8 @@ typedef struct
combo_name_map_t combo_name_map[] =
{
+ {"SubtitleTrackSelectionBehavior", &subtitle_track_sel_opts},
+ {"AudioTrackSelectionBehavior", &audio_track_sel_opts},
{"PtoPType", &point_to_point_opts},
{"WhenComplete", &when_complete_opts},
{"PicturePAR", &par_opts},
@@ -1028,62 +1054,33 @@ ghb_find_closest_audio_samplerate(gint irate)
return result;
}
-hb_rate_t *ghb_audio_bitrates = NULL;
-int ghb_audio_bitrates_count = 0;
-int ghb_abr_count = 0;
-
-static const hb_rate_t *
-lookup_audio_bitrate(const GValue *grate)
-{
- gint ii;
- const hb_rate_t *result = NULL;
-
- if (G_VALUE_TYPE(grate) == G_TYPE_STRING)
- {
- // Coincidentally, the string "source" will return 0
- // which is our flag to use "same as source"
- gchar *str = ghb_value_string(grate);
- for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
- {
- if (strcmp(ghb_audio_bitrates[ii].name, str) == 0)
- {
- g_free(str);
- return &ghb_audio_bitrates[ii];
- }
- }
- g_free(str);
- }
- else if (G_VALUE_TYPE(grate) == G_TYPE_INT ||
- G_VALUE_TYPE(grate) == G_TYPE_INT64 ||
- G_VALUE_TYPE(grate) == G_TYPE_DOUBLE)
- {
- gint val = ghb_value_int(grate);
- for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
- {
- if (ghb_audio_bitrates[ii].rate == val)
- {
- return &ghb_audio_bitrates[ii];
- }
- }
- }
- return result;
-}
+int ghb_custom_bitrate = 0;
+gchar *ghb_custom_bitrate_str = NULL;
static gint
lookup_audio_bitrate_int(const GValue *grate)
{
- const hb_rate_t *rate = lookup_audio_bitrate(grate);
- if (rate != NULL)
- return rate->rate;
- return 160;
+ return ghb_value_int(grate);
}
static const gchar*
lookup_audio_bitrate_option(const GValue *grate)
{
- const hb_rate_t *rate = lookup_audio_bitrate(grate);
- if (rate != NULL)
- return rate->name;
+ int rate = ghb_value_int(grate);
+
+ if (rate == ghb_custom_bitrate && ghb_custom_bitrate_str != NULL)
+ return ghb_custom_bitrate_str;
+
+ const hb_rate_t *hbrate;
+ for (hbrate = hb_audio_bitrate_get_next(NULL); hbrate != NULL;
+ hbrate = hb_audio_bitrate_get_next(hbrate))
+ {
+ if (rate == hbrate->rate)
+ {
+ return hbrate->name;
+ }
+ }
+
return "160";
}
@@ -1199,7 +1196,7 @@ lookup_audio_encoder_option(const GValue *genc)
const hb_encoder_t *enc = lookup_audio_encoder(genc);
if (enc != NULL)
return enc->name;
- return NULL;
+ return "None";
}
static const gchar*
@@ -1217,7 +1214,7 @@ lookup_audio_encoder_string(const GValue *genc)
const hb_encoder_t *enc = lookup_audio_encoder(genc);
if (enc != NULL)
return enc->short_name;
- return NULL;
+ return "none";
}
static const gchar*
@@ -1229,8 +1226,13 @@ lookup_video_encoder_string(const GValue *genc)
return NULL;
}
-static int
-lookup_audio_lang(const GValue *glang)
+const iso639_lang_t* ghb_iso639_lookup_by_int(int idx)
+{
+ return &ghb_language_table[idx];
+}
+
+int
+ghb_lookup_audio_lang(const GValue *glang)
{
gint ii;
gchar *str;
@@ -1238,7 +1240,32 @@ lookup_audio_lang(const GValue *glang)
str = ghb_value_string(glang);
for (ii = 0; ii < LANG_TABLE_SIZE; ii++)
{
- if (strcmp(ghb_language_table[ii].iso639_2, str) == 0)
+ if (ghb_language_table[ii].iso639_2 &&
+ strcmp(ghb_language_table[ii].iso639_2, str) == 0)
+ {
+ g_free(str);
+ return ii;
+ }
+ if (ghb_language_table[ii].iso639_2b &&
+ strcmp(ghb_language_table[ii].iso639_2b, str) == 0)
+ {
+ g_free(str);
+ return ii;
+ }
+ if (ghb_language_table[ii].iso639_1 &&
+ strcmp(ghb_language_table[ii].iso639_1, str) == 0)
+ {
+ g_free(str);
+ return ii;
+ }
+ if (ghb_language_table[ii].native_name &&
+ strcmp(ghb_language_table[ii].native_name, str) == 0)
+ {
+ g_free(str);
+ return ii;
+ }
+ if (ghb_language_table[ii].eng_name &&
+ strcmp(ghb_language_table[ii].eng_name, str) == 0)
{
g_free(str);
return ii;
@@ -1251,7 +1278,7 @@ lookup_audio_lang(const GValue *glang)
static int
lookup_audio_lang_int(const GValue *glang)
{
- gint ii = lookup_audio_lang(glang);
+ gint ii = ghb_lookup_audio_lang(glang);
if (ii >= 0)
return ii;
return 0;
@@ -1260,7 +1287,7 @@ lookup_audio_lang_int(const GValue *glang)
static const gchar*
lookup_audio_lang_option(const GValue *glang)
{
- gint ii = lookup_audio_lang(glang);
+ gint ii = ghb_lookup_audio_lang(glang);
if (ii >= 0)
{
if (ghb_language_table[ii].native_name[0] != 0)
@@ -1268,7 +1295,7 @@ lookup_audio_lang_option(const GValue *glang)
else
return ghb_language_table[ii].eng_name;
}
- return "Same as source";
+ return "Any";
}
GValue*
@@ -1277,7 +1304,7 @@ ghb_lookup_audio_encoder_value(gint ienc)
const hb_encoder_t *enc = lookup_audio_encoder_by_int(ienc);
if (enc != NULL)
return ghb_string_value_new(enc->short_name);
- return ghb_string_value_new("copy");
+ return ghb_string_value_new("none");
}
static GValue*
@@ -1413,21 +1440,20 @@ const gchar*
ghb_subtitle_track_lang(GValue *settings, gint track)
{
gint titleindex;
+ hb_title_t * title;
titleindex = ghb_settings_combo_int(settings, "title");
if (titleindex < 0)
goto fail;
+ title = ghb_get_title_info(titleindex);
+ if (title == NULL) // Bad titleindex
+ goto fail;
if (track == -1)
- return ghb_get_user_audio_lang(settings, titleindex, 0);
+ return ghb_get_user_audio_lang(settings, title, 0);
if (track < 0)
goto fail;
- hb_title_t * title;
hb_subtitle_t * sub;
-
- title = ghb_get_title_info( titleindex );
- if (title == NULL) // Bad titleindex
- goto fail;
sub = hb_list_item( title->list_subtitle, track);
if (sub != NULL)
return sub->iso639_2;
@@ -1471,39 +1497,27 @@ get_hb_audio(hb_handle_t *h, gint titleindex, gint track)
}
static gint
-search_rates(hb_rate_t *rates, gint rate, gint count)
+search_audio_bitrates(gint rate)
{
- gint ii;
- for (ii = 0; ii < count; ii++)
+ const hb_rate_t *hbrate;
+ for (hbrate = hb_audio_bitrate_get_next(NULL); hbrate != NULL;
+ hbrate = hb_audio_bitrate_get_next(hbrate))
{
- if (rates[ii].rate == rate)
- return ii;
+ if (hbrate->rate == rate)
+ return 1;
}
- return -1;
+ return 0;
}
static gboolean find_combo_item_by_int(GtkTreeModel *store, gint value, GtkTreeIter *iter);
-static GtkListStore*
-get_combo_box_store(GtkBuilder *builder, const gchar *name)
-{
- GtkComboBox *combo;
- GtkListStore *store;
-
- g_debug("get_combo_box_store() %s\n", name);
- // First modify the combobox model to allow greying out of options
- combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
- store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
- return store;
-}
-
static void
-grey_combo_box_item(GtkBuilder *builder, const gchar *name, gint value, gboolean grey)
+grey_combo_box_item(GtkComboBox *combo, gint value, gboolean grey)
{
GtkListStore *store;
GtkTreeIter iter;
- store = get_combo_box_store(builder, name);
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
if (find_combo_item_by_int(GTK_TREE_MODEL(store), value, &iter))
{
gtk_list_store_set(store, &iter,
@@ -1513,6 +1527,27 @@ grey_combo_box_item(GtkBuilder *builder, const gchar *name, gint value, gboolean
}
static void
+grey_builder_combo_box_item(GtkBuilder *builder, const gchar *name, gint value, gboolean grey)
+{
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ grey_combo_box_item(combo, value, grey);
+}
+
+void
+ghb_mix_opts_filter(GtkComboBox *combo, gint acodec)
+{
+ g_debug("ghb_mix_opts_filter()\n");
+
+ const hb_mixdown_t *mix;
+ for (mix = hb_mixdown_get_next(NULL); mix != NULL;
+ mix = hb_mixdown_get_next(mix))
+ {
+ grey_combo_box_item(combo, mix->amixdown,
+ !hb_mixdown_has_codec_support(mix->amixdown, acodec));
+ }
+}
+
+static void
grey_mix_opts(signal_user_data_t *ud, gint acodec, gint64 layout)
{
g_debug("grey_mix_opts()\n");
@@ -1521,7 +1556,7 @@ grey_mix_opts(signal_user_data_t *ud, gint acodec, gint64 layout)
for (mix = hb_mixdown_get_next(NULL); mix != NULL;
mix = hb_mixdown_get_next(mix))
{
- grey_combo_box_item(ud->builder, "AudioMixdown", mix->amixdown,
+ grey_builder_combo_box_item(ud->builder, "AudioMixdown", mix->amixdown,
!hb_mixdown_is_supported(mix->amixdown, acodec, layout));
}
}
@@ -1548,7 +1583,7 @@ ghb_grey_combo_options(signal_user_data_t *ud)
mux = ghb_lookup_combo_int("FileFormat", gval);
ghb_value_free(gval);
- grey_combo_box_item(ud->builder, "x264_analyse", 4, TRUE);
+ grey_builder_combo_box_item(ud->builder, "x264_analyse", 4, TRUE);
const hb_encoder_t *enc;
for (enc = hb_audio_encoder_get_next(NULL); enc != NULL;
@@ -1556,16 +1591,16 @@ ghb_grey_combo_options(signal_user_data_t *ud)
{
if (!(mux & enc->muxers))
{
- grey_combo_box_item(ud->builder, "AudioEncoder",
+ grey_builder_combo_box_item(ud->builder, "AudioEncoder",
enc->codec, TRUE);
- grey_combo_box_item(ud->builder, "AudioEncoderFallback",
+ grey_builder_combo_box_item(ud->builder, "AudioEncoderFallback",
enc->codec, TRUE);
}
else
{
- grey_combo_box_item(ud->builder, "AudioEncoder",
+ grey_builder_combo_box_item(ud->builder, "AudioEncoder",
enc->codec, FALSE);
- grey_combo_box_item(ud->builder, "AudioEncoderFallback",
+ grey_builder_combo_box_item(ud->builder, "AudioEncoderFallback",
enc->codec, FALSE);
}
}
@@ -1574,35 +1609,35 @@ ghb_grey_combo_options(signal_user_data_t *ud)
{
if (!(mux & enc->muxers))
{
- grey_combo_box_item(ud->builder, "VideoEncoder",
+ grey_builder_combo_box_item(ud->builder, "VideoEncoder",
enc->codec, TRUE);
}
else
{
- grey_combo_box_item(ud->builder, "VideoEncoder",
+ grey_builder_combo_box_item(ud->builder, "VideoEncoder",
enc->codec, FALSE);
}
}
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_MP3)
{
- grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_MP3_PASS, TRUE);
+ grey_builder_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_MP3_PASS, TRUE);
}
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_FFAAC)
{
- grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AAC_PASS, TRUE);
+ grey_builder_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AAC_PASS, TRUE);
}
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_AC3)
{
- grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AC3_PASS, TRUE);
+ grey_builder_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_AC3_PASS, TRUE);
}
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_DCA)
{
- grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
+ grey_builder_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_PASS, TRUE);
}
if (aconfig && (aconfig->in.codec & HB_ACODEC_MASK) != HB_ACODEC_DCA_HD)
{
- grey_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_HD_PASS, TRUE);
+ grey_builder_combo_box_item(ud->builder, "AudioEncoder", HB_ACODEC_DCA_HD_PASS, TRUE);
}
widget = GHB_WIDGET (ud->builder, "AudioEncoder");
@@ -1611,7 +1646,7 @@ ghb_grey_combo_options(signal_user_data_t *ud)
ghb_value_free(gval);
gint64 layout = aconfig != NULL ? aconfig->in.channel_layout : ~0;
- fallback = ghb_select_fallback(ud->settings, mux, acodec);
+ fallback = ghb_select_fallback(ud->settings, acodec);
gint copy_mask = ghb_get_copy_mask(ud->settings);
acodec = ghb_select_audio_codec(mux, aconfig, acodec, fallback, copy_mask);
grey_mix_opts(ud, acodec, layout);
@@ -1630,16 +1665,14 @@ ghb_get_best_mix(hb_audio_config_t *aconfig, gint acodec, gint mix)
}
// Set up the model for the combo box
-static void
-init_combo_box(GtkBuilder *builder, const gchar *name)
+void
+ghb_init_combo_box(GtkComboBox *combo)
{
- GtkComboBox *combo;
GtkListStore *store;
GtkCellRenderer *cell;
- g_debug("init_combo_box() %s\n", name);
+ g_debug("ghb_init_combo_box()\n");
// First modify the combobox model to allow greying out of options
- combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
if (combo == NULL)
return;
// Store contains:
@@ -1666,15 +1699,27 @@ init_combo_box(GtkBuilder *builder, const gchar *name)
}
}
+// Set up the model for the combo box
static void
-audio_samplerate_opts_set(GtkBuilder *builder, const gchar *name)
+init_combo_box(GtkBuilder *builder, const gchar *name)
+{
+ GtkComboBox *combo;
+
+ g_debug("init_combo_box() %s\n", name);
+ // First modify the combobox model to allow greying out of options
+ combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ ghb_init_combo_box(combo);
+}
+
+void
+ghb_audio_samplerate_opts_set(GtkComboBox *combo)
{
GtkTreeIter iter;
GtkListStore *store;
gchar *str;
g_debug("audio_samplerate_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
// Add an item for "Same As Source"
gtk_list_store_append(store, &iter);
@@ -1706,13 +1751,22 @@ audio_samplerate_opts_set(GtkBuilder *builder, const gchar *name)
}
static void
+audio_samplerate_opts_set(GtkBuilder *builder, const gchar *name)
+{
+ g_debug("audio_samplerate_opts_set ()\n");
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ ghb_audio_samplerate_opts_set(combo);
+}
+
+static void
video_framerate_opts_set(GtkBuilder *builder, const gchar *name)
{
GtkTreeIter iter;
GtkListStore *store;
g_debug("video_framerate_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
// Add an item for "Same As Source"
gtk_list_store_append(store, &iter);
@@ -1765,7 +1819,8 @@ video_encoder_opts_set(
gchar *str;
g_debug("video_encoder_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
const hb_encoder_t *enc;
@@ -1785,10 +1840,9 @@ video_encoder_opts_set(
}
}
-static void
-audio_encoder_opts_set_with_mask(
- GtkBuilder *builder,
- const gchar *name,
+void
+ghb_audio_encoder_opts_set_with_mask(
+ GtkComboBox *combo,
int mask,
int neg_mask)
{
@@ -1796,8 +1850,8 @@ audio_encoder_opts_set_with_mask(
GtkListStore *store;
gchar *str;
- g_debug("audio_encoder_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ g_debug("ghb_audio_encoder_opts_set_with_mask()\n");
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
const hb_encoder_t *enc;
@@ -1821,11 +1875,54 @@ audio_encoder_opts_set_with_mask(
}
static void
+audio_encoder_opts_set_with_mask(
+ GtkBuilder *builder,
+ const gchar *name,
+ int mask,
+ int neg_mask)
+{
+ g_debug("audio_encoder_opts_set_with_mask()\n");
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ ghb_audio_encoder_opts_set_with_mask(combo, mask, neg_mask);
+}
+
+void
+ghb_audio_encoder_opts_set(GtkComboBox *combo)
+{
+ ghb_audio_encoder_opts_set_with_mask(combo, ~0, 0);
+}
+
+static void
audio_encoder_opts_set(
GtkBuilder *builder,
const gchar *name)
{
- audio_encoder_opts_set_with_mask(builder, name, ~0, 0);
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gchar *str;
+
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
+ gtk_list_store_clear(store);
+
+ const hb_encoder_t *enc;
+ for (enc = hb_audio_encoder_get_next(NULL); enc != NULL;
+ enc = hb_audio_encoder_get_next(enc))
+ {
+ if (enc->codec != HB_ACODEC_AUTO_PASS)
+ {
+ gtk_list_store_append(store, &iter);
+ str = g_strdup_printf("<small>%s</small>", enc->name);
+ gtk_list_store_set(store, &iter,
+ 0, str,
+ 1, TRUE,
+ 2, enc->short_name,
+ 3, (gdouble)enc->codec,
+ 4, enc->short_name,
+ -1);
+ g_free(str);
+ }
+ }
}
static void
@@ -1834,15 +1931,15 @@ acodec_fallback_opts_set(GtkBuilder *builder, const gchar *name)
audio_encoder_opts_set_with_mask(builder, name, ~0, HB_ACODEC_PASS_FLAG);
}
-static void
-mix_opts_set(GtkBuilder *builder, const gchar *name)
+void
+ghb_mix_opts_set(GtkComboBox *combo)
{
GtkTreeIter iter;
GtkListStore *store;
gchar *str;
g_debug("mix_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
const hb_mixdown_t *mix;
@@ -1863,6 +1960,14 @@ mix_opts_set(GtkBuilder *builder, const gchar *name)
}
static void
+mix_opts_set(GtkBuilder *builder, const gchar *name)
+{
+ g_debug("mix_opts_set ()\n");
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ ghb_mix_opts_set(combo);
+}
+
+static void
container_opts_set(
GtkBuilder *builder,
const gchar *name)
@@ -1872,7 +1977,8 @@ container_opts_set(
gchar *str;
g_debug("hb_container_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
const hb_container_t *mux;
@@ -1900,7 +2006,8 @@ srt_codeset_opts_set(GtkBuilder *builder, const gchar *name)
gint ii;
g_debug("srt_codeset_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
for (ii = 0; ii < SRT_TABLE_SIZE; ii++)
{
@@ -1923,7 +2030,8 @@ language_opts_set(GtkBuilder *builder, const gchar *name)
gint ii;
g_debug("language_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
for (ii = 0; ii < LANG_TABLE_SIZE; ii++)
{
@@ -1958,7 +2066,8 @@ title_opts_set(GtkBuilder *builder, const gchar *name)
gint count = 0;
g_debug("title_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
if (h_scan != NULL)
{
@@ -2074,7 +2183,8 @@ x264_tune_opts_set(GtkBuilder *builder, const gchar *name)
while (tunes && tunes[count]) count++;
g_debug("x264_tune_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
gtk_list_store_append(store, &iter);
@@ -2114,7 +2224,8 @@ h264_profile_opts_set(GtkBuilder *builder, const gchar *name)
while (profiles && profiles[count]) count++;
g_debug("h264_profile_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
for (ii = 0; ii < count; ii++)
@@ -2142,7 +2253,8 @@ h264_level_opts_set(GtkBuilder *builder, const gchar *name)
while (levels && levels[count]) count++;
g_debug("h264_level_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
for (ii = 0; ii < count; ii++)
@@ -2197,7 +2309,8 @@ audio_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex)
gchar *str;
g_debug("audio_track_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
title = ghb_get_title_info(titleindex);
if (title != NULL)
@@ -2264,7 +2377,6 @@ audio_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex)
audio_track_opts.map[ii].ivalue = ii;
audio_track_opts.map[ii].svalue = index_str[ii];
}
- GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
gtk_combo_box_set_active (combo, 0);
}
@@ -2297,39 +2409,34 @@ subtitle_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex)
static char ** options = NULL;
g_debug("subtitle_track_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
title = ghb_get_title_info(titleindex);
if (title != NULL)
{
count = hb_list_count( title->list_subtitle );
}
- if (count > 100) count = 100;
if (subtitle_opts.map) g_free(subtitle_opts.map);
+
+ subtitle_opts.count = count+1;
+ subtitle_opts.map = g_malloc((subtitle_opts.count)*sizeof(options_map_t));
+
if (count > 0)
{
- subtitle_opts.count = count+1;
- subtitle_opts.map = g_malloc((count+1)*sizeof(options_map_t));
- }
- else
- {
- subtitle_opts.count = LANG_TABLE_SIZE+1;
- subtitle_opts.map = g_malloc((LANG_TABLE_SIZE+1)*sizeof(options_map_t));
- }
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- 0, _("Foreign Audio Search"),
- 1, TRUE,
- 2, "-1",
- 3, -1.0,
- 4, "auto",
- -1);
- subtitle_opts.map[0].option = "Foreign Audio Search";
- subtitle_opts.map[0].shortOpt = "-1";
- subtitle_opts.map[0].ivalue = -1;
- subtitle_opts.map[0].svalue = "auto";
- if (count > 0)
- {
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, _("Foreign Audio Search"),
+ 1, TRUE,
+ 2, "-1",
+ 3, -1.0,
+ 4, "auto",
+ -1);
+ subtitle_opts.map[0].option = "Foreign Audio Search";
+ subtitle_opts.map[0].shortOpt = "-1";
+ subtitle_opts.map[0].ivalue = -1;
+ subtitle_opts.map[0].svalue = "auto";
+
if (options != NULL)
g_strfreev(options);
options = g_malloc((count+1)*sizeof(gchar*));
@@ -2357,31 +2464,19 @@ subtitle_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex)
}
else
{
- index_str_init(LANG_TABLE_SIZE-1);
- for (ii = 0; ii < LANG_TABLE_SIZE; ii++)
- {
- const gchar *lang;
-
- if (ghb_language_table[ii].native_name[0] != 0)
- lang = ghb_language_table[ii].native_name;
- else
- lang = ghb_language_table[ii].eng_name;
-
- subtitle_opts.map[ii+1].option = (gchar*)lang;
- subtitle_opts.map[ii+1].shortOpt = index_str[ii];
- subtitle_opts.map[ii+1].ivalue = ii;
- subtitle_opts.map[ii+1].svalue = ghb_language_table[ii].iso639_2;
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- 0, lang,
- 1, TRUE,
- 2, index_str[ii],
- 3, (gdouble)ii,
- 4, ghb_language_table[ii].iso639_2,
- -1);
- }
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ 0, _("None"),
+ 1, TRUE,
+ 2, "0",
+ 3, 0.0,
+ 4, "none",
+ -1);
+ subtitle_opts.map[0].option = "None";
+ subtitle_opts.map[0].shortOpt = "0";
+ subtitle_opts.map[0].ivalue = 0;
+ subtitle_opts.map[0].svalue = "none";
}
- GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
gtk_combo_box_set_active (combo, 0);
}
@@ -2413,14 +2508,12 @@ ghb_longest_title()
}
const gchar*
-ghb_get_source_audio_lang(gint titleindex, gint track)
+ghb_get_source_audio_lang(hb_title_t *title, gint track)
{
- hb_title_t * title;
hb_audio_config_t * audio;
const gchar *lang = "und";
g_debug("ghb_lookup_1st_audio_lang ()\n");
- title = ghb_get_title_info( titleindex );
if (title == NULL)
return lang;
if (hb_list_count( title->list_audio ) <= track)
@@ -2434,236 +2527,26 @@ ghb_get_source_audio_lang(gint titleindex, gint track)
return lang;
}
-static gboolean*
-get_track_used(gint acodec, GHashTable *track_indices, gint count)
-{
- gboolean *used;
-
- used = g_hash_table_lookup(track_indices, &acodec);
- if (used == NULL)
- {
- gint *key;
-
- used = g_malloc0(count * sizeof(gboolean));
- key = g_malloc(sizeof(gint));
- *key = acodec;
- g_hash_table_insert(track_indices, key, used);
- }
- return used;
-}
-
gint
-ghb_find_audio_track(
- gint titleindex,
- const gchar *lang,
- gint acodec,
- gint fallback_acodec,
- GHashTable *track_indices)
+ghb_find_audio_track(hb_title_t *title, const gchar *lang, int start)
{
- hb_title_t * title;
hb_audio_config_t * audio;
- gint ii;
- gint count = 0;
- gint track = -1;
- gint max_chan;
- gboolean *used = NULL;
- gboolean *passthru_used;
- gint try_acodec;
- gint passthru_acodec;
- gboolean passthru;
- gint channels;
-
- g_debug("find_audio_track ()\n");
- title = ghb_get_title_info( titleindex );
+ gint ii, count = 0;
+
if (title != NULL)
{
- count = hb_list_count( title->list_audio );
+ count = hb_list_count(title->list_audio);
}
- if (count > 10) count = 10;
- // Try to find an item that matches the preferred language and
- // the passthru codec type
- max_chan = 0;
- passthru = (acodec & HB_ACODEC_PASS_FLAG) != 0;
- if (passthru)
- {
- for (ii = 0; ii < count; ii++)
- {
- audio = (hb_audio_config_t*)hb_list_audio_config_item(
- title->list_audio, ii );
- passthru_acodec = HB_ACODEC_PASS_MASK & acodec & audio->in.codec;
- // Is the source track use a passthru capable codec?
- if (passthru_acodec == 0)
- continue;
- used = get_track_used(passthru_acodec, track_indices, count);
- // Has the track already been used with this codec?
- if (used[ii])
- continue;
- channels = av_get_channel_layout_nb_channels(
- audio->in.channel_layout);
- // Find a track that is not visually impaired or dirctor's
- // commentary, and has the highest channel count.
- if ((audio->lang.type < 2) &&
- ((strcmp(lang, audio->lang.iso639_2) == 0) ||
- (strcmp(lang, "und") == 0)))
- {
- if (channels > max_chan)
- {
- track = ii;
- max_chan = channels;
- }
- }
- }
- try_acodec = fallback_acodec;
- }
- else
- {
- try_acodec = acodec;
- }
- if (track > -1)
- {
- used[track] = TRUE;
- return track;
- }
- // Try to find an item that matches the preferred language
- max_chan = 0;
- used = get_track_used(try_acodec, track_indices, count);
- for (ii = 0; ii < count; ii++)
- {
- // Has the track already been used with this codec?
- if (used[ii])
- continue;
- audio = (hb_audio_config_t*)hb_list_audio_config_item(
- title->list_audio, ii );
- passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
- if (passthru_acodec && passthru)
- {
- passthru_used = get_track_used(passthru_acodec, track_indices, count);
- // Has the track already been used with this codec for passthru?
- if (passthru_used[ii])
- continue;
- }
- channels = av_get_channel_layout_nb_channels(
- audio->in.channel_layout);
- // Find a track that is not visually impaired or dirctor's commentary
- if ((audio->lang.type < 2) &&
- ((strcmp(lang, audio->lang.iso639_2) == 0) ||
- (strcmp(lang, "und") == 0)))
- {
- if (channels > max_chan)
- {
- track = ii;
- max_chan = channels;
- }
- }
- }
- if (track > -1)
+ for (ii = start; ii < count; ii++)
{
- used[track] = TRUE;
- return track;
- }
- // Try to fine an item that does not match the preferred language and
- // matches the passthru codec type
- max_chan = 0;
- if (passthru)
- {
- for (ii = 0; ii < count; ii++)
+ audio = hb_list_audio_config_item(title->list_audio, ii);
+ if (!strcmp(lang, audio->lang.iso639_2) || !strcmp(lang, "und"))
{
- audio = (hb_audio_config_t*)hb_list_audio_config_item(
- title->list_audio, ii );
- passthru_acodec = HB_ACODEC_PASS_MASK & acodec & audio->in.codec;
- // Is the source track use a passthru capable codec?
- if (passthru_acodec == 0)
- continue;
- used = get_track_used(passthru_acodec, track_indices, count);
- // Has the track already been used with this codec?
- if (used[ii])
- continue;
-
- channels = av_get_channel_layout_nb_channels(
- audio->in.channel_layout);
- // Find a track that is not visually impaired or dirctor's
- // commentary, and has the highest channel count.
- if (audio->lang.type < 2)
- {
- if (channels > max_chan)
- {
- track = ii;
- max_chan = channels;
- }
- }
- }
- try_acodec = fallback_acodec;
- }
- else
- {
- try_acodec = acodec;
- }
- if (track > -1)
- {
- used[track] = TRUE;
- return track;
- }
- // Try to fine an item that does not match the preferred language
- max_chan = 0;
- used = get_track_used(try_acodec, track_indices, count);
- for (ii = 0; ii < count; ii++)
- {
- // Has the track already been used with this codec?
- if (used[ii])
- continue;
- audio = (hb_audio_config_t*)hb_list_audio_config_item(
- title->list_audio, ii );
- passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
- channels = av_get_channel_layout_nb_channels(
- audio->in.channel_layout);
- if (passthru_acodec && passthru)
- {
- passthru_used = get_track_used(passthru_acodec, track_indices, count);
- // Has the track already been used with this codec for passthru?
- if (passthru_used[ii])
- continue;
- }
- // Find a track that is not visually impaired or dirctor's commentary
- if (audio->lang.type < 2)
- {
- if (channels > max_chan)
- {
- track = ii;
- max_chan = channels;
- }
- }
- }
- if (track > -1)
- {
- used[track] = TRUE;
- return track;
- }
- // Last ditch, anything goes
- for (ii = 0; ii < count; ii++)
- {
- audio = (hb_audio_config_t*)hb_list_audio_config_item(
- title->list_audio, ii );
- passthru_acodec = HB_ACODEC_PASS_MASK & audio->in.codec;
- if (passthru_acodec && passthru)
- {
- passthru_used = get_track_used(passthru_acodec, track_indices, count);
- // Has the track already been used with this codec for passthru?
- if (passthru_used[ii])
- continue;
- }
- // Has the track already been used with this codec?
- if (!used[ii])
- {
- track = ii;
- break;
+ return ii;
}
}
- if (track > -1)
- {
- used[track] = TRUE;
- }
- return track;
+ return -1;
}
gint
@@ -2682,89 +2565,24 @@ ghb_find_pref_subtitle_track(const gchar *lang)
}
gint
-ghb_find_cc_track(gint titleindex)
+ghb_find_subtitle_track(hb_title_t * title, const gchar * lang, int start)
{
- hb_title_t * title;
hb_subtitle_t * subtitle;
gint count, ii;
-
- g_debug("ghb_find_cc_track ()\n");
- title = ghb_get_title_info( titleindex );
- if (title != NULL)
- {
- count = hb_list_count( title->list_subtitle );
- // Try to find an item that matches the preferred language
- for (ii = 0; ii < count; ii++)
- {
- subtitle = (hb_subtitle_t*)hb_list_item( title->list_subtitle, ii );
- if (subtitle->source == CC608SUB || subtitle->source == CC708SUB)
- return ii;
- }
- }
- return -2;
-}
-
-gint
-ghb_find_subtitle_track(
- gint titleindex,
- const gchar * lang,
- gboolean burn,
- gboolean force,
- gint source,
- GHashTable * track_indices)
-{
- hb_title_t * title;
- hb_subtitle_t * subtitle;
- gint count, ii;
- gboolean *used;
-
- g_debug("find_subtitle_track ()\n");
- if (strcmp(lang, "auto") == 0)
- return -1;
- title = ghb_get_title_info( titleindex );
- if (title == NULL)
- return -2;
-
- count = hb_list_count( title->list_subtitle );
- used = g_hash_table_lookup(track_indices, lang);
- if (used == NULL)
- {
- used = g_malloc0(count * sizeof(gboolean));
- g_hash_table_insert(track_indices, g_strdup(lang), used);
- }
- // Try to find an item that matches the preferred language and source
- for (ii = 0; ii < count; ii++)
- {
- if (used[ii])
- continue;
+ count = hb_list_count(title->list_subtitle);
- subtitle = (hb_subtitle_t*)hb_list_item( title->list_subtitle, ii );
- if (source == subtitle->source &&
- ((strcmp(lang, subtitle->iso639_2) == 0) ||
- (strcmp(lang, "und") == 0)))
- {
- used[ii] = TRUE;
- return ii;
- }
- }
// Try to find an item that matches the preferred language
- for (ii = 0; ii < count; ii++)
+ for (ii = start; ii < count; ii++)
{
- if (used[ii])
- continue;
-
subtitle = (hb_subtitle_t*)hb_list_item( title->list_subtitle, ii );
- if (((!force || (force && ghb_canForceSub(subtitle->source))) &&
- (!burn || (burn && ghb_canBurnSub(subtitle->source)))) &&
- ((strcmp(lang, subtitle->iso639_2) == 0) ||
- (strcmp(lang, "und") == 0)))
+ if (strcmp(lang, subtitle->iso639_2) == 0 ||
+ strcmp(lang, "und") == 0)
{
- used[ii] = TRUE;
return ii;
}
}
- return -2;
+ return -1;
}
static void
@@ -2776,13 +2594,14 @@ generic_opts_set(GtkBuilder *builder, const gchar *name, combo_opts_t *opts)
g_debug("generic_opts_set ()\n");
if (name == NULL || opts == NULL) return;
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
for (ii = 0; ii < opts->count; ii++)
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
- 0, _(opts->map[ii].option),
+ 0, gettext(opts->map[ii].option),
1, TRUE,
2, opts->map[ii].shortOpt,
3, opts->map[ii].ivalue,
@@ -2801,12 +2620,14 @@ small_opts_set(GtkBuilder *builder, const gchar *name, combo_opts_t *opts)
g_debug("small_opts_set ()\n");
if (name == NULL || opts == NULL) return;
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
for (ii = 0; ii < opts->count; ii++)
{
gtk_list_store_append(store, &iter);
- str = g_strdup_printf("<small>%s</small>", _(opts->map[ii].option));
+ str = g_strdup_printf("<small>%s</small>",
+ gettext(opts->map[ii].option));
gtk_list_store_set(store, &iter,
0, str,
1, TRUE,
@@ -2848,16 +2669,12 @@ ghb_lookup_combo_int(const gchar *name, const GValue *gval)
return lookup_mixdown_int(gval);
else if (strcmp(name, "SrtLanguage") == 0)
return lookup_audio_lang_int(gval);
- else if (strcmp(name, "PreferredLanguage") == 0)
- return lookup_audio_lang_int(gval);
else if (strcmp(name, "VideoEncoder") == 0)
return lookup_video_encoder_int(gval);
else if (strcmp(name, "AudioEncoder") == 0)
return lookup_audio_encoder_int(gval);
else if (strcmp(name, "AudioEncoderFallback") == 0)
return lookup_audio_encoder_int(gval);
- else if (strcmp(name, "AudioEncoderActual") == 0)
- return lookup_audio_encoder_int(gval);
else if (strcmp(name, "FileFormat") == 0)
return lookup_container_int(gval);
else
@@ -2883,16 +2700,12 @@ ghb_lookup_combo_double(const gchar *name, const GValue *gval)
return lookup_mixdown_int(gval);
else if (strcmp(name, "SrtLanguage") == 0)
return lookup_audio_lang_int(gval);
- else if (strcmp(name, "PreferredLanguage") == 0)
- return lookup_audio_lang_int(gval);
else if (strcmp(name, "VideoEncoder") == 0)
return lookup_video_encoder_int(gval);
else if (strcmp(name, "AudioEncoder") == 0)
return lookup_audio_encoder_int(gval);
else if (strcmp(name, "AudioEncoderFallback") == 0)
return lookup_audio_encoder_int(gval);
- else if (strcmp(name, "AudioEncoderActual") == 0)
- return lookup_audio_encoder_int(gval);
else if (strcmp(name, "FileFormat") == 0)
return lookup_container_int(gval);
else
@@ -2918,16 +2731,12 @@ ghb_lookup_combo_option(const gchar *name, const GValue *gval)
return lookup_mixdown_option(gval);
else if (strcmp(name, "SrtLanguage") == 0)
return lookup_audio_lang_option(gval);
- else if (strcmp(name, "PreferredLanguage") == 0)
- return lookup_audio_lang_option(gval);
else if (strcmp(name, "VideoEncoder") == 0)
return lookup_video_encoder_option(gval);
else if (strcmp(name, "AudioEncoder") == 0)
return lookup_audio_encoder_option(gval);
else if (strcmp(name, "AudioEncoderFallback") == 0)
return lookup_audio_encoder_option(gval);
- else if (strcmp(name, "AudioEncoderActual") == 0)
- return lookup_audio_encoder_option(gval);
else if (strcmp(name, "FileFormat") == 0)
return lookup_container_option(gval);
else
@@ -2953,16 +2762,12 @@ ghb_lookup_combo_string(const gchar *name, const GValue *gval)
return lookup_mixdown_string(gval);
else if (strcmp(name, "SrtLanguage") == 0)
return lookup_audio_lang_option(gval);
- else if (strcmp(name, "PreferredLanguage") == 0)
- return lookup_audio_lang_option(gval);
else if (strcmp(name, "VideoEncoder") == 0)
return lookup_video_encoder_string(gval);
else if (strcmp(name, "AudioEncoder") == 0)
return lookup_audio_encoder_string(gval);
else if (strcmp(name, "AudioEncoderFallback") == 0)
return lookup_audio_encoder_string(gval);
- else if (strcmp(name, "AudioEncoderActual") == 0)
- return lookup_audio_encoder_string(gval);
else if (strcmp(name, "FileFormat") == 0)
return lookup_container_string(gval);
else
@@ -2973,6 +2778,77 @@ ghb_lookup_combo_string(const gchar *name, const GValue *gval)
return NULL;
}
+#if 0
+static gboolean acodec_list_box_filter(GtkListBoxRow *row, gpointer data)
+{
+ GValue *settings = (GValue*)data;
+
+ int mux = ghb_settings_combo_int(settings, "FileFormat");
+
+ GtkWidget *label = gtk_bin_get_child(GTK_BIN(row));
+ int codec = (intptr_t)g_object_get_data(G_OBJECT(label), "codec");
+
+ const hb_encoder_t *enc;
+ for (enc = hb_audio_encoder_get_next(NULL); enc != NULL;
+ enc = hb_audio_encoder_get_next(enc))
+ {
+ if (enc->codec == codec && (mux & enc->muxers))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void ghb_update_acodec_list_box(GtkListBox *list_box)
+{
+ gtk_list_box_invalidate_filter(list_box);
+}
+
+void ghb_init_acodec_list_box(GtkListBox *list_box, GValue *settings)
+{
+ int mux = ghb_settings_combo_int(settings, "FileFormat");
+
+ const hb_encoder_t *enc;
+ for (enc = hb_audio_encoder_get_next(NULL); enc != NULL;
+ enc = hb_audio_encoder_get_next(enc))
+ {
+ if (mux & enc->muxers)
+ {
+ GtkWidget *label = gtk_label_new(enc->name);
+ g_object_set_data(G_OBJECT(label), "codec", (gpointer)(intptr_t)enc->codec);
+ gtk_widget_show(label);
+ gtk_list_box_insert(list_box, label, -1);
+ }
+ }
+ gtk_list_box_set_filter_func(list_box, acodec_list_box_filter,
+ settings, NULL);
+}
+#endif
+
+void ghb_init_lang_list_box(GtkListBox *list_box)
+{
+ int ii;
+
+ for (ii = 0; ii < LANG_TABLE_SIZE; ii++)
+ {
+ const char *lang;
+ if (ghb_language_table[ii].native_name != NULL &&
+ ghb_language_table[ii].native_name[0] != 0)
+ {
+ lang = ghb_language_table[ii].native_name;
+ }
+ else
+ {
+ lang = ghb_language_table[ii].eng_name;
+ }
+ GtkWidget *label = gtk_label_new(lang);
+ g_object_set_data(G_OBJECT(label), "lang_idx", (gpointer)(intptr_t)ii);
+ gtk_widget_show(label);
+ gtk_list_box_insert(list_box, label, -1);
+ }
+}
+
void
ghb_update_ui_combo_box(
signal_user_data_t *ud,
@@ -3014,12 +2890,13 @@ ghb_update_ui_combo_box(
audio_encoder_opts_set(ud->builder, "AudioEncoder");
acodec_fallback_opts_set(ud->builder, "AudioEncoderFallback");
language_opts_set(ud->builder, "SrtLanguage");
- language_opts_set(ud->builder, "PreferredLanguage");
srt_codeset_opts_set(ud->builder, "SrtCodeset");
title_opts_set(ud->builder, "title");
audio_track_opts_set(ud->builder, "AudioTrack", user_data);
subtitle_track_opts_set(ud->builder, "SubtitleTrack", user_data);
generic_opts_set(ud->builder, "VideoQualityGranularity", &vqual_granularity_opts);
+ generic_opts_set(ud->builder, "SubtitleTrackSelectionBehavior", &subtitle_track_sel_opts);
+ generic_opts_set(ud->builder, "AudioTrackSelectionBehavior", &audio_track_sel_opts);
generic_opts_set(ud->builder, "PtoPType", &point_to_point_opts);
generic_opts_set(ud->builder, "WhenComplete", &when_complete_opts);
generic_opts_set(ud->builder, "PicturePAR", &par_opts);
@@ -3062,8 +2939,6 @@ ghb_update_ui_combo_box(
acodec_fallback_opts_set(ud->builder, "AudioEncoderFallback");
else if (strcmp(name, "SrtLanguage") == 0)
language_opts_set(ud->builder, "SrtLanguage");
- else if (strcmp(name, "PreferredLanguage") == 0)
- language_opts_set(ud->builder, "PreferredLanguage");
else if (strcmp(name, "SrtCodeset") == 0)
srt_codeset_opts_set(ud->builder, "SrtCodeset");
else if (strcmp(name, "title") == 0)
@@ -3099,7 +2974,6 @@ init_ui_combo_boxes(GtkBuilder *builder)
init_combo_box(builder, "VideoFramerate");
init_combo_box(builder, "AudioMixdown");
init_combo_box(builder, "SrtLanguage");
- init_combo_box(builder, "PreferredLanguage");
init_combo_box(builder, "SrtCodeset");
init_combo_box(builder, "title");
init_combo_box(builder, "AudioTrack");
@@ -3354,38 +3228,68 @@ audio_bitrate_opts_add(GtkBuilder *builder, const gchar *name, gint rate)
if (rate >= 0 && rate < 8) return;
- if (ghb_audio_bitrates[ghb_abr_count].name)
+ if (ghb_custom_bitrate_str != NULL)
{
- g_free((char*)ghb_audio_bitrates[ghb_abr_count].name);
+ g_free(ghb_custom_bitrate_str);
}
- ghb_audio_bitrates[ghb_abr_count].rate = rate;
+ ghb_custom_bitrate = rate;
if (rate < 0)
{
- ghb_audio_bitrates[ghb_abr_count].name = g_strdup_printf("N/A");
+ ghb_custom_bitrate_str = g_strdup_printf("N/A");
}
else
{
- ghb_audio_bitrates[ghb_abr_count].name = g_strdup_printf("%d", rate);
+ ghb_custom_bitrate_str = g_strdup_printf("%d", rate);
}
- ghb_audio_bitrates_count = ghb_abr_count + 1;
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
if (!find_combo_item_by_int(GTK_TREE_MODEL(store), rate, &iter))
{
- str = g_strdup_printf ("<small>%s</small>",
- ghb_audio_bitrates[ghb_abr_count].name);
+ str = g_strdup_printf ("<small>%s</small>", ghb_custom_bitrate_str);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, str,
1, TRUE,
- 2, ghb_audio_bitrates[ghb_abr_count].name,
+ 2, ghb_custom_bitrate_str,
3, (gdouble)rate,
- 4, ghb_audio_bitrates[ghb_abr_count].name,
+ 4, ghb_custom_bitrate_str,
-1);
g_free(str);
}
}
+void
+ghb_audio_bitrate_opts_filter(
+ GtkComboBox *combo,
+ gint first_rate,
+ gint last_rate)
+{
+ GtkTreeIter iter;
+ GtkListStore *store;
+ gdouble ivalue;
+ gboolean done = FALSE;
+
+ g_debug("audio_bitrate_opts_filter ()\n");
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter))
+ {
+ do
+ {
+ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 3, &ivalue, -1);
+ if ((int)ivalue < first_rate || (int)ivalue > last_rate)
+ {
+ gtk_list_store_set(store, &iter, 1, FALSE, -1);
+ }
+ else
+ {
+ gtk_list_store_set(store, &iter, 1, TRUE, -1);
+ }
+ done = !gtk_tree_model_iter_next (GTK_TREE_MODEL(store), &iter);
+ } while (!done);
+ }
+}
+
static void
audio_bitrate_opts_update(
GtkBuilder *builder,
@@ -3398,91 +3302,85 @@ audio_bitrate_opts_update(
GtkListStore *store;
gdouble ivalue;
gboolean done = FALSE;
- gint ii = 0;
- guint last = (guint)last_rate;
- guint first = (guint)first_rate;
- ghb_audio_bitrates_count = ghb_abr_count;
-
g_debug("audio_bitrate_opts_clean ()\n");
- store = get_combo_box_store(builder, name);
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ ghb_audio_bitrate_opts_filter(combo, first_rate, last_rate);
+
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter))
{
do
{
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 3, &ivalue, -1);
- if (ivalue != first_rate && ivalue != last_rate &&
- !(ivalue == extra_rate && extra_rate >= first_rate) &&
- search_rates(
- ghb_audio_bitrates, ivalue, ghb_audio_bitrates_count) < 0)
+ if (!search_audio_bitrates(ivalue) && (ivalue != extra_rate))
{
done = !gtk_list_store_remove(store, &iter);
}
- else if ((int)ivalue < first || (int)ivalue > last)
- {
- ii++;
- gtk_list_store_set(store, &iter, 1, FALSE, -1);
- done = !gtk_tree_model_iter_next (GTK_TREE_MODEL(store), &iter);
- }
else
{
- ii++;
- gtk_list_store_set(store, &iter, 1, TRUE, -1);
- done = !gtk_tree_model_iter_next (GTK_TREE_MODEL(store), &iter);
+ done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
}
} while (!done);
}
- if (extra_rate >= first_rate)
+ if (extra_rate > 0 && !search_audio_bitrates(extra_rate))
+ {
audio_bitrate_opts_add(builder, name, extra_rate);
+ }
+ else
+ {
+ g_free(ghb_custom_bitrate_str);
+ ghb_custom_bitrate_str = NULL;
+ ghb_custom_bitrate = 0;
+ }
}
-static void
-audio_bitrate_opts_set(GtkBuilder *builder, const gchar *name)
+void
+ghb_audio_bitrate_opts_set(GtkComboBox *combo, gboolean extra)
{
GtkTreeIter iter;
GtkListStore *store;
- gint count = 0;
gchar *str;
- int ii;
- const hb_rate_t *rate;
-
- if (ghb_audio_bitrates == NULL)
- {
- // Count rates
- for (rate = hb_audio_bitrate_get_next(NULL); rate != NULL;
- rate = hb_audio_bitrate_get_next(rate))
- {
- count++;
- }
-
- ghb_audio_bitrates_count = ghb_abr_count = count;
- ghb_audio_bitrates = calloc(count+1, sizeof(hb_rate_t));
-
- for (ii = 0, rate = hb_audio_bitrate_get_next(NULL); rate != NULL;
- ii++, rate = hb_audio_bitrate_get_next(rate))
- {
- ghb_audio_bitrates[ii] = *rate;
- }
- }
-
g_debug("audio_bitrate_opts_set ()\n");
- store = get_combo_box_store(builder, name);
+ store = GTK_LIST_STORE(gtk_combo_box_get_model (combo));
gtk_list_store_clear(store);
- for (ii = 0; ii < ghb_audio_bitrates_count; ii++)
+
+ const hb_rate_t *rate;
+ for (rate = hb_audio_bitrate_get_next(NULL); rate != NULL;
+ rate = hb_audio_bitrate_get_next(rate))
{
gtk_list_store_append(store, &iter);
- str = g_strdup_printf ("<small>%s</small>",
- ghb_audio_bitrates[ii].name);
+ str = g_strdup_printf ("<small>%s</small>", rate->name);
gtk_list_store_set(store, &iter,
0, str,
1, TRUE,
- 2, ghb_audio_bitrates[ii].name,
- 3, (gdouble)ghb_audio_bitrates[ii].rate,
- 4, ghb_audio_bitrates[ii].name,
+ 2, rate->name,
+ 3, (gdouble)rate->rate,
+ 4, rate->name,
-1);
g_free(str);
}
+ if (extra && ghb_custom_bitrate_str != NULL)
+ {
+ gtk_list_store_append(store, &iter);
+ str = g_strdup_printf ("<small>%s</small>", ghb_custom_bitrate_str);
+ gtk_list_store_set(store, &iter,
+ 0, str,
+ 1, TRUE,
+ 2, ghb_custom_bitrate_str,
+ 3, (gdouble)ghb_custom_bitrate,
+ 4, ghb_custom_bitrate_str,
+ -1);
+ g_free(str);
+ }
+}
+
+static void
+audio_bitrate_opts_set(GtkBuilder *builder, const gchar *name)
+{
+ GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(builder, name));
+ ghb_audio_bitrate_opts_set(combo, TRUE);
}
void
@@ -4361,7 +4259,7 @@ ghb_validate_filters(GValue *settings)
if (!ghb_validate_filter_string(str, -1))
{
message = g_strdup_printf(
- N_("Invalid Decomb Settings:\n\n%s\n"),
+ _("Invalid Decomb Settings:\n\n%s\n"),
str);
ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
g_free(message);
@@ -5147,7 +5045,7 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
{
sub_config.dest = PASSTHRUSUB;
}
- else if ( burned && ghb_canBurnSub(subt->source) )
+ else if (burned && hb_subtitle_can_burn(subt->source))
{
// Only allow one subtitle to be burned into the video
if (one_burned)
diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h
index 7b514cf8d..9aaf94fcc 100644
--- a/gtk/src/hb-backend.h
+++ b/gtk/src/hb-backend.h
@@ -19,6 +19,7 @@
#include "settings.h"
#include "hb.h"
+#include "lang.h"
enum
{
@@ -120,18 +121,13 @@ void ghb_set_bitrate_opts(
void ghb_grey_combo_options(signal_user_data_t *ud);
void ghb_update_ui_combo_box(
signal_user_data_t *ud, const gchar *name, gint user_data, gboolean all);
-const gchar* ghb_get_source_audio_lang(gint titleindex, gint track);
-gint ghb_find_audio_track(
- gint titleindex, const gchar *lang, gint acodec,
- gint fallback_acodec, GHashTable *track_indices);
+const gchar* ghb_get_source_audio_lang(hb_title_t *title, gint track);
+gint ghb_find_audio_track(hb_title_t *title, const gchar *lang, int start);
const gchar* ghb_audio_track_description(gint track, int titleindex);
void ghb_add_all_subtitles(signal_user_data_t *ud, gint titleindex);
gint ghb_find_pref_subtitle_track(const gchar *lang);
-gint ghb_find_subtitle_track(
- gint titleindex, const gchar *lang, gboolean burn,
- gboolean force, gint source, GHashTable *track_indices);
+gint ghb_find_subtitle_track(hb_title_t * title, const gchar * lang, int start);
gint ghb_pick_subtitle_track(signal_user_data_t *ud);
-gint ghb_find_cc_track(gint titleindex);
gint ghb_longest_title(void);
gchar* ghb_build_advanced_opts_string(GValue *settings);
GdkPixbuf* ghb_get_preview_image(
@@ -158,4 +154,17 @@ gchar* ghb_get_tmp_dir();
gint ghb_find_closest_audio_samplerate(gint rate);
GValue* ghb_lookup_audio_encoder_value(gint val);
+void ghb_init_lang_list_box(GtkListBox *list_box);
+
+void ghb_init_combo_box(GtkComboBox *combo);
+void ghb_audio_encoder_opts_set(GtkComboBox *combo);
+void ghb_audio_bitrate_opts_set(GtkComboBox *combo, gboolean extra);
+void ghb_audio_bitrate_opts_filter(GtkComboBox *combo, gint first_rate, gint last_rate);
+void ghb_mix_opts_set(GtkComboBox *combo);
+void ghb_mix_opts_filter(GtkComboBox *combo, gint acodec);
+void ghb_audio_samplerate_opts_set(GtkComboBox *combo);
+
+int ghb_lookup_audio_lang(const GValue *glang);
+const iso639_lang_t* ghb_iso639_lookup_by_int(int idx);
+
#endif // _HBBACKEND_H_
diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml
index 7ac06d3e8..467880c9e 100644
--- a/gtk/src/internal_defaults.xml
+++ b/gtk/src/internal_defaults.xml
@@ -6,8 +6,6 @@
<dict>
<key>AudioTrackName</key>
<string></string>
- <key>AudioEncoderActual</key>
- <string></string>
<key>angle_count</key>
<integer>1</integer>
<key>angle</key>
@@ -215,10 +213,6 @@
<string>0.1</string>
<key>PreferredLanguage</key>
<string>und</string>
- <key>AudioDUB</key>
- <false />
- <key>NotAudioDUB</key>
- <true />
<key>constant_rate_factor</key>
<true />
<key>WhenComplete</key>
@@ -335,6 +329,10 @@
<true />
<key>AudioEncoderFallback</key>
<string>ffac3</string>
+ <key>AudioLanguageList</key>
+ <array>
+ <string>und</string>
+ </array>
<key>AudioList</key>
<array>
<dict>
@@ -342,10 +340,6 @@
<string>192</string>
<key>AudioEncoder</key>
<string>copy:ac3</string>
- <key>AudioTrack</key>
- <integer>1</integer>
- <key>AudioTrackDescription</key>
- <string></string>
<key>AudioTrackQualityEnable</key>
<false />
<key>AudioTrackQuality</key>
@@ -360,27 +354,28 @@
<string>source</string>
</dict>
</array>
+ <key>AudioSecondaryEncoderMode</key>
+ <true />
+ <key>AudioTrackSelectionBehavior</key>
+ <string>first</string>
<key>PresetDescription</key>
<string></string>
<key>PresetName</key>
<string>Name Missing</string>
<key>Type</key>
<integer>1</integer>
- <key>SubtitleList</key>
+ <key>SubtitleLanguageList</key>
<array>
- <dict>
- <key>SubtitleLanguage</key>
- <string>und</string>
- <key>SubtitleForced</key>
- <true />
- <key>SubtitleSource</key>
- <integer>0</integer>
- <key>SubtitleBurned</key>
- <true />
- <key>SubtitleDefaultTrack</key>
- <false />
- </dict>
+ <string>und</string>
</array>
+ <key>SubtitleTrackSelectionBehavior</key>
+ <string>none</string>
+ <key>SubtitleAddCC</key>
+ <false />
+ <key>SubtitleAddForeignAudioSearch</key>
+ <false />
+ <key>SubtitleAddForeignAudioSubtitle</key>
+ <false />
<key>VideoTurboTwoPass</key>
<false />
<key>UsesPictureFilters</key>
diff --git a/gtk/src/main.c b/gtk/src/main.c
index 04c43df6a..437540380 100644
--- a/gtk/src/main.c
+++ b/gtk/src/main.c
@@ -63,6 +63,8 @@
#include "icons.h"
#include "callbacks.h"
#include "queuehandler.h"
+#include "audiohandler.h"
+#include "subtitlehandler.h"
#include "x264handler.h"
#include "settings.h"
#include "resources.h"
@@ -112,7 +114,7 @@ create_builder_or_die(const gchar * name)
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
- _(markup),
+ gettext(markup),
name, error->message);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
@@ -274,7 +276,6 @@ bind_queue_tree_model(signal_user_data_t *ud)
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(column, _("Job Information"));
cell = gtk_cell_renderer_pixbuf_new();
- g_object_set(cell, "yalign", 0.0, NULL);
gtk_tree_view_column_pack_start(column, cell, FALSE);
gtk_tree_view_column_add_attribute(column, cell, "icon-name", 0);
textcell = gtk_cell_renderer_text_new();
@@ -287,7 +288,6 @@ bind_queue_tree_model(signal_user_data_t *ud)
gtk_tree_view_column_set_max_width(column, 550);
cell = custom_cell_renderer_button_new();
- g_object_set(cell, "yalign", 0.0, NULL);
column = gtk_tree_view_column_new_with_attributes(
_(""), cell, "icon-name", 2, NULL);
gtk_tree_view_column_set_min_width(column, 24);
@@ -307,161 +307,128 @@ bind_queue_tree_model(signal_user_data_t *ud)
}
extern G_MODULE_EXPORT void audio_list_selection_changed_cb(void);
+extern G_MODULE_EXPORT void audio_edit_clicked_cb(void);
+extern G_MODULE_EXPORT void audio_remove_clicked_cb(void);
// Create and bind the tree model to the tree view for the audio track list
// Also, connect up the signal that lets us know the selection has changed
static void
bind_audio_tree_model(signal_user_data_t *ud)
{
- GtkCellRenderer *cell;
+ GtkCellRenderer *source_cell;
+ GtkCellRenderer *arrow_cell;
+ GtkCellRenderer *output_cell;
+ GtkCellRenderer *edit_cell;
+ GtkCellRenderer *delete_cell;
GtkTreeViewColumn *column;
- GtkListStore *treestore;
+ GtkTreeStore *treestore;
GtkTreeView *treeview;
GtkTreeSelection *selection;
- GtkWidget *widget;
g_debug("bind_audio_tree_model()\n");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
selection = gtk_tree_view_get_selection(treeview);
- // 12 columns in model. 6 are visible, the other 6 are for storing
- // values that I need
- treestore = gtk_list_store_new(7, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ treestore = gtk_tree_store_new(6, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_FLOAT);
gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(treestore));
- cell = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Track"), cell, "text", 0, NULL);
- gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- gtk_tree_view_column_set_min_width(column, 200);
- gtk_tree_view_column_set_max_width(column, 200);
+ source_cell = gtk_cell_renderer_text_new();
+ arrow_cell = gtk_cell_renderer_text_new();
+ output_cell = gtk_cell_renderer_text_new();
+ edit_cell = custom_cell_renderer_button_new();
+ delete_cell = custom_cell_renderer_button_new();
- cell = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Codec"), cell, "text", 1, NULL);
- gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- gtk_tree_view_column_set_min_width(column, 110);
-
- cell = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Bitrate"), cell, "text", 2, NULL);
- gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- gtk_tree_view_column_set_min_width(column, 50);
-
- cell = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Sample Rate"), cell, "text", 3, NULL);
- gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- gtk_tree_view_column_set_min_width(column, 100);
-
- cell = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Mix"), cell, "text", 4, NULL);
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_spacing(column, 12);
+ gtk_tree_view_column_set_title(column, _("Track Information"));
+ gtk_tree_view_column_pack_start(column, source_cell, FALSE);
+ gtk_tree_view_column_add_attribute(column, source_cell, "text", 0);
+ gtk_tree_view_column_add_attribute(column, source_cell, "yalign", 5);
+ gtk_tree_view_column_pack_start(column, arrow_cell, FALSE);
+ gtk_tree_view_column_add_attribute(column, arrow_cell, "text", 1);
+ gtk_tree_view_column_pack_start(column, output_cell, TRUE);
+ gtk_tree_view_column_add_attribute(column, output_cell, "markup", 2);
+ gtk_tree_view_column_add_attribute(column, output_cell, "yalign", 5);
gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- gtk_tree_view_column_set_min_width(column, 115);
+ gtk_tree_view_column_set_expand(column, TRUE);
- cell = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
- _("Gain"), cell, "text", 5, NULL);
+ _(""), edit_cell, "icon-name", 3, NULL);
+ //gtk_tree_view_column_set_min_width(column, 24);
gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- cell = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
- _("DRC"), cell, "text", 6, NULL);
+ _(""), delete_cell, "icon-name", 4, NULL);
+ //gtk_tree_view_column_set_min_width(column, 24);
gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
g_signal_connect(selection, "changed", audio_list_selection_changed_cb, ud);
- // Need to disable remove and update buttons since there are initially
- // no selections
- widget = GHB_WIDGET(ud->builder, "audio_remove");
- gtk_widget_set_sensitive(widget, FALSE);
+ g_signal_connect(edit_cell, "clicked", audio_edit_clicked_cb, ud);
+ g_signal_connect(delete_cell, "clicked", audio_remove_clicked_cb, ud);
+
g_debug("Done\n");
}
extern G_MODULE_EXPORT void subtitle_list_selection_changed_cb(void);
-extern G_MODULE_EXPORT void subtitle_forced_toggled_cb(void);
-extern G_MODULE_EXPORT void subtitle_burned_toggled_cb(void);
-extern G_MODULE_EXPORT void subtitle_default_toggled_cb(void);
+extern G_MODULE_EXPORT void subtitle_edit_clicked_cb(void);
+extern G_MODULE_EXPORT void subtitle_remove_clicked_cb(void);
// Create and bind the tree model to the tree view for the subtitle track list
// Also, connect up the signal that lets us know the selection has changed
static void
bind_subtitle_tree_model(signal_user_data_t *ud)
{
- GtkCellRenderer *cell;
+ GtkCellRenderer *source_cell;
+ GtkCellRenderer *arrow_cell;
+ GtkCellRenderer *output_cell;
+ GtkCellRenderer *edit_cell;
+ GtkCellRenderer *delete_cell;
GtkTreeViewColumn *column;
- GtkListStore *treestore;
+ GtkTreeStore *treestore;
GtkTreeView *treeview;
GtkTreeSelection *selection;
- GtkWidget *widget;
g_debug("bind_subtitle_tree_model()\n");
treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
selection = gtk_tree_view_get_selection(treeview);
- // 6 columns in model. 5 are visible, the other 1 is for storing
- // values that I need
- // Track, force, burn, default, type, srt offset, track short, source
- // force visible, burn visible, offset visible
- treestore = gtk_list_store_new(10,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN,
- G_TYPE_INT, G_TYPE_STRING,
- G_TYPE_INT,
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN);
+ treestore = gtk_tree_store_new(6, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_FLOAT);
gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(treestore));
- cell = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Track"), cell, "text", 0, NULL);
- widget = GHB_WIDGET(ud->builder, "SubTrackLabel");
- gtk_tree_view_column_set_widget(column, widget);
- gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- gtk_tree_view_column_set_min_width(column, 350);
- gtk_tree_view_column_set_max_width(column, 350);
-
- cell = gtk_cell_renderer_toggle_new();
- column = gtk_tree_view_column_new_with_attributes(
- _("Forced Only"), cell, "active", 1, "visible", 7, NULL);
- widget = GHB_WIDGET(ud->builder, "SubForcedLabel");
- gtk_tree_view_column_set_widget(column, widget);
- gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- g_signal_connect(cell, "toggled", subtitle_forced_toggled_cb, ud);
+ source_cell = gtk_cell_renderer_text_new();
+ arrow_cell = gtk_cell_renderer_text_new();
+ output_cell = gtk_cell_renderer_text_new();
+ edit_cell = custom_cell_renderer_button_new();
+ delete_cell = custom_cell_renderer_button_new();
- cell = gtk_cell_renderer_toggle_new();
- gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(cell), TRUE);
- column = gtk_tree_view_column_new_with_attributes(
- _("Burned In"), cell, "active", 2, "visible", 8, NULL);
- widget = GHB_WIDGET(ud->builder, "SubBurnedLabel");
- gtk_tree_view_column_set_widget(column, widget);
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_spacing(column, 12);
+ gtk_tree_view_column_set_title(column, _("Track Information"));
+ gtk_tree_view_column_pack_start(column, source_cell, FALSE);
+ gtk_tree_view_column_add_attribute(column, source_cell, "text", 0);
+ gtk_tree_view_column_add_attribute(column, source_cell, "yalign", 5);
+ gtk_tree_view_column_pack_start(column, arrow_cell, FALSE);
+ gtk_tree_view_column_add_attribute(column, arrow_cell, "text", 1);
+ gtk_tree_view_column_pack_start(column, output_cell, TRUE);
+ gtk_tree_view_column_add_attribute(column, output_cell, "markup", 2);
+ gtk_tree_view_column_add_attribute(column, output_cell, "yalign", 5);
gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- g_signal_connect(cell, "toggled", subtitle_burned_toggled_cb, ud);
+ gtk_tree_view_column_set_expand(column, TRUE);
+ gtk_tree_view_column_set_max_width(column, 400);
- cell = gtk_cell_renderer_toggle_new();
- gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(cell), TRUE);
column = gtk_tree_view_column_new_with_attributes(
- _("Default"), cell, "active", 3, NULL);
- widget = GHB_WIDGET(ud->builder, "SubDefaultLabel");
- gtk_tree_view_column_set_widget(column, widget);
+ _(""), edit_cell, "icon-name", 3, NULL);
gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
- g_signal_connect(cell, "toggled", subtitle_default_toggled_cb, ud);
- cell = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
- _("Srt Offset"), cell, "text", 4, "visible", 9, NULL);
- widget = GHB_WIDGET(ud->builder, "SubSRTOffsetLabel");
- gtk_tree_view_column_set_widget(column, widget);
+ _(""), delete_cell, "icon-name", 4, NULL);
gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
-
g_signal_connect(selection, "changed", subtitle_list_selection_changed_cb, ud);
- // Need to disable remove and update buttons since there are initially
- // no selections
- widget = GHB_WIDGET(ud->builder, "subtitle_remove");
- gtk_widget_set_sensitive(widget, FALSE);
- g_debug("Done\n");
+ g_signal_connect(edit_cell, "clicked", subtitle_edit_clicked_cb, ud);
+ g_signal_connect(delete_cell, "clicked", subtitle_remove_clicked_cb, ud);
}
extern G_MODULE_EXPORT void presets_list_selection_changed_cb(void);
@@ -734,11 +701,18 @@ G_MODULE_EXPORT void preview_hud_size_alloc_cb(GtkWidget *widget, signal_user_da
#if GTK_CHECK_VERSION(3, 0, 0)
const gchar *MyCSS =
" \n\
+GtkRadioButton .button { \n\
+ border-width: 0px; \n\
+ padding: 0px; \n\
+} \n\
GtkComboBox { \n\
- padding: 1px; \n\
+ padding: 0px; \n\
+} \n\
+GtkComboBox .button { \n\
+ padding: 2px; \n\
} \n\
GtkEntry { \n\
- padding: 4px; \n\
+ padding: 0px 4px; \n\
} \n\
\n\
@define-color black #000000; \n\
@@ -1028,11 +1002,16 @@ main(int argc, char *argv[])
while (x264_presets && x264_presets[count]) count++;
gtk_range_set_range(GTK_RANGE(presetSlider), 0, count-1);
+ ghb_init_audio_defaults_ui(ud);
+ ghb_init_subtitle_defaults_ui(ud);
+
// Load all internal settings
ghb_settings_init(ud);
+ // Load prefs before presets. Some preset defaults may depend
+ // on preference settings.
+ ghb_prefs_load(ud);
// Load the presets files
ghb_presets_load(ud);
- ghb_prefs_load(ud);
ghb_prefs_to_ui(ud);
@@ -1132,8 +1111,6 @@ main(int argc, char *argv[])
widget = GHB_WIDGET(ud->builder, "srt_code_label");
gtk_widget_get_preferred_size( widget, &min_size, &size );
height += MAX(min_size.height, size.height);
- widget = GHB_WIDGET(ud->builder, "subtitle_table");
- gtk_widget_set_size_request(widget, -1, height);
#else
GtkRequisition size;
@@ -1143,8 +1120,6 @@ main(int argc, char *argv[])
widget = GHB_WIDGET(ud->builder, "srt_code_label");
gtk_widget_size_request( widget, &size );
height += size.height;
- widget = GHB_WIDGET(ud->builder, "subtitle_table");
- gtk_widget_set_size_request(widget, -1, height);
#endif
widget = GHB_WIDGET(ud->builder, "hb_window");
diff --git a/gtk/src/makedeps.py b/gtk/src/makedeps.py
index c0f791d1c..40ea364d4 100644
--- a/gtk/src/makedeps.py
+++ b/gtk/src/makedeps.py
@@ -48,22 +48,17 @@ dep_map = (
DepEntry("VideoEncoder", "x264_tab", "x264", False, True),
DepEntry("VideoEncoder", "x264VideoSettings", "x264", False, True),
DepEntry("VideoEncoder", "lavc_mpeg4_tab", "mpeg4|mpeg2", False, True),
- DepEntry("AudioTrackQualityEnable", "AudioBitrateLabel", "TRUE", True, False),
- DepEntry("AudioTrackQualityEnable", "AudioBitrate", "TRUE", True, False),
- DepEntry("AudioEncoderActual", "AudioBitrateLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioBitrate", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioSamplerateLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioSamplerate", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioMixdownLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioMixdown", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioTrackGainLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioTrackGain", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoderActual", "AudioTrackGainValue", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
- DepEntry("AudioEncoder", "AudioAllowMP3Pass", "copy", False, False),
- DepEntry("AudioEncoder", "AudioAllowAACPass", "copy", False, False),
- DepEntry("AudioEncoder", "AudioAllowAC3Pass", "copy", False, False),
- DepEntry("AudioEncoder", "AudioAllowDTSPass", "copy", False, False),
- DepEntry("AudioEncoder", "AudioAllowDTSHDPass", "copy", False, False),
+ DepEntry("AudioTrackQualityEnable", "AudioBitrate", "TRUE", True, True),
+ DepEntry("AudioTrackQualityEnable", "AudioTrackQualityBox", "FALSE", True, True),
+ DepEntry("AudioEncoder", "AudioBitrateLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioBitrate", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioSamplerateLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioSamplerate", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioMixdownLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioMixdown", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioTrackGainLabel", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioTrackGain", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
+ DepEntry("AudioEncoder", "AudioTrackGainValue", "copy:mp3|copy:aac|copy:ac3|copy:dts|copy:dtshd", True, False),
DepEntry("x264_bframes", "x264_bpyramid", "<2", True, False),
DepEntry("x264_bframes", "x264_direct", "0", True, False),
DepEntry("x264_bframes", "x264_b_adapt", "0", True, False),
diff --git a/gtk/src/presets.c b/gtk/src/presets.c
index 3b374375b..81d610cba 100644
--- a/gtk/src/presets.c
+++ b/gtk/src/presets.c
@@ -807,9 +807,9 @@ init_settings_from_array(
else
init_settings_from_array(new_array, gval, gval);
}
- else
+ else if (val != NULL)
{
- ghb_array_append(dest, val);
+ ghb_array_append(dest, ghb_value_dup(val));
}
}
}
@@ -1581,7 +1581,7 @@ ghb_prefs_load(signal_user_data_t *ud)
GValue *dict, *internal;
GHashTableIter iter;
gchar *key;
- GValue *gval, *path;
+ GValue *gval;
g_debug("ghb_prefs_load");
prefsPlist = load_plist("preferences");
@@ -1636,32 +1636,6 @@ ghb_prefs_load(signal_user_data_t *ud)
#endif
store_prefs();
}
- // Read legacy default_preset preference and update accordingly
- path = ghb_dict_lookup(dict, "default_preset");
- if (path)
- {
- gint *indices, len;
-
- if (G_VALUE_TYPE(path) == G_TYPE_STRING)
- {
- GValue *str = path;
-
- path = ghb_array_value_new(1);
- ghb_array_append(path, ghb_value_dup(str));
- indices = ghb_preset_indices_from_path(presetsPlist, path, &len);
- ghb_value_free(path);
- }
- else
- indices = ghb_preset_indices_from_path(presetsPlist, path, &len);
-
- if (indices)
- {
- presets_set_default(indices, len);
- g_free(indices);
- }
- ghb_dict_remove(dict, "default_preset");
- store_prefs();
- }
}
static const gchar*
@@ -2057,6 +2031,7 @@ value_map_t decomb_xlat[] =
{NULL, NULL}
};
+#if 0
extern iso639_lang_t ghb_language_table[];
static GValue*
@@ -2091,30 +2066,6 @@ export_lang_xlat2(GValue *lin_val)
}
static GValue*
-export_subtitle_xlat2(GValue *lin_val)
-{
- gchar *str;
- GValue *gval;
-
- if (lin_val == NULL) return NULL;
- str = ghb_value_string(lin_val);
- if (strcmp(str, "none") == 0)
- {
- gval = ghb_string_value_new("None");
- }
- else if (strcmp(str, "auto") == 0)
- {
- gval = ghb_string_value_new("Autoselect");
- }
- else
- {
- gval = export_lang_xlat2(lin_val);
- }
- g_free(str);
- return gval;
-}
-
-static GValue*
import_lang_xlat2(GValue *mac_val)
{
GValue *gval;
@@ -2138,74 +2089,7 @@ import_lang_xlat2(GValue *mac_val)
g_free(str);
return NULL;
}
-
-static GValue*
-import_subtitle_xlat2(GValue *mac_val)
-{
- gchar *str;
- GValue *gval;
-
- if (mac_val == NULL) return NULL;
- str = ghb_value_string(mac_val);
- if (strcmp(str, "None") == 0)
- {
- gval = ghb_string_value_new("none");
- }
- else if (strcmp(str, "Autoselect") == 0)
- {
- gval = ghb_string_value_new("auto");
- }
- else
- {
- gval = import_lang_xlat2(mac_val);
- }
- g_free(str);
- return gval;
-}
-
-static GValue*
-export_audio_track_xlat2(GValue *lin_val)
-{
- gchar *str;
- GValue *gval = NULL;
-
- if (lin_val == NULL) return NULL;
- str = ghb_value_string(lin_val);
- if (strcmp(str, "none") == 0)
- {
- gval = ghb_int_value_new(1);
- }
- else
- {
- gint val = ghb_value_int(lin_val) + 1;
- gval = ghb_int_value_new(val);
- }
- g_free(str);
- return gval;
-}
-
-static GValue*
-import_audio_track_xlat2(GValue *mac_val)
-{
- gint val;
- gchar *str;
- GValue *gval;
-
- if (mac_val == NULL) return NULL;
- val = ghb_value_int(mac_val);
- if (val <= 0)
- {
- val = 0;
- }
- else
- {
- val--;
- }
- str = g_strdup_printf("%d", val);
- gval = ghb_string_value_new(str);
- g_free(str);
- return gval;
-}
+#endif
static GValue*
export_value_xlat2(value_map_t *value_map, GValue *lin_val, GType mac_type)
@@ -2379,22 +2263,7 @@ export_value_xlat(GValue *dict)
if (gval)
ghb_dict_insert(dict, g_strdup(key), gval);
- GValue *slist;
- GValue *sdict;
gint count, ii;
-
- slist = ghb_dict_lookup(dict, "SubtitleList");
- count = ghb_array_len(slist);
- for (ii = 0; ii < count; ii++)
- {
- sdict = ghb_array_get_nth(slist, ii);
- key = "SubtitleLanguage";
- lin_val = ghb_dict_lookup(sdict, key);
- gval = export_subtitle_xlat2(lin_val);
- if (gval)
- ghb_dict_insert(sdict, g_strdup(key), gval);
- }
-
GValue *alist;
GValue *adict;
@@ -2409,11 +2278,6 @@ export_value_xlat(GValue *dict)
for (ii = 0; ii < count; ii++)
{
adict = ghb_array_get_nth(alist, ii);
- key = "AudioTrack";
- lin_val = ghb_dict_lookup(adict, key);
- gval = export_audio_track_xlat2(lin_val);
- if (gval)
- ghb_dict_insert(adict, g_strdup(key), gval);
key = "AudioEncoder";
lin_val = ghb_dict_lookup(adict, key);
gval = export_value_audio_encoder(lin_val);
@@ -2649,75 +2513,10 @@ import_value_xlat(GValue *dict)
if (gval)
ghb_dict_insert(dict, g_strdup(key), gval);
- GValue *sdeflist;
- GValue *slist;
- GValue *sdict;
- gint count, ii;
-
- sdeflist = ghb_dict_lookup(defaults, "SubtitleList");
- if (sdeflist)
- {
- slist = ghb_dict_lookup(dict, "SubtitleList");
- if (slist)
- {
- count = ghb_array_len(slist);
- for (ii = 0; ii < count; ii++)
- {
- sdict = ghb_array_get_nth(slist, ii);
- key = "SubtitleLanguage";
- mac_val = ghb_dict_lookup(sdict, key);
- gval = import_subtitle_xlat2(mac_val);
- if (gval)
- ghb_dict_insert(sdict, g_strdup(key), gval);
- }
-
- }
- else
- {
- key = "Subtitles";
- mac_val = ghb_dict_lookup(dict, key);
- slist = ghb_array_value_new(8);
- ghb_dict_insert(dict, g_strdup("SubtitleList"), slist);
- if (mac_val)
- {
- gchar *lang;
-
- gval = import_subtitle_xlat2(mac_val);
- lang = ghb_value_string(gval);
- if (lang && strcasecmp(lang, "none") != 0 && !slist)
- {
- sdict = ghb_dict_value_new();
- ghb_array_append(slist, sdict);
- ghb_dict_insert(sdict, g_strdup("SubtitleLanguage"), gval);
- gval = ghb_dict_lookup(dict, "SubtitlesForced");
- if (gval != NULL)
- {
- ghb_dict_insert(sdict, g_strdup("SubtitleForced"),
- ghb_value_dup(gval));
- }
- else
- {
- ghb_dict_insert(sdict, g_strdup("SubtitleForced"),
- ghb_boolean_value_new(FALSE));
- }
- ghb_dict_insert(sdict, g_strdup("SubtitleBurned"),
- ghb_boolean_value_new(TRUE));
- ghb_dict_insert(sdict, g_strdup("SubtitleDefaultTrack"),
- ghb_boolean_value_new(FALSE));
- }
- else
- {
- ghb_value_free(gval);
- }
- if (lang)
- g_free(lang);
- }
- }
- }
ghb_dict_remove(dict, "Subtitles");
ghb_dict_remove(dict, "SubtitlesForced");
-
+ gint count, ii;
GValue *alist;
GValue *adict;
GValue *adefaults;
@@ -2738,11 +2537,6 @@ import_value_xlat(GValue *dict)
for (ii = 0; ii < count; ii++)
{
adict = ghb_array_get_nth(alist, ii);
- key = "AudioTrack";
- mac_val = ghb_dict_lookup(adict, key);
- gval = import_audio_track_xlat2(mac_val);
- if (gval)
- ghb_dict_insert(adict, g_strdup(key), gval);
key = "AudioEncoder";
mac_val = ghb_dict_lookup(adict, key);
gval = import_value_audio_encoder(mac_val);
@@ -2789,7 +2583,6 @@ import_xlat_preset(GValue *dict)
gint vqtype;
g_debug("import_xlat_preset ()");
-
uses_max = ghb_value_boolean(
preset_dict_get_value(dict, "UsesMaxPictureSettings"));
uses_pic = ghb_value_int(
@@ -2862,6 +2655,75 @@ import_xlat_preset(GValue *dict)
} break;
}
+ // Initialize the AudioLanguageList from preferences PreferredLanguage
+ // and translate old AudioDUB preference option if found
+ GValue *list = ghb_dict_lookup(dict, "AudioLanguageList");
+ if (list == NULL)
+ {
+ list = ghb_array_value_new(8);
+ ghb_dict_insert(dict, g_strdup("AudioLanguageList"), list);
+ }
+ if (ghb_array_len(list) == 0)
+ {
+ GValue *prefs = plist_get_dict(prefsPlist, "Preferences");
+ GValue *gdub = ghb_dict_lookup(prefs, "AudioDUB");
+ GValue *glang = ghb_dict_lookup(prefs, "PreferredLanguage");
+ const char *lang = NULL;
+ if (glang != NULL)
+ {
+ lang = g_value_get_string(glang);
+ }
+ if (gdub != NULL && !ghb_value_boolean(gdub))
+ {
+ if (lang == NULL || strncmp(lang, "und", 4))
+ {
+ ghb_array_append(list, ghb_string_value_new("und"));
+ }
+ }
+ if (glang != NULL)
+ {
+ ghb_array_append(list, ghb_value_dup(glang));
+ }
+ }
+
+ // Initialize the SubtitleLanguageList from preferences PreferredLanguage
+ // and translate old AudioDUB preference option if found
+ list = ghb_dict_lookup(dict, "SubtitleLanguageList");
+ if (list == NULL)
+ {
+ list = ghb_array_value_new(8);
+ ghb_dict_insert(dict, g_strdup("SubtitleLanguageList"), list);
+ }
+ if (ghb_array_len(list) == 0)
+ {
+ GValue *prefs = plist_get_dict(prefsPlist, "Preferences");
+ GValue *val = ghb_dict_lookup(prefs, "PreferredLanguage");
+ if (val != NULL)
+ {
+ ghb_array_append(list, ghb_value_dup(val));
+
+ val = ghb_dict_lookup(prefs, "AudioDUB");
+ if (val != NULL && !ghb_value_boolean(val))
+ {
+ ghb_dict_insert(dict,
+ g_strdup("SubtitleAddForeignAudioSubtitle"),
+ ghb_boolean_value_new(TRUE));
+ }
+ }
+ }
+
+ GValue *addCC = ghb_dict_lookup(dict, "SubtitleAddCC");
+ if (addCC == NULL)
+ {
+ GValue *prefs = plist_get_dict(prefsPlist, "Preferences");
+ GValue *val = ghb_dict_lookup(prefs, "AddCC");
+ if (val != NULL)
+ {
+ ghb_dict_insert(dict, g_strdup("SubtitleAddCC"),
+ ghb_value_dup(val));
+ }
+ }
+
import_value_xlat(dict);
GValue *mode = ghb_dict_lookup(dict, "VideoFramerateMode");
@@ -3665,16 +3527,6 @@ ghb_presets_list_clear_default(signal_user_data_t *ud)
}
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, "AudioList", audio_list);
-}
-
-static void
update_subtitle_presets(signal_user_data_t *ud)
{
g_debug("update_subtitle_presets");
@@ -4037,8 +3889,6 @@ presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
ghb_widget_to_setting(ud->settings, GTK_WIDGET(desc));
- // Construct the audio settings presets from the current audio list
- update_audio_presets(ud);
update_subtitle_presets(ud);
settings_save(ud, dest);
ghb_value_free(dest);
@@ -4502,6 +4352,8 @@ ghb_refresh_preset(signal_user_data_t *ud)
ghb_set_preset_from_indices(ud, indices, len);
gint titleindex;
titleindex = ghb_settings_combo_int(ud->settings, "title");
+ ghb_audio_def_settings_init(ud);
+ ghb_subtitle_def_settings_init(ud);
ghb_set_pref_audio_settings(titleindex, ud->settings);
ghb_set_pref_audio_from_settings(ud, ud->settings);
ghb_set_pref_subtitle(titleindex, ud);
@@ -4579,6 +4431,8 @@ presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_
ghb_set_preset_from_indices(ud, indices, len);
gint titleindex;
titleindex = ghb_settings_combo_int(ud->settings, "title");
+ ghb_audio_def_settings_init(ud);
+ ghb_subtitle_def_settings_init(ud);
ghb_set_pref_audio_settings(titleindex, ud->settings);
ghb_set_pref_audio_from_settings(ud, ud->settings);
ghb_set_pref_subtitle(titleindex, ud);
diff --git a/gtk/src/queuehandler.c b/gtk/src/queuehandler.c
index f02195673..5c45eebb8 100644
--- a/gtk/src/queuehandler.c
+++ b/gtk/src/queuehandler.c
@@ -417,12 +417,12 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
asettings = ghb_array_get_nth(audio_list, ii);
- acodec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
+ acodec = ghb_settings_combo_option(asettings, "AudioEncoder");
double q = ghb_settings_get_double(asettings, "AudioTrackQuality");
if (ghb_settings_get_boolean(asettings, "AudioTrackQualityEnable") &&
q != HB_INVALID_AUDIO_QUALITY)
{
- int codec = ghb_settings_combo_int(asettings, "AudioEncoderActual");
+ int codec = ghb_settings_combo_int(asettings, "AudioEncoder");
quality = ghb_format_quality("Quality: ", codec, q);
}
else
@@ -715,7 +715,7 @@ queue_add_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
if (!ghb_queue_add(ud, settings, 0))
ghb_value_free(settings);
// Validation of settings may have changed audio list
- ghb_audio_list_refresh(ud);
+ ghb_audio_list_refresh_all(ud);
}
G_MODULE_EXPORT void
@@ -1196,7 +1196,7 @@ queue_start_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
return;
}
// Validation of settings may have changed audio list
- ghb_audio_list_refresh(ud);
+ ghb_audio_list_refresh_all(ud);
}
if (state == GHB_STATE_IDLE)
{
diff --git a/gtk/src/settings.c b/gtk/src/settings.c
index ee68f74f6..5acee1ece 100644
--- a/gtk/src/settings.c
+++ b/gtk/src/settings.c
@@ -190,6 +190,10 @@ ghb_get_setting_key(GtkWidget *widget)
if (name == NULL)
{
+ name = gtk_widget_get_name(widget);
+ }
+ if (name == NULL)
+ {
// Bad widget pointer? Should never happen.
g_debug("Bad widget\n");
return NULL;
@@ -415,26 +419,6 @@ ghb_widget_boolean(GtkWidget *widget)
return bval;
}
-static void check_radio_consistency(GValue *settings, GtkWidget *widget)
-{
- const gchar *key = NULL;
- GValue *value;
-
- if (widget == NULL) return;
- if (G_OBJECT_TYPE(widget) == GTK_TYPE_RADIO_BUTTON)
- {
- // Find corresponding setting
- key = ghb_get_setting_key(widget);
- if (key == NULL) return;
- value = ghb_widget_value(widget);
- if (value == NULL) return;
- if (ghb_value_boolean(value) == ghb_settings_get_boolean(settings, key))
- {
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget), FALSE);
- }
- }
-}
-
void
ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
{
@@ -449,7 +433,6 @@ ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
value = ghb_widget_value(widget);
if (value != NULL)
{
- check_radio_consistency(settings, widget);
ghb_settings_take_value(settings, key, value);
}
else
@@ -458,15 +441,15 @@ ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
}
}
-static void
-update_widget(GtkWidget *widget, const GValue *value)
+void
+ghb_update_widget(GtkWidget *widget, const GValue *value)
{
GType type;
gchar *str;
gint ival;
gdouble dval;
- g_debug("update_widget");
+ g_debug("ghb_update_widget");
type = G_VALUE_TYPE(value);
if (type == ghb_array_get_type() || type == ghb_dict_get_type())
return;
@@ -475,6 +458,7 @@ update_widget(GtkWidget *widget, const GValue *value)
ival = ghb_value_int(value);
dval = ghb_value_double(value);
type = G_OBJECT_TYPE(widget);
+
if (type == GTK_TYPE_ENTRY)
{
g_debug("entry");
@@ -483,16 +467,7 @@ update_widget(GtkWidget *widget, const GValue *value)
else if (type == GTK_TYPE_RADIO_BUTTON)
{
g_debug("radio button");
- int cur_val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- if (cur_val && !ival)
- {
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget), TRUE);
- }
- else
- {
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(widget), FALSE);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
- }
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), !!ival);
}
else if (type == GTK_TYPE_CHECK_BUTTON)
{
@@ -666,7 +641,7 @@ ghb_ui_update_from_settings(GtkBuilder *builder, const gchar *name, const GValue
g_debug("Failed to find widget for key: %s\n", name);
return -1;
}
- update_widget((GtkWidget*)object, value);
+ ghb_update_widget((GtkWidget*)object, value);
return 0;
}
@@ -684,7 +659,7 @@ ghb_ui_update(signal_user_data_t *ud, const gchar *name, const GValue *value)
g_debug("Failed to find widget for key: %s\n", name);
return -1;
}
- update_widget((GtkWidget*)object, value);
+ ghb_update_widget((GtkWidget*)object, value);
// Its possible the value hasn't changed. Since settings are only
// updated when the value changes, I'm initializing settings here as well.
ghb_widget_to_setting(ud->settings, (GtkWidget*)object);
diff --git a/gtk/src/settings.h b/gtk/src/settings.h
index 76f2d97be..6e3ee55ff 100644
--- a/gtk/src/settings.h
+++ b/gtk/src/settings.h
@@ -118,5 +118,6 @@ int ghb_ui_update(
int ghb_ui_update_from_settings(
GtkBuilder *builder, const gchar *name, const GValue *settings);
const gchar* ghb_get_setting_key(GtkWidget *widget);
+void ghb_update_widget(GtkWidget *widget, const GValue *value);
#endif // _SETTINGS_H_
diff --git a/gtk/src/subtitlehandler.c b/gtk/src/subtitlehandler.c
index 121654ac5..abaee4b2e 100644
--- a/gtk/src/subtitlehandler.c
+++ b/gtk/src/subtitlehandler.c
@@ -2,15 +2,16 @@
/*
* subtitlehandler.c
* Copyright (C) John Stebbins 2008-2013 <stebbins@stebbins>
- *
+ *
* subtitlehandler.c is free software.
- *
+ *
* You may redistribute it and/or modify it under the terms of the
* GNU General Public License, as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*/
+#include <glib/gi18n.h>
#include "ghbcompat.h"
#include "hb.h"
#include "settings.h"
@@ -22,118 +23,164 @@
#include "audiohandler.h"
#include "subtitlehandler.h"
-static gboolean ghb_add_subtitle_to_settings(GValue *settings, GValue *subsettings);
+static void subtitle_add_to_settings(GValue *settings, GValue *subsettings);
static void ghb_add_subtitle_to_ui(signal_user_data_t *ud, GValue *subsettings);
-static void add_to_subtitle_list(signal_user_data_t *ud, GValue *settings);
-static void add_to_srt_list(signal_user_data_t *ud, GValue *settings);
+static void add_to_subtitle_list_ui(signal_user_data_t *ud, GValue *settings);
static void ghb_clear_subtitle_list_settings(GValue *settings);
-static void ghb_clear_subtitle_list(signal_user_data_t *ud);
+static void ghb_clear_subtitle_list_ui(GtkBuilder *builder);
static void
-free_subtitle_index_list(gpointer data)
+subtitle_refresh_list_row_ui(
+ GtkTreeModel *tm,
+ GtkTreeIter *ti,
+ GValue *subsettings)
{
- g_free(data);
-}
+ GtkTreeIter cti;
+ gboolean forced, burned, def;
+ char *info_src, *info_src_2;
+ char *info_dst, *info_dst_2;
-static void
-free_subtitle_key(gpointer data)
-{
- if (data != NULL)
- g_free(data);
-}
-gboolean
-ghb_canPassSub(int source, int mux)
-{
- return hb_subtitle_can_pass(source, mux);
-}
+ info_src_2 = NULL;
+ info_dst_2 = NULL;
-gboolean
-ghb_canBurnSub(int source)
-{
- return hb_subtitle_can_burn(source);
-}
+ forced = ghb_settings_get_boolean(subsettings, "SubtitleForced");
+ burned = ghb_settings_get_boolean(subsettings, "SubtitleBurned");
+ def = ghb_settings_get_boolean(subsettings, "SubtitleDefaultTrack");
+ info_src = ghb_settings_get_string(subsettings, "SubtitleTrackDescription");
+ if (ghb_settings_get_int(subsettings, "SubtitleSource") == SRTSUB)
+ {
+ gint offset;
+ offset = ghb_settings_get_int(subsettings, "SrtOffset");
+ if (offset != 0)
+ {
+ info_dst_2 = g_strdup_printf("Offset: %dms", offset);
+ }
+ }
-gboolean
-ghb_canForceSub(int source)
-{
- return hb_subtitle_can_force(source);
-}
+ GString *str = g_string_new("");
+ g_string_append_printf(str, "%s ", burned ? "Burned Into Video" :
+ "Passthrough");
+ if (forced)
+ {
+ g_string_append_printf(str, "(Forced Subtitles Only)");
+ }
+ if (def)
+ {
+ g_string_append_printf(str, "(Default)");
+ }
-gboolean
-ghb_soft_in_subtitle_list(GValue *subtitle_list)
-{
- gint count, ii;
- GValue *settings;
+ info_dst = g_string_free(str, FALSE);
- count = ghb_array_len(subtitle_list);
- for (ii = 0; ii < count; ii++)
+ gtk_tree_store_set(GTK_TREE_STORE(tm), ti,
+ // These are displayed in list
+ 0, info_src,
+ 1, "-->",
+ 2, info_dst,
+ 3, "hb-edit",
+ 4, "hb-queue-delete",
+ 5, 0.5,
+ -1);
+
+ if (info_src_2 != NULL || info_dst_2 != NULL)
{
- settings = ghb_array_get_nth(subtitle_list, ii);
- if (!ghb_settings_get_boolean(settings, "SubtitleBurned"))
+ if (info_src_2 == NULL)
+ info_src_2 = g_strdup("");
+ if (info_dst_2 == NULL)
+ info_dst_2 = g_strdup("");
+
+ if(!gtk_tree_model_iter_children(tm, &cti, ti))
{
- return TRUE;
+ gtk_tree_store_append(GTK_TREE_STORE(tm), &cti, ti);
}
+ gtk_tree_store_set(GTK_TREE_STORE(tm), &cti,
+ // These are displayed in list
+ 0, info_src_2,
+ 2, info_dst_2,
+ 5, 0.0,
+ -1);
}
- return FALSE;
+ else
+ {
+ if(gtk_tree_model_iter_children(tm, &cti, ti))
+ {
+ gtk_tree_store_remove(GTK_TREE_STORE(tm), &cti);
+ }
+ }
+
+ g_free(info_src);
+ g_free(info_src_2);
+ g_free(info_dst);
+ g_free(info_dst_2);
}
-void
-ghb_subtitle_exclusive_burn_settings(GValue *settings, gint index)
+static void
+subtitle_refresh_list_ui(signal_user_data_t *ud)
{
GValue *subtitle_list;
GValue *subsettings;
- gint ii, count;
+ gint ii, count, tm_count;
+ GtkTreeView *tv;
+ GtkTreeModel *tm;
+ GtkTreeIter ti;
- g_debug("ghb_subtitle_exclusive_burn_settings");
- subtitle_list = ghb_settings_get_value(settings, "subtitle_list");
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
+ tm = gtk_tree_view_get_model(tv);
+
+ tm_count = gtk_tree_model_iter_n_children(tm, NULL);
+
+ subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
count = ghb_array_len(subtitle_list);
- for (ii = 0; ii < count; ii++)
+ if (count != tm_count)
{
- if (ii != index)
+ ghb_clear_subtitle_list_ui(ud->builder);
+ for (ii = 0; ii < count; ii++)
{
- subsettings = ghb_array_get_nth(subtitle_list, ii);
- ghb_settings_set_boolean(subsettings, "SubtitleBurned", FALSE);
+ gtk_tree_store_append(GTK_TREE_STORE(tm), &ti, NULL);
}
}
+ for (ii = 0; ii < count; ii++)
+ {
+ g_return_if_fail(tv != NULL);
+ gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
+ subsettings = ghb_array_get_nth(subtitle_list, ii);
+ subtitle_refresh_list_row_ui(tm, &ti, subsettings);
+ }
}
void
-ghb_subtitle_exclusive_burn(signal_user_data_t *ud, gint index)
+ghb_subtitle_exclusive_burn_settings(GValue *settings, gint index)
{
GValue *subtitle_list;
GValue *subsettings;
gint ii, count;
- GtkTreeView *tv;
- GtkTreeModel *tm;
- GtkTreeIter ti;
- g_debug("ghb_subtitle_exclusive_burn");
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
+ subtitle_list = ghb_settings_get_value(settings, "subtitle_list");
count = ghb_array_len(subtitle_list);
for (ii = 0; ii < count; ii++)
{
- tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- g_return_if_fail(tv != NULL);
- tm = gtk_tree_view_get_model(tv);
- gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
if (ii != index)
{
subsettings = ghb_array_get_nth(subtitle_list, ii);
ghb_settings_set_boolean(subsettings, "SubtitleBurned", FALSE);
- gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, FALSE, -1);
}
}
}
void
+ghb_subtitle_exclusive_burn(signal_user_data_t *ud, gint index)
+{
+ ghb_subtitle_exclusive_burn_settings(ud->settings, index);
+ subtitle_refresh_list_ui(ud);
+}
+
+void
ghb_subtitle_exclusive_default_settings(GValue *settings, gint index)
{
GValue *subtitle_list;
GValue *subtitle;
gint ii, count;
- g_debug("ghb_subtitle_exclusive_default");
subtitle_list = ghb_settings_get_value(settings, "subtitle_list");
count = ghb_array_len(subtitle_list);
for (ii = 0; ii < count; ii++)
@@ -149,93 +196,29 @@ ghb_subtitle_exclusive_default_settings(GValue *settings, gint index)
void
ghb_subtitle_exclusive_default(signal_user_data_t *ud, gint index)
{
- GValue *subtitle_list;
- GValue *settings;
- gint ii, count;
- GtkTreeView *tv;
- GtkTreeModel *tm;
- GtkTreeIter ti;
- gboolean def;
-
- g_debug("ghb_subtitle_exclusive_default");
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- count = ghb_array_len(subtitle_list);
- for (ii = 0; ii < count; ii++)
- {
- settings = ghb_array_get_nth(subtitle_list, ii);
- def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
-
- tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- g_return_if_fail(tv != NULL);
- tm = gtk_tree_view_get_model(tv);
- gtk_tree_model_iter_nth_child(tm, &ti, NULL, ii);
- if (def && ii != index)
- {
-
- ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", FALSE);
- gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, FALSE, -1);
- }
- }
+ ghb_subtitle_exclusive_default_settings(ud->settings, index);
+ subtitle_refresh_list_ui(ud);
}
-void
-ghb_add_srt(signal_user_data_t *ud, GValue *settings)
+static void
+ghb_add_subtitle_to_ui(signal_user_data_t *ud, GValue *subsettings)
{
- // Add the current subtitle settings to the list.
- GValue *subtitle_list;
- gint count;
- const gchar *lang;
-
- g_debug("ghb_add_srt ()");
-
- ghb_settings_set_boolean(settings, "SubtitleBurned", FALSE);
- // Add the long track description so the queue can access it
- // when a different title is selected.
- lang = ghb_settings_combo_option(settings, "SrtLanguage");
- ghb_settings_set_string(settings, "SubtitleTrackDescription", lang);
-
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- if (subtitle_list == NULL)
- {
- subtitle_list = ghb_array_value_new(8);
- ghb_settings_set_value(ud->settings, "subtitle_list", subtitle_list);
- }
- count = ghb_array_len(subtitle_list);
-
- // Don't allow more than 99
- // This is a had limit imposed by libhb/sync.c:GetFifoForId()
- if (count >= 99)
- {
- ghb_value_free(settings);
+ if (subsettings == NULL)
return;
- }
-
- ghb_array_append(subtitle_list, settings);
- add_to_srt_list(ud, settings);
- if (count == 98)
- {
- GtkWidget *widget;
- widget = GHB_WIDGET (ud->builder, "subtitle_add");
- gtk_widget_set_sensitive(widget, FALSE);
- widget = GHB_WIDGET (ud->builder, "srt_add");
- gtk_widget_set_sensitive(widget, FALSE);
- }
+ // Add the current subtitle settings to the list.
+ add_to_subtitle_list_ui(ud, subsettings);
ghb_live_reset(ud);
}
-static gboolean
-ghb_add_subtitle_to_settings(GValue *settings, GValue *subsettings)
+static void
+subtitle_add_to_settings(GValue *settings, GValue *subsettings)
{
// Add the current subtitle settings to the list.
GValue *subtitle_list;
gint count;
- gboolean burned, forced;
+ gboolean burned, forced, def;
gint source, mux;
- const gchar *track;
- const gchar *lang;
-
- g_debug("ghb_add_subtitle_to_settings ()");
subtitle_list = ghb_settings_get_value(settings, "subtitle_list");
if (subtitle_list == NULL)
@@ -244,39 +227,24 @@ ghb_add_subtitle_to_settings(GValue *settings, GValue *subsettings)
ghb_settings_set_value(settings, "subtitle_list", subtitle_list);
}
- count = ghb_array_len(subtitle_list);
- // Don't allow more than 99
- // This is a hard limit imposed by libhb/reader.c:GetFifoForId()
- if (count >= 99)
- {
- ghb_value_free(subsettings);
- return FALSE;
- }
-
- // Add the long track description so the queue can access it
- // when a different title is selected.
- track = ghb_settings_combo_option(subsettings, "SubtitleTrack");
- ghb_settings_set_string(subsettings, "SubtitleTrackDescription", track);
-
- lang = ghb_settings_combo_string(subsettings, "SubtitleTrack");
- ghb_settings_set_string(subsettings, "SubtitleLanguage", lang);
-
+ // Validate some settings
mux = ghb_settings_combo_int(settings, "FileFormat");
source = ghb_settings_get_int(subsettings, "SubtitleSource");
burned = ghb_settings_get_boolean(subsettings, "SubtitleBurned");
- if (burned && !ghb_canBurnSub(source))
+ if (burned && !hb_subtitle_can_burn(source))
{
burned = FALSE;
ghb_settings_set_boolean(subsettings, "SubtitleBurned", burned);
}
- if (!burned && !ghb_canPassSub(source, mux))
+ if (!burned && !hb_subtitle_can_pass(source, mux))
{
burned = TRUE;
ghb_settings_set_boolean(subsettings, "SubtitleBurned", burned);
ghb_settings_set_boolean(subsettings, "SubtitleDefaultTrack", FALSE);
}
+ def = ghb_settings_get_boolean(subsettings, "SubtitleDefaultTrack");
forced = ghb_settings_get_boolean(subsettings, "SubtitleForced");
- if (forced && !ghb_canForceSub(source))
+ if (forced && !hb_subtitle_can_force(source))
{
forced = FALSE;
ghb_settings_set_boolean(subsettings, "SubtitleForced", forced);
@@ -284,85 +252,177 @@ ghb_add_subtitle_to_settings(GValue *settings, GValue *subsettings)
ghb_array_append(subtitle_list, subsettings);
+ // Check consistancy of exclusive flags
+ count = ghb_array_len(subtitle_list);
if (burned)
- ghb_subtitle_exclusive_burn_settings(settings, count);
- return TRUE;
+ ghb_subtitle_exclusive_burn_settings(settings, count-1);
+ if (def)
+ ghb_subtitle_exclusive_default_settings(settings, count-1);
}
static void
-ghb_add_subtitle_to_ui(signal_user_data_t *ud, GValue *subsettings)
+subtitle_set_track_description(GValue *subsettings)
{
- // Add the current subtitle settings to the list.
- GValue *subtitle_list;
- gint count;
-
- g_debug("ghb_add_subtitle_to_ui ()");
- add_to_subtitle_list(ud, subsettings);
+ char *track;
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- count = ghb_array_len(subtitle_list);
- if (count == 99)
+ if (ghb_settings_get_int(subsettings, "SubtitleSource") == SRTSUB)
{
- GtkWidget *widget;
- widget = GHB_WIDGET (ud->builder, "subtitle_add");
- gtk_widget_set_sensitive(widget, FALSE);
- widget = GHB_WIDGET (ud->builder, "srt_add");
- gtk_widget_set_sensitive(widget, FALSE);
+ gchar *filename, *code;
+ const gchar *lang;
+
+ lang = ghb_settings_combo_option(subsettings, "SrtLanguage");
+ code = ghb_settings_get_string(subsettings, "SrtCodeset");
+
+ filename = ghb_settings_get_string(subsettings, "SrtFile");
+ if (g_file_test(filename, G_FILE_TEST_IS_REGULAR))
+ {
+ gchar *basename;
+
+ basename = g_path_get_basename(filename);
+ track = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename);
+ g_free(basename);
+ }
+ else
+ {
+ track = g_strdup_printf("%s (%s)(SRT)", lang, code);
+ }
+ g_free(code);
}
- ghb_live_reset(ud);
+ else
+ {
+ track = g_strdup(
+ ghb_settings_combo_option(subsettings, "SubtitleTrack"));
+ }
+
+ ghb_settings_set_string(
+ subsettings, "SubtitleTrackDescription", track);
+
+ g_free(track);
}
-static void
-add_all_pref_subtitles(signal_user_data_t *ud)
+static GValue* subtitle_add_track(
+ GValue *settings,
+ hb_title_t *title,
+ int track,
+ int mux,
+ gboolean default_track,
+ gboolean srt,
+ gboolean *burned)
{
- const GValue *pref_subtitle;
- GValue *subtitle;
- gint count, ii, track;
- char *lang;
+ int source = 0;
- pref_subtitle = ghb_settings_get_value(ud->settings, "SubtitleList");
- count = ghb_array_len(pref_subtitle);
- for (ii = 0; ii < count; ii++)
+ if (track >= 0 && !srt)
{
- subtitle = ghb_value_dup(ghb_array_get_nth(pref_subtitle, ii));
- lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
- // If there are multiple subtitles using the same language, then
- // select sequential tracks for each. The hash keeps track
- // of the tracks used for each language.
- track = ghb_find_pref_subtitle_track(lang);
- g_free(lang);
- if (track >= -1)
- {
- int source;
+ hb_subtitle_t *subtitle = hb_list_item(title->list_subtitle, track);
+ source = subtitle->source;
+ }
+ else if (srt)
+ {
+ source = SRTSUB;
+ }
- // Add to subtitle list
- ghb_settings_set_int(subtitle, "SubtitleTrack", track);
- source = ghb_subtitle_track_source(ud->settings, track);
- ghb_settings_set_int(subtitle, "SubtitleSource", source);
+ if (*burned && !hb_subtitle_can_pass(source, mux))
+ {
+ // Can only burn one. Skip others that must be burned.
+ return NULL;
+ }
- if (!ghb_add_subtitle_to_settings(ud->settings, subtitle))
- return;
+ GValue *subsettings = ghb_dict_value_new();
+ ghb_settings_set_int(subsettings, "SubtitleTrack", track);
+ ghb_settings_set_int(subsettings, "SubtitleSource", source);
- ghb_add_subtitle_to_ui(ud, subtitle);
- }
+ // Set default SRT settings
+ gchar *pref_lang, *dir, *filename;
+
+ pref_lang = ghb_settings_get_string(settings, "PreferredLanguage");
+ ghb_settings_set_string(subsettings, "SrtLanguage", pref_lang);
+ g_free(pref_lang);
+
+ ghb_settings_set_string(subsettings, "SrtCodeset", "UTF-8");
+
+ dir = ghb_settings_get_string(settings, "SrtDir");
+ filename = g_strdup_printf("%s/none", dir);
+ ghb_settings_set_string(subsettings, "SrtFile", filename);
+ g_free(dir);
+ g_free(filename);
+
+ ghb_settings_set_int(subsettings, "SrtOffset", 0);
+
+ subtitle_set_track_description(subsettings);
+
+ if (!hb_subtitle_can_pass(source, mux))
+ {
+ ghb_settings_set_boolean(subsettings, "SubtitleBurned", TRUE);
+ *burned = TRUE;
+ }
+ else
+ {
+ ghb_settings_set_boolean(subsettings, "SubtitleBurned", FALSE);
}
+ if (track == -1)
+ {
+ // Foreign audio search "track"
+ ghb_settings_set_boolean(subsettings, "SubtitleForced", TRUE);
+ }
+ else
+ {
+ ghb_settings_set_boolean(subsettings, "SubtitleForced", FALSE);
+ }
+ if (default_track)
+ {
+ ghb_settings_set_boolean(subsettings, "SubtitleDefaultTrack", TRUE);
+ }
+ else
+ {
+ ghb_settings_set_boolean(subsettings, "SubtitleDefaultTrack", FALSE);
+ }
+ subtitle_add_to_settings(settings, subsettings);
+
+ return subsettings;
}
void
-ghb_set_pref_subtitle_settings(gint titleindex, GValue *settings)
+ghb_subtitle_title_change(signal_user_data_t *ud, gboolean show)
+{
+ GtkWidget *w = GHB_WIDGET(ud->builder, "subtitle_add");
+ gtk_widget_set_sensitive(w, show);
+ w = GHB_WIDGET(ud->builder, "subtitle_add_all");
+ gtk_widget_set_sensitive(w, show);
+ w = GHB_WIDGET(ud->builder, "subtitle_reset");
+ gtk_widget_set_sensitive(w, show);
+}
+
+void
+ghb_set_pref_subtitle_settings(hb_title_t *title, GValue *settings)
{
gint track;
- GHashTable *track_indices;
- gchar *lang, *pref_lang = NULL;
- const gchar *audio_lang;
- gint foreign_lang_index = -1;
- gboolean found_cc = FALSE;
+ gboolean *used;
+ const gchar *audio_lang, *pref_lang = NULL;
+ gboolean foreign_audio_search, foreign_audio_subs;
+ gboolean one_burned = FALSE;
- const GValue *pref_subtitle;
- GValue *subtitle;
- gint count, ii, jj;
-
- g_debug("ghb_set_pref_subtitle %d", titleindex);
+ const GValue *lang_list;
+ gint lang_count, sub_count, ii;
+ int behavior, mux;
+
+ behavior = ghb_settings_combo_int(settings,
+ "SubtitleTrackSelectionBehavior");
+ // Clear the subtitle list
+ ghb_clear_subtitle_list_settings(settings);
+
+ if (title == NULL)
+ {
+ // no source title
+ return;
+ }
+ sub_count = hb_list_count(title->list_subtitle);
+ if (sub_count == 0)
+ {
+ // No source subtitles
+ return;
+ }
+
+ mux = ghb_settings_combo_int(settings, "FileFormat");
// Check to see if we need to add a subtitle track for foreign audio
// language films. A subtitle track will be added if:
@@ -370,560 +430,466 @@ ghb_set_pref_subtitle_settings(gint titleindex, GValue *settings)
// The first (default) audio track language does NOT match the users
// chosen Preferred Language AND the Preferred Language is NOT Any (und).
//
- audio_lang = ghb_get_user_audio_lang(settings, titleindex, 0);
- pref_lang = ghb_settings_get_string(settings, "PreferredLanguage");
-
- if (audio_lang != NULL && pref_lang != NULL &&
- (strcmp(audio_lang, pref_lang) == 0 || strcmp("und", pref_lang) == 0))
+ audio_lang = ghb_get_user_audio_lang(settings, title, 0);
+ foreign_audio_search = ghb_settings_get_boolean(
+ settings, "SubtitleAddForeignAudioSearch");
+ foreign_audio_subs = ghb_settings_get_boolean(
+ settings, "SubtitleAddForeignAudioSubtitle");
+ lang_list = ghb_settings_get_value(settings, "SubtitleLanguageList");
+ lang_count = ghb_array_len(lang_list);
+ if (lang_count > 0)
{
- g_free(pref_lang);
- pref_lang = NULL;
+ GValue *glang = ghb_array_get_nth(lang_list, 0);
+ pref_lang = g_value_get_string(glang);
}
- track_indices = g_hash_table_new_full(g_str_hash, g_str_equal,
- free_subtitle_key, free_subtitle_index_list);
-
- ghb_settings_set_int(settings, "SubtitleTrack", 0);
-
- // Clear the subtitle list
- ghb_clear_subtitle_list_settings(settings);
- if (titleindex < 0)
+ if (pref_lang == NULL || !strncmp(pref_lang, "und", 4))
{
- return;
+ foreign_audio_search = foreign_audio_subs = FALSE;
+ pref_lang = NULL;
}
- // Find "best" subtitle based on subtitle preferences
- pref_subtitle = ghb_settings_get_value(settings, "SubtitleList");
+ used = g_malloc0(sub_count * sizeof(gboolean));
- count = ghb_array_len(pref_subtitle);
- jj = 0;
- for (ii = 0; ii < count; ii++)
+ if (foreign_audio_subs &&
+ (audio_lang == NULL || strncmp(audio_lang, pref_lang, 4)))
{
- gint source;
- gboolean force, burn;
-
- subtitle = ghb_array_get_nth(pref_subtitle, ii);
- lang = ghb_settings_get_string(subtitle, "SubtitleLanguage");
- source = ghb_settings_get_int(subtitle, "SubtitleSource");
- burn = ghb_settings_get_boolean(subtitle, "SubtitleBurned");
- force = ghb_settings_get_boolean(subtitle, "SubtitleForced");
- // If there are multiple subtitles using the same language, then
- // select sequential tracks for each. The hash keeps track
- // of the tracks used for each language.
- track = ghb_find_subtitle_track(titleindex, lang, burn,
- force, source, track_indices);
- g_free(lang);
- if (track >= -1)
+ // Add preferred language subtitle since first audio track
+ // is foreign language.
+ foreign_audio_search = FALSE;
+ track = ghb_find_subtitle_track(title, pref_lang, 0);
+ if (track > 0)
{
- const gchar *track_lang;
- GValue *dup = ghb_value_dup(subtitle);
- track_lang = ghb_subtitle_track_lang(settings, track);
- ghb_settings_set_int(dup, "SubtitleTrack", track);
- if (foreign_lang_index < 0 && pref_lang != NULL &&
- strcmp(track_lang, pref_lang) == 0 &&
- !ghb_settings_get_boolean(dup, "SubtitleBurned"))
- {
- foreign_lang_index = jj;
- ghb_settings_take_value(dup, "SubtitleForced",
- ghb_boolean_value_new(FALSE));
- ghb_settings_take_value(dup, "SubtitleDefaultTrack",
- ghb_boolean_value_new(TRUE));
- }
- source = ghb_subtitle_track_source(settings, track);
- ghb_settings_set_int(dup, "SubtitleSource", source);
- if (source == CC608SUB || source == CC708SUB)
- found_cc = TRUE;
- ghb_add_subtitle_to_settings(settings, dup);
- jj++;
+ used[track] = TRUE;
+ subtitle_add_track(settings, title, track, mux,
+ TRUE, FALSE, &one_burned);
}
}
- if (foreign_lang_index < 0 && pref_lang != NULL)
+
+ if (foreign_audio_search &&
+ (audio_lang != NULL && !strncmp(audio_lang, pref_lang, 4)))
{
- // Subtitle for foreign language audio not added yet
- GValue *subsettings;
- gboolean burn;
+ // Add search for foreign audio segments
+ subtitle_add_track(settings, title, -1, mux, TRUE, FALSE, &one_burned);
+ }
- track = ghb_find_subtitle_track(titleindex, pref_lang, FALSE, FALSE, PGSSUB, track_indices);
- if (track >= -1)
+ if (behavior != 0)
+ {
+ // Find "best" subtitle based on subtitle preferences
+ for (ii = 0; ii < lang_count; ii++)
{
- int source;
+ GValue *glang = ghb_array_get_nth(lang_list, ii);
+ const gchar *lang = g_value_get_string(glang);
- subsettings = ghb_dict_value_new();
- ghb_settings_set_int(subsettings, "SubtitleTrack", track);
- source = ghb_subtitle_track_source(settings, track);
- ghb_settings_set_int(subsettings, "SubtitleSource", source);
- burn = FALSE;
- ghb_settings_take_value(subsettings, "SubtitleForced",
- ghb_boolean_value_new(FALSE));
- ghb_settings_take_value(subsettings, "SubtitleBurned",
- ghb_boolean_value_new(burn));
- ghb_settings_take_value(subsettings, "SubtitleDefaultTrack",
- ghb_boolean_value_new(TRUE));
-
- ghb_add_subtitle_to_settings(settings, subsettings);
- foreign_lang_index = jj;
+ int next_track = 0;
+ track = ghb_find_subtitle_track(title, lang, next_track);
+ while (track >= 0)
+ {
+ if (!used[track])
+ {
+ used[track] = TRUE;
+ subtitle_add_track(settings, title, track, mux,
+ FALSE, FALSE, &one_burned);
+ }
+ next_track = track + 1;
+ if (behavior == 2)
+ {
+ track = ghb_find_subtitle_track(title, lang, next_track);
+ }
+ else
+ {
+ break;
+ }
+ }
}
}
- if (foreign_lang_index >= 0)
- {
- GValue *subtitle_list;
- gboolean burn, def;
-
- subtitle_list = ghb_settings_get_value(settings, "subtitle_list");
- subtitle = ghb_array_get_nth(subtitle_list, foreign_lang_index);
- burn = ghb_settings_get_boolean(subtitle, "SubtitleBurned");
- def = ghb_settings_get_boolean(subtitle, "SubtitleDefaultTrack");
- if (burn)
- ghb_subtitle_exclusive_burn_settings(settings, foreign_lang_index);
- if (def)
- ghb_subtitle_exclusive_default_settings(settings, foreign_lang_index);
- ghb_log("adding subtitle for foreign language audio: %s", audio_lang);
- }
- if (ghb_settings_get_boolean(settings, "AddCC") && !found_cc)
+ if (ghb_settings_get_boolean(settings, "SubtitleAddCC"))
{
- // Subtitle for foreign language audio not added yet
- GValue *subsettings;
+ for (track = 0; track < sub_count; track++)
+ {
+ hb_subtitle_t *subtitle = hb_list_item(title->list_subtitle, track);
+ if (subtitle->source == CC608SUB || subtitle->source == CC708SUB)
+ break;
+ }
- track = ghb_find_cc_track(titleindex);
- if (track >= 0)
+ if (track < sub_count && !used[track])
{
- int source;
- subsettings = ghb_dict_value_new();
- ghb_settings_set_int(subsettings, "SubtitleTrack", track);
- source = ghb_subtitle_track_source(settings, track);
- ghb_settings_set_int(subsettings, "SubtitleSource", source);
- ghb_settings_take_value(subsettings, "SubtitleForced",
- ghb_boolean_value_new(FALSE));
- ghb_settings_take_value(subsettings, "SubtitleBurned",
- ghb_boolean_value_new(FALSE));
- ghb_settings_take_value(subsettings, "SubtitleDefaultTrack",
- ghb_boolean_value_new(FALSE));
-
- ghb_add_subtitle_to_settings(settings, subsettings);
- ghb_log("adding Closed Captions: %s", audio_lang);
+ used[track] = TRUE;
+ subtitle_add_track(settings, title, track, mux,
+ FALSE, FALSE, &one_burned);
}
}
- if (pref_lang != NULL)
- g_free(pref_lang);
- g_hash_table_destroy(track_indices);
+ g_free(used);
}
void
ghb_set_pref_subtitle(gint titleindex, signal_user_data_t *ud)
{
- ghb_set_pref_subtitle_settings(titleindex, ud->settings);
- ghb_clear_subtitle_list(ud);
- if (titleindex < 0)
+ hb_title_t *title;
+ int sub_count;
+ GtkWidget *widget;
+
+ ghb_clear_subtitle_list_ui(ud->builder);
+ title = ghb_get_title_info(titleindex);
+ if (title == NULL)
{
- add_all_pref_subtitles(ud);
return;
}
-
- gint count, ii;
- GValue *subtitle_list;
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- count = ghb_array_len(subtitle_list);
- for (ii = 0; ii < count; ii++)
+ sub_count = hb_list_count(title->list_subtitle);
+ if (sub_count == 0)
+ {
+ // No source subtitles
+ widget = GHB_WIDGET(ud->builder, "SubtitleSrtDisable");
+ gtk_widget_set_sensitive(widget, FALSE);
+ }
+ else
{
- GValue *subtitle;
- subtitle = ghb_array_get_nth(subtitle_list, ii);
- ghb_add_subtitle_to_ui(ud, subtitle);
+ widget = GHB_WIDGET(ud->builder, "SubtitleSrtDisable");
+ gtk_widget_set_sensitive(widget, TRUE);
}
+ ghb_set_pref_subtitle_settings(title, ud->settings);
+ subtitle_refresh_list_ui(ud);
}
gint
ghb_selected_subtitle_row(signal_user_data_t *ud)
{
- GtkTreeView *treeview;
- GtkTreePath *treepath;
- GtkTreeSelection *selection;
- GtkTreeModel *store;
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeSelection *ts;
+ GtkTreeModel *tm;
GtkTreeIter iter;
gint *indices;
gint row = -1;
-
+
g_debug("ghb_selected_subtitle_row ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected(selection, &store, &iter))
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ if (gtk_tree_selection_get_selected(ts, &tm, &iter))
{
// Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
+ tp = gtk_tree_model_get_path(tm, &iter);
+ indices = gtk_tree_path_get_indices(tp);
row = indices[0];
- gtk_tree_path_free(treepath);
+ gtk_tree_path_free(tp);
}
return row;
}
-GValue*
-ghb_selected_subtitle_settings(signal_user_data_t *ud)
+static GValue*
+subtitle_get_selected_settings(signal_user_data_t *ud, int *index)
{
- GtkTreeView *treeview;
- GtkTreePath *treepath;
- GtkTreeSelection *selection;
- GtkTreeModel *store;
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeSelection *ts;
+ GtkTreeModel *tm;
GtkTreeIter iter;
gint *indices;
gint row;
- GValue *settings = NULL;
+ GValue *subsettings = NULL;
const GValue *subtitle_list;
-
+
g_debug("get_selected_settings ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected(selection, &store, &iter))
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ if (gtk_tree_selection_get_selected(ts, &tm, &iter))
{
// Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
+ tp = gtk_tree_model_get_path(tm, &iter);
+ indices = gtk_tree_path_get_indices(tp);
row = indices[0];
- gtk_tree_path_free(treepath);
- // find subtitle settings
+ gtk_tree_path_free(tp);
if (row < 0) return NULL;
+
subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
if (row >= ghb_array_len(subtitle_list))
return NULL;
- settings = ghb_array_get_nth(subtitle_list, row);
+
+ subsettings = ghb_array_get_nth(subtitle_list, row);
+ if (index != NULL)
+ *index = row;
}
- return settings;
+ return subsettings;
}
-G_MODULE_EXPORT void
-subtitle_forced_toggled_cb(
- GtkCellRendererToggle *cell,
- gchar *path,
- signal_user_data_t *ud)
+static void
+subtitle_update_dialog_widgets(signal_user_data_t *ud, GValue *subsettings)
{
- GtkTreeView *tv;
- GtkTreeModel *tm;
- GtkTreeIter ti;
- gboolean active;
- gint row;
- GtkTreePath *tp;
- gint *indices;
- GValue *subtitle_list, *settings;
- gint source;
+ GtkWidget *widget;
- g_debug("forced toggled");
- tp = gtk_tree_path_new_from_string (path);
- tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- g_return_if_fail(tv != NULL);
- tm = gtk_tree_view_get_model(tv);
- g_return_if_fail(tm != NULL);
- gtk_tree_model_get_iter(tm, &ti, tp);
- gtk_tree_model_get(tm, &ti, 1, &active, -1);
- active ^= 1;
-
- // Get the row number
- indices = gtk_tree_path_get_indices (tp);
- row = indices[0];
- gtk_tree_path_free(tp);
+ if (subsettings != NULL)
+ {
+ // Update widgets with subsettings
+ gchar *str, *track;
+ gint offset;
+ gboolean burn, force, def;
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
+ int mux = ghb_settings_combo_int(ud->settings, "FileFormat");
+ int source = ghb_settings_get_int(subsettings, "SubtitleSource");
- if (row < 0 || row >= ghb_array_len(subtitle_list))
- return;
+ track = ghb_settings_get_string(subsettings, "SubtitleTrack");
+ ghb_ui_update(ud, "SubtitleTrack", ghb_string_value(track));
+ g_free(track);
- settings = ghb_array_get_nth(subtitle_list, row);
+ str = ghb_settings_get_string(subsettings, "SrtLanguage");
+ ghb_ui_update(ud, "SrtLanguage", ghb_string_value(str));
+ g_free(str);
- source = ghb_settings_get_int(settings, "SubtitleSource");
- if (!ghb_canForceSub(source))
- {
- return;
- }
+ str = ghb_settings_get_string(subsettings, "SrtCodeset");
+ ghb_ui_update(ud, "SrtCodeset", ghb_string_value(str));
+ g_free(str);
- ghb_settings_set_boolean(settings, "SubtitleForced", active);
- gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 1, active, -1);
- ghb_live_reset(ud);
-}
+ str = ghb_settings_get_string(subsettings, "SrtFile");
+ ghb_ui_update(ud, "SrtFile", ghb_string_value(str));
+ g_free(str);
-G_MODULE_EXPORT void
-subtitle_burned_toggled_cb(
- GtkCellRendererToggle *cell,
- gchar *path,
- signal_user_data_t *ud)
-{
- GtkTreeView *tv;
- GtkTreeModel *tm;
- GtkTreeIter ti;
- GtkTreePath *tp;
- gboolean active;
- gint row;
- gint *indices;
- GValue *subtitle_list;
- gint count;
- GValue *settings;
- gint source, mux;
+ offset = ghb_settings_get_int(subsettings, "SrtOffset");
+ ghb_ui_update(ud, "SrtOffset", ghb_int_value(offset));
- g_debug("burned toggled");
- tp = gtk_tree_path_new_from_string (path);
- tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- g_return_if_fail(tv != NULL);
- tm = gtk_tree_view_get_model(tv);
- g_return_if_fail(tm != NULL);
- gtk_tree_model_get_iter(tm, &ti, tp);
- gtk_tree_model_get(tm, &ti, 2, &active, -1);
- active ^= 1;
-
- // Get the row number
- indices = gtk_tree_path_get_indices (tp);
- row = indices[0];
- gtk_tree_path_free(tp);
+ if (source == SRTSUB)
+ {
+ ghb_ui_update(ud, "SubtitleSrtEnable", ghb_boolean_value(TRUE));
+ }
+ else
+ {
+ ghb_ui_update(ud, "SubtitleSrtDisable", ghb_boolean_value(TRUE));
+ }
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- count = ghb_array_len(subtitle_list);
- if (row < 0 || row >= count)
- return;
+ widget = GHB_WIDGET(ud->builder, "SubtitleBurned");
+ gtk_widget_set_sensitive(widget,
+ hb_subtitle_can_burn(source) && hb_subtitle_can_pass(source, mux));
+ widget = GHB_WIDGET(ud->builder, "SubtitleForced");
+ gtk_widget_set_sensitive(widget, hb_subtitle_can_force(source));
+ widget = GHB_WIDGET(ud->builder, "SubtitleDefaultTrack");
+ gtk_widget_set_sensitive(widget, hb_subtitle_can_pass(source, mux));
- settings = ghb_array_get_nth(subtitle_list, row);
- source = ghb_settings_get_int(settings, "SubtitleSource");
- if (!ghb_canBurnSub(source))
- return;
- mux = ghb_settings_combo_int(ud->settings, "FileFormat");
- if (!active && !hb_subtitle_can_pass(source, mux))
- return;
+ burn = ghb_settings_get_int(subsettings, "SubtitleBurned");
+ force = ghb_settings_get_int(subsettings, "SubtitleForced");
+ def = ghb_settings_get_int(subsettings, "SubtitleDefaultTrack");
+
+ if (!hb_subtitle_can_burn(source))
+ {
+ burn = FALSE;
+ }
+ if (!hb_subtitle_can_force(source))
+ {
+ force = FALSE;
+ }
+ if (!hb_subtitle_can_pass(source, mux))
+ {
+ def = FALSE;
+ burn = TRUE;
+ }
+ ghb_settings_set_boolean(subsettings, "SubtitleBurned", burn);
+ ghb_ui_update(ud, "SubtitleBurned", ghb_boolean_value(burn));
+ ghb_settings_set_boolean(subsettings, "SubtitleForced", force);
+ ghb_ui_update(ud, "SubtitleForced", ghb_boolean_value(force));
+ ghb_settings_set_boolean(subsettings, "SubtitleDefaultTrack", def);
+ ghb_ui_update(ud, "SubtitleDefaultTrack", ghb_boolean_value(def));
- ghb_settings_set_boolean(settings, "SubtitleBurned", active);
- gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, active, -1);
+ if (source == SRTSUB)
+ {
+ // Hide regular subtitle widgets
+ widget = GHB_WIDGET(ud->builder, "subtitle_track_box");
+ gtk_widget_hide(widget);
- if (active)
- {
- ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", !active);
- gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, !active, -1);
+ // Show SRT subitle widgets
+ widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid");
+ gtk_widget_show(widget);
+ }
+ else
+ {
+ // Hide SRT subitle widgets
+ widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid");
+ gtk_widget_hide(widget);
+
+ // Show regular subtitle widgets
+ widget = GHB_WIDGET(ud->builder, "subtitle_track_box");
+ gtk_widget_show(widget);
+ }
}
+ else
+ {
+ // Hide SRT subitle widgets
+ widget = GHB_WIDGET(ud->builder, "subtitle_srt_grid");
+ gtk_widget_hide(widget);
- // Unburn the rest
- if (active)
- ghb_subtitle_exclusive_burn(ud, row);
- ghb_live_reset(ud);
+ // Show regular subtitle widgets
+ widget = GHB_WIDGET(ud->builder, "subtitle_track_box");
+ gtk_widget_show(widget);
+ }
}
-G_MODULE_EXPORT void
-subtitle_default_toggled_cb(
- GtkCellRendererToggle *cell,
- gchar *path,
- signal_user_data_t *ud)
+static GValue*
+subtitle_update_setting(GtkWidget *widget, signal_user_data_t *ud)
{
- GtkTreeView *tv;
- GtkTreeModel *tm;
- GtkTreeIter ti;
- GtkTreePath *tp;
- gboolean active;
- gint row;
- gint *indices;
- GValue *subtitle_list;
- gint count;
- GValue *settings;
-
- g_debug("default toggled");
- tp = gtk_tree_path_new_from_string (path);
- tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- g_return_if_fail(tv != NULL);
- tm = gtk_tree_view_get_model(tv);
- g_return_if_fail(tm != NULL);
- gtk_tree_model_get_iter(tm, &ti, tp);
- gtk_tree_model_get(tm, &ti, 3, &active, -1);
- active ^= 1;
-
- // Get the row number
- indices = gtk_tree_path_get_indices (tp);
- row = indices[0];
- gtk_tree_path_free(tp);
-
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- count = ghb_array_len(subtitle_list);
- if (row < 0 || row >= count)
- return;
-
- settings = ghb_array_get_nth(subtitle_list, row);
+ GValue *subsettings;
- int source, mux;
- source = ghb_settings_get_int(settings, "SubtitleSource");
- mux = ghb_settings_combo_int(ud->settings, "FileFormat");
- if (active && !hb_subtitle_can_pass(source, mux))
- return;
+ ghb_widget_to_setting(ud->settings, widget);
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
+ {
+ ghb_widget_to_setting(subsettings, widget);
+ ghb_subtitle_list_refresh_selected(ud);
+ ghb_live_reset(ud);
+ }
+ return subsettings;
+}
- ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", active);
- gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 3, active, -1);
+G_MODULE_EXPORT void
+subtitle_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GValue *subsettings;
- if (active)
+ g_debug("subtitle_track_changed_cb()");
+ ghb_widget_to_setting(ud->settings, widget);
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
{
- ghb_settings_set_boolean(settings, "SubtitleBurned", !active);
- gtk_list_store_set(GTK_LIST_STORE(tm), &ti, 2, !active, -1);
+ gint track, source;
+
+ ghb_widget_to_setting(subsettings, widget);
+ track = ghb_settings_get_int(subsettings, "SubtitleTrack");
+ source = ghb_subtitle_track_source(ud->settings, track);
+ ghb_settings_set_int(subsettings, "SubtitleSource", source);
+ subtitle_set_track_description(subsettings);
+ subtitle_update_dialog_widgets(ud, subsettings);
+ ghb_subtitle_list_refresh_selected(ud);
+ ghb_live_reset(ud);
}
- // allow only one default
- ghb_subtitle_exclusive_default(ud, row);
- ghb_live_reset(ud);
}
-void
-ghb_subtitle_list_refresh_selected(signal_user_data_t *ud)
+G_MODULE_EXPORT void
+subtitle_forced_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- GtkTreeView *treeview;
- GtkTreePath *treepath;
- GtkTreeSelection *selection;
- GtkTreeModel *store;
- GtkTreeIter iter;
- gint *indices;
- gint row;
- GValue *settings = NULL;
- const GValue *subtitle_list;
- gboolean allow_force = FALSE;
- gboolean allow_burn = FALSE;
-
- g_debug("subtitle_list_refresh_selected ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected(selection, &store, &iter))
- {
- gchar *track, *source;
- gboolean forced, burned, def;
- gchar *s_track;
- gint offset = 0;
-
- // Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
- row = indices[0];
- gtk_tree_path_free(treepath);
- if (row < 0) return;
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- if (row >= ghb_array_len(subtitle_list))
- return;
- settings = ghb_array_get_nth(subtitle_list, row);
+ subtitle_update_setting(widget, ud);
+}
- burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
+G_MODULE_EXPORT void
+subtitle_burned_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GValue *subsettings;
+ int index;
- gint i_source;
- i_source = ghb_settings_get_int(settings, "SubtitleSource");
- if (!ghb_canBurnSub(i_source))
+ ghb_widget_to_setting(ud->settings, widget);
+ subsettings = subtitle_get_selected_settings(ud, &index);
+ if (subsettings != NULL)
+ {
+ ghb_widget_to_setting(subsettings, widget);
+ if (ghb_settings_get_boolean(subsettings, "SubtitleBurned"))
{
- burned = FALSE;
- ghb_settings_set_boolean(settings, "SubtitleBurned", burned);
+ ghb_ui_update(ud, "SubtitleDefaultTrack", ghb_boolean_value(FALSE));
+ ghb_subtitle_exclusive_burn(ud, index);
}
+ ghb_subtitle_list_refresh_selected(ud);
+ ghb_live_reset(ud);
+ }
+}
- gint i_mux;
- i_mux = ghb_settings_combo_int(ud->settings, "FileFormat");
- if (!burned && !ghb_canPassSub(i_source, i_mux))
- {
- burned = TRUE;
- ghb_settings_set_boolean(settings, "SubtitleBurned", burned);
- ghb_settings_set_boolean(settings, "SubtitleDefaultTrack", FALSE);
- }
+G_MODULE_EXPORT void
+subtitle_default_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GValue *subsettings;
+ int index;
- forced = ghb_settings_get_boolean(settings, "SubtitleForced");
- if (!ghb_canForceSub(i_source))
+ ghb_widget_to_setting(ud->settings, widget);
+ subsettings = subtitle_get_selected_settings(ud, &index);
+ if (subsettings != NULL)
+ {
+ ghb_widget_to_setting(subsettings, widget);
+ if (ghb_settings_get_boolean(subsettings, "SubtitleDefaultTrack"))
{
- forced = FALSE;
- ghb_settings_set_boolean(settings, "SubtitleForced", forced);
+ ghb_ui_update(ud, "SubtitleBurned", ghb_boolean_value(FALSE));
+ ghb_subtitle_exclusive_default(ud, index);
}
+ ghb_subtitle_list_refresh_selected(ud);
+ ghb_live_reset(ud);
+ }
+}
- def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
+G_MODULE_EXPORT void
+subtitle_srt_radio_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GValue *subsettings;
- if (i_source == SRTSUB)
+ ghb_widget_to_setting(ud->settings, widget);
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
+ {
+ if (ghb_settings_get_boolean(ud->settings, "SubtitleSrtEnable"))
{
- const gchar *lang;
- gchar *code;
-
- lang = ghb_settings_combo_option(settings, "SrtLanguage");
- code = ghb_settings_get_string(settings, "SrtCodeset");
-
- s_track = ghb_settings_get_string(settings, "SrtFile");
- if (g_file_test(s_track, G_FILE_TEST_IS_REGULAR))
- {
- gchar *basename;
-
- basename = g_path_get_basename(s_track);
- track = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename);
- source = g_strdup_printf("SRT (%s)", basename);
- g_free(basename);
- }
- else
- {
- track = g_strdup_printf("%s (%s)(SRT)", lang, code);
- source = g_strdup_printf("SRT (none)");
- }
- g_free(code);
- offset = ghb_settings_get_int(settings, "SrtOffset");
+ ghb_settings_set_int(subsettings, "SubtitleSource", SRTSUB);
}
else
{
- track = g_strdup(
- ghb_settings_combo_option(settings, "SubtitleTrack"));
- source = g_strdup(hb_subsource_name(i_source));
- s_track = ghb_settings_get_string(settings, "SubtitleTrack");
- }
-
- if (ghb_canBurnSub(i_source))
- allow_burn = TRUE;
- if (ghb_canForceSub(i_source))
- allow_force = TRUE;
+ int track, source;
- gtk_list_store_set(GTK_LIST_STORE(store), &iter,
- // These are displayed in list
- 0, track,
- 1, forced,
- 2, burned,
- 3, def,
- 4, offset,
- // These are used to set combo box values when a list item is selected
- 5, s_track,
- 6, i_source,
- 7, allow_force,
- 8, allow_burn,
- -1);
- g_free(track);
- g_free(source);
- g_free(s_track);
- if (burned)
- ghb_subtitle_exclusive_burn(ud, row);
+ track = ghb_settings_get_int(subsettings, "SubtitleTrack");
+ source = ghb_subtitle_track_source(ud->settings, track);
+ ghb_settings_set_int(subsettings, "SubtitleSource", source);
+ }
+ subtitle_set_track_description(subsettings);
+ subtitle_update_dialog_widgets(ud, subsettings);
+ ghb_subtitle_list_refresh_selected(ud);
+ ghb_live_reset(ud);
}
}
-G_MODULE_EXPORT void
-subtitle_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+void
+ghb_subtitle_list_refresh_selected(signal_user_data_t *ud)
{
- GValue *settings;
+ GtkTreeView *tv;
+ GtkTreeModel *tm;
+ GtkTreePath *tp;
+ GtkTreeSelection *ts;
+ GtkTreeIter ti;
+ gint *indices;
+ gint row;
+ GValue *subsettings = NULL;
+ const GValue *subtitle_list;
- g_debug("subtitle_track_changed_cb ()");
- ghb_check_dependency(ud, widget, NULL);
- ghb_widget_to_setting(ud->settings, widget);
- settings = ghb_selected_subtitle_settings(ud);
- if (settings != NULL)
- {
- const gchar *track, *lang;
- gint tt, source;
-
- ghb_widget_to_setting(settings, widget);
- track = ghb_settings_combo_option(settings, "SubtitleTrack");
- ghb_settings_set_string(settings, "SubtitleTrackDescription", track);
- tt = ghb_settings_get_int(settings, "SubtitleTrack");
- source = ghb_subtitle_track_source(ud->settings, tt);
- ghb_settings_set_int(settings, "SubtitleSource", source);
- lang = ghb_settings_combo_string(settings, "SubtitleTrack");
- ghb_settings_set_string(settings, "SubtitleLanguage", lang);
- ghb_subtitle_list_refresh_selected(ud);
- ghb_live_reset(ud);
+ g_debug("subtitle_list_refresh_selected()");
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ if (gtk_tree_selection_get_selected(ts, &tm, &ti))
+ {
+ // Get the row number
+ tp = gtk_tree_model_get_path(tm, &ti);
+ indices = gtk_tree_path_get_indices(tp);
+ row = indices[0];
+ gtk_tree_path_free(tp);
+ if (row < 0) return;
+
+ subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
+ if (row >= ghb_array_len(subtitle_list))
+ return;
+
+ subsettings = ghb_array_get_nth(subtitle_list, row);
+ subtitle_refresh_list_row_ui(tm, &ti, subsettings);
}
- ghb_live_reset(ud);
+}
+
+void
+ghb_subtitle_list_refresh_all(signal_user_data_t *ud)
+{
+ subtitle_refresh_list_ui(ud);
}
G_MODULE_EXPORT void
srt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- GValue *settings;
+ GValue *subsettings;
- g_debug("srt_changed_cb ()");
+ g_debug("srt_changed_cb()");
ghb_check_dependency(ud, widget, NULL);
ghb_widget_to_setting(ud->settings, widget);
- settings = ghb_selected_subtitle_settings(ud);
- if (settings != NULL)
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
{
- ghb_widget_to_setting(settings, widget);
+ ghb_widget_to_setting(subsettings, widget);
+ subtitle_set_track_description(subsettings);
ghb_subtitle_list_refresh_selected(ud);
-
ghb_live_reset(ud);
}
}
@@ -931,22 +897,23 @@ srt_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
G_MODULE_EXPORT void
srt_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- GValue *settings;
+ GValue *subsettings;
- g_debug("srt_file_changed_cb ()");
+ g_debug("srt_file_changed_cb()");
ghb_check_dependency(ud, widget, NULL);
ghb_widget_to_setting(ud->settings, widget);
- settings = ghb_selected_subtitle_settings(ud);
- if (settings != NULL)
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
{
gchar *filename, *dirname;
- ghb_widget_to_setting(settings, widget);
+ ghb_widget_to_setting(subsettings, widget);
+ subtitle_set_track_description(subsettings);
ghb_subtitle_list_refresh_selected(ud);
-
ghb_live_reset(ud);
- filename = ghb_settings_get_string(settings, "SrtFile");
+ // Update SrtDir preference
+ filename = ghb_settings_get_string(subsettings, "SrtFile");
if (g_file_test(filename, G_FILE_TEST_IS_DIR))
{
ghb_settings_set_string(ud->settings, "SrtDir", filename);
@@ -965,23 +932,18 @@ srt_file_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
G_MODULE_EXPORT void
srt_lang_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- GValue *settings;
+ GValue *subsettings;
- g_debug("srt_lang_changed_cb ()");
+ g_debug("srt_lang_changed_cb()");
ghb_check_dependency(ud, widget, NULL);
ghb_widget_to_setting(ud->settings, widget);
- settings = ghb_selected_subtitle_settings(ud);
- if (settings != NULL)
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
{
- const gchar *lang;
-
- ghb_widget_to_setting(settings, widget);
+ ghb_widget_to_setting(subsettings, widget);
+ subtitle_set_track_description(subsettings);
ghb_subtitle_list_refresh_selected(ud);
-
ghb_live_reset(ud);
-
- lang = ghb_settings_combo_option(settings, "SrtLanguage");
- ghb_settings_set_string(settings, "SubtitleTrackDescription", lang);
}
}
@@ -990,7 +952,6 @@ ghb_clear_subtitle_list_settings(GValue *settings)
{
GValue *subtitle_list;
- g_debug("clear_subtitle_list ()");
subtitle_list = ghb_settings_get_value(settings, "subtitle_list");
if (subtitle_list == NULL)
{
@@ -1002,415 +963,239 @@ ghb_clear_subtitle_list_settings(GValue *settings)
}
static void
-ghb_clear_subtitle_list(signal_user_data_t *ud)
+ghb_clear_subtitle_list_ui(GtkBuilder *builder)
{
- GtkTreeView *treeview;
- GtkListStore *store;
-
- g_debug("clear_subtitle_list ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
- gtk_list_store_clear (store);
-}
+ GtkTreeView *tv;
+ GtkTreeStore *ts;
-static void
-add_to_subtitle_list(
- signal_user_data_t *ud,
- GValue *settings)
-{
- GtkTreeView *treeview;
- GtkTreeIter iter;
- GtkListStore *store;
- GtkTreeSelection *selection;
- const gchar *track;
- gboolean forced, burned, def;
- gchar *s_track;
- gint i_source;
- gboolean allow_force = FALSE;
- gboolean allow_burn = FALSE;
-
- g_debug("add_to_subtitle_list ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- selection = gtk_tree_view_get_selection (treeview);
- store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-
- track = ghb_settings_combo_option(settings, "SubtitleTrack");
- forced = ghb_settings_get_boolean(settings, "SubtitleForced");
- burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
- def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
-
- s_track = ghb_settings_get_string(settings, "SubtitleTrack");
- i_source = ghb_settings_get_int(settings, "SubtitleSource");
-
- if (ghb_canBurnSub(i_source))
- allow_burn = TRUE;
- if (ghb_canForceSub(i_source))
- allow_force = TRUE;
-
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- // These are displayed in list
- 0, track,
- 1, forced,
- 2, burned,
- 3, def,
- // These are used to set combo box values when a list item is selected
- 5, s_track,
- 6, i_source,
- 7, allow_force,
- 8, allow_burn,
- 9, FALSE,
- -1);
- gtk_tree_selection_select_iter(selection, &iter);
- g_free(s_track);
+ tv = GTK_TREE_VIEW(GHB_WIDGET(builder, "subtitle_list"));
+ ts = GTK_TREE_STORE(gtk_tree_view_get_model(tv));
+ gtk_tree_store_clear(ts);
}
static void
-add_to_srt_list(
- signal_user_data_t *ud,
- GValue *settings)
+add_to_subtitle_list_ui(signal_user_data_t *ud, GValue *subsettings)
{
- GtkTreeView *treeview;
- GtkTreeIter iter;
- GtkListStore *store;
- GtkTreeSelection *selection;
- const gchar *lang;
- gboolean forced, burned, def;
- gchar *filename, *code, *track, *source;
- gint i_source, offset;
-
- g_debug("add_to_srt_list ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- selection = gtk_tree_view_get_selection (treeview);
- store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
-
- lang = ghb_settings_combo_option(settings, "SrtLanguage");
- code = ghb_settings_get_string(settings, "SrtCodeset");
- forced = FALSE;
- burned = FALSE;
- def = ghb_settings_get_boolean(settings, "SubtitleDefaultTrack");
-
- filename = ghb_settings_get_string(settings, "SrtFile");
- if (g_file_test(filename, G_FILE_TEST_IS_REGULAR))
- {
- gchar *basename;
-
- basename = g_path_get_basename(filename);
- track = g_strdup_printf("%s (%s)(SRT)(%s)", lang, code, basename);
- source = g_strdup_printf("SRT (%s)", basename);
- g_free(basename);
- }
- else
- {
- track = g_strdup_printf("%s (%s)(SRT)", lang, code);
- source = g_strdup_printf("SRT (none)");
- }
- i_source = SRTSUB;
- offset = ghb_settings_get_int(settings, "SrtOffset");
+ GtkTreeView *tv;
+ GtkTreeIter ti;
+ GtkTreeModel *tm;
+ GtkTreeSelection *ts;
- gtk_list_store_append(store, &iter);
- gtk_list_store_set(store, &iter,
- // These are displayed in list
- 0, track,
- 1, forced,
- 2, burned,
- 3, def,
- 4, offset,
- // These are used to set combo box values when a list item is selected
- 5, filename,
- 6, i_source,
- 7, FALSE,
- 8, FALSE,
- 9, TRUE,
- -1);
- gtk_tree_selection_select_iter(selection, &iter);
- g_free(code);
- g_free(track);
- g_free(filename);
- g_free(source);
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ tm = gtk_tree_view_get_model(tv);
+
+ gtk_tree_store_append(GTK_TREE_STORE(tm), &ti, NULL);
+ subtitle_refresh_list_row_ui(tm, &ti, subsettings);
+
+ gtk_tree_selection_select_iter(ts, &ti);
}
G_MODULE_EXPORT void
-subtitle_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
+subtitle_list_selection_changed_cb(GtkTreeSelection *ts, signal_user_data_t *ud)
{
- GtkTreeModel *store;
+ GtkTreeModel *tm;
GtkTreeIter iter;
- GtkWidget *widget;
-
- g_debug("subtitle_list_selection_changed_cb ()");
- if (gtk_tree_selection_get_selected(selection, &store, &iter))
- {
- gint source;
- GtkTreePath *treepath;
- gint *indices, row;
- GValue *subtitle_list, *settings;
+ GValue *subsettings = NULL;
+ int row;
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
- row = indices[0];
- gtk_tree_path_free(treepath);
-
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- if (row >= ghb_array_len(subtitle_list))
- return;
-
- settings = ghb_array_get_nth(subtitle_list, row);
+ g_debug("subtitle_list_selection_changed_cb()");
+ if (gtk_tree_selection_get_selected(ts, &tm, &iter))
+ {
+ GtkTreeIter piter;
- source = ghb_settings_get_int(settings, "SubtitleSource");
- if (source == SRTSUB)
+ if (gtk_tree_model_iter_parent(tm, &piter, &iter))
{
- gchar *str;
- gint offset;
-
- str = ghb_settings_get_string(settings, "SrtLanguage");
- ghb_ui_update(ud, "SrtLanguage", ghb_string_value(str));
- g_free(str);
-
- str = ghb_settings_get_string(settings, "SrtCodeset");
- ghb_ui_update(ud, "SrtCodeset", ghb_string_value(str));
- g_free(str);
-
- str = ghb_settings_get_string(settings, "SrtFile");
- ghb_ui_update(ud, "SrtFile", ghb_string_value(str));
- g_free(str);
-
- offset = ghb_settings_get_int(settings, "SrtOffset");
- ghb_ui_update(ud, "SrtOffset", ghb_int_value(offset));
-
- widget = GHB_WIDGET(ud->builder, "subtitle_track_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SubtitleTrack");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "srt_lang_label");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "srt_code_label");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "srt_file_label");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "srt_offset_label");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "SrtLanguage");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "SrtCodeset");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "SrtFile");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "SrtOffset");
- gtk_widget_show(widget);
+ GtkTreePath *path;
+ GtkTreeView *tv;
+
+ gtk_tree_selection_select_iter(ts, &piter);
+ path = gtk_tree_model_get_path(tm, &piter);
+ tv = gtk_tree_selection_get_tree_view(ts);
+ // Make the parent visible in scroll window if it is not.
+ gtk_tree_view_scroll_to_cell(tv, path, NULL, FALSE, 0, 0);
+ gtk_tree_path_free(path);
+ return;
}
- else
- {
- gchar *track;
- track = ghb_settings_get_string(settings, "SubtitleTrack");
- ghb_ui_update(ud, "SubtitleTrack", ghb_string_value(track));
- g_free(track);
+ GtkTreePath *tp;
+ gint *indices;
+ GValue *subtitle_list;
- widget = GHB_WIDGET(ud->builder, "srt_lang_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "srt_code_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "srt_file_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "srt_offset_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtLanguage");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtCodeset");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtFile");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtOffset");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "subtitle_track_label");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "SubtitleTrack");
- gtk_widget_show(widget);
- }
- widget = GHB_WIDGET (ud->builder, "subtitle_remove");
- gtk_widget_set_sensitive(widget, TRUE);
+ tp = gtk_tree_model_get_path(tm, &iter);
+ indices = gtk_tree_path_get_indices(tp);
+ row = indices[0];
+ gtk_tree_path_free(tp);
+
+ subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
+ if (row >= 0 && row < ghb_array_len(subtitle_list))
+ subsettings = ghb_array_get_nth(subtitle_list, row);
}
- else
+ subtitle_update_dialog_widgets(ud, subsettings);
+ if (subsettings)
{
- widget = GHB_WIDGET(ud->builder, "srt_lang_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "srt_code_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "srt_file_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "srt_offset_label");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtLanguage");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtCodeset");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtFile");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "SrtOffset");
- gtk_widget_hide(widget);
- widget = GHB_WIDGET(ud->builder, "subtitle_track_label");
- gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "SubtitleTrack");
- gtk_widget_show(widget);
+ if (ghb_settings_get_boolean(subsettings, "SubtitleBurned"))
+ {
+ ghb_subtitle_exclusive_burn(ud, row);
+ }
}
}
-G_MODULE_EXPORT void
-srt_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
+static gboolean subtitle_is_one_burned(GValue *settings)
{
- // Add the current subtitle settings to the list.
- GValue *settings;
- gchar *dir, *filename, *lang;
-
- g_debug("subtitle_add_clicked_cb ()");
-
- settings = ghb_dict_value_new();
- ghb_settings_set_int(settings, "SubtitleSource", SRTSUB);
- lang = ghb_settings_get_string(ud->settings, "PreferredLanguage");
- ghb_settings_set_string(settings, "SrtLanguage", lang);
- g_free(lang);
- ghb_settings_set_string(settings, "SrtCodeset", "UTF-8");
-
- dir = ghb_settings_get_string(ud->settings, "SrtDir");
- filename = g_strdup_printf("%s/none", dir);
- ghb_settings_set_string(settings, "SrtFile", filename);
- g_free(dir);
- g_free(filename);
+ GValue *subtitle_list, *subsettings;
+ int count, ii;
- ghb_settings_set_int(settings, "SrtOffset", 0);
- ghb_settings_take_value(settings, "SubtitleDefaultTrack",
- ghb_boolean_value_new(FALSE));
+ subtitle_list = ghb_settings_get_value(settings, "subtitle_list");
+ if (subtitle_list == NULL)
+ return FALSE;
- ghb_add_srt(ud, settings);
+ count = ghb_array_len(subtitle_list);
+ for (ii = 0; ii < count; ii++)
+ {
+ subsettings = ghb_array_get_nth(subtitle_list, ii);
+ if (ghb_settings_get_boolean(subsettings, "SubtitleBurned"))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
}
G_MODULE_EXPORT void
subtitle_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
// Add the current subtitle settings to the list.
- GValue *settings;
- gboolean burned = FALSE;
- gint track, source, mux;
-
- g_debug("subtitle_add_clicked_cb ()");
-
- track = ghb_settings_get_int(ud->settings, "SubtitleTrack");
+ GValue *subsettings, *backup;
+ gboolean one_burned;
+ gint track, mux;
+
+ hb_title_t *title;
+ int titleindex = ghb_settings_combo_int(ud->settings, "title");
+ title = ghb_get_title_info(titleindex);
+ if (title == NULL)
+ {
+ return;
+ }
- settings = ghb_dict_value_new();
- ghb_settings_set_int(settings, "SubtitleTrack", track);
- source = ghb_subtitle_track_source(ud->settings, track);
+ // Back up settings in case we need to revert.
+ backup = ghb_value_dup(
+ ghb_settings_get_value(ud->settings, "subtitle_list"));
- // Initialize to passthru if possible, else burn
+ one_burned = subtitle_is_one_burned(ud->settings);
mux = ghb_settings_combo_int(ud->settings, "FileFormat");
- burned = !hb_subtitle_can_pass(source, mux);
-
- ghb_settings_set_int(settings, "SubtitleSource", source);
- ghb_settings_take_value(settings, "SubtitleForced",
- ghb_boolean_value_new(FALSE));
- ghb_settings_take_value(settings, "SubtitleBurned",
- ghb_boolean_value_new(burned));
- ghb_settings_take_value(settings, "SubtitleDefaultTrack",
- ghb_boolean_value_new(FALSE));
- if (!ghb_add_subtitle_to_settings(ud->settings, settings))
- return;
-
- ghb_add_subtitle_to_ui(ud, settings);
-}
-
-G_MODULE_EXPORT void
-subtitle_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 *subtitle_list;
+ int count = hb_list_count(title->list_subtitle);
+ for (subsettings = NULL, track = 0;
+ subsettings == NULL && track < count; track++)
+ {
+ subsettings = subtitle_add_track(ud->settings, title, track, mux,
+ FALSE, FALSE, &one_burned);
+ }
+ if (subsettings == NULL)
+ {
+ subsettings = subtitle_add_track(ud->settings, title, 0, mux,
+ FALSE, TRUE, &one_burned);
+ }
+ ghb_add_subtitle_to_ui(ud, subsettings);
- g_debug("subtitle_remove_clicked_cb ()");
- treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected(selection, &store, &iter))
+ if (subsettings != NULL)
{
- nextIter = iter;
- if (!gtk_tree_model_iter_next(store, &nextIter))
+ // Pop up the edit dialog
+ GtkResponseType response;
+ GtkWidget *dialog = GHB_WIDGET(ud->builder, "subtitle_dialog");
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_hide(dialog);
+ if (response != GTK_RESPONSE_OK)
{
- nextIter = iter;
- if (gtk_tree_model_get_iter_first(store, &nextIter))
+ ghb_settings_take_value(ud->settings, "subtitle_list", backup);
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
{
- gtk_tree_selection_select_iter (selection, &nextIter);
+ subtitle_update_dialog_widgets(ud, subsettings);
}
+ subtitle_refresh_list_ui(ud);
}
else
{
- gtk_tree_selection_select_iter (selection, &nextIter);
+ ghb_value_free(backup);
}
+ }
+}
- // Get the row number
- treepath = gtk_tree_model_get_path (store, &iter);
- indices = gtk_tree_path_get_indices (treepath);
- row = indices[0];
- gtk_tree_path_free(treepath);
- if (row < 0) return;
+G_MODULE_EXPORT void
+subtitle_add_all_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
+{
+ // Add the current subtitle settings to the list.
+ gboolean one_burned = FALSE;
+ gint track, mux;
- subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
- if (row >= ghb_array_len(subtitle_list))
- return;
+ hb_title_t *title;
+ int titleindex = ghb_settings_combo_int(ud->settings, "title");
+ title = ghb_get_title_info(titleindex);
+ if (title == NULL)
+ {
+ return;
+ }
- // Update our settings list before removing the row from the
- // treeview. Removing from the treeview sometimes provokes an
- // immediate selection change, so the list needs to be up to date
- // when this happens.
- GValue *old = ghb_array_get_nth(subtitle_list, row);
- ghb_value_free(old);
- ghb_array_remove(subtitle_list, row);
+ ghb_clear_subtitle_list_settings(ud->settings);
+ ghb_clear_subtitle_list_ui(ud->builder);
- // Remove the selected item
- gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
- // remove from subtitle settings list
- widget = GHB_WIDGET (ud->builder, "subtitle_add");
- gtk_widget_set_sensitive(widget, TRUE);
- widget = GHB_WIDGET (ud->builder, "srt_add");
- gtk_widget_set_sensitive(widget, TRUE);
+ mux = ghb_settings_combo_int(ud->settings, "FileFormat");
- ghb_live_reset(ud);
+ int count = hb_list_count(title->list_subtitle);
+ for (track = 0; track < count; track++)
+ {
+ subtitle_add_track(ud->settings, title, track, mux,
+ FALSE, FALSE, &one_burned);
}
+ subtitle_refresh_list_ui(ud);
+ ghb_live_reset(ud);
+}
+
+G_MODULE_EXPORT void
+subtitle_reset_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
+{
+ int titleindex = ghb_settings_combo_int(ud->settings, "title");
+ ghb_set_pref_subtitle(titleindex, ud);
}
void
ghb_subtitle_prune(signal_user_data_t *ud)
{
- GtkTreeView *tv;
GValue *subtitle_list;
- gint count, ii;
- gint first_track = 0, one_burned = 0;
+ GValue *subsettings;
+ gint ii;
+ gboolean one_burned = FALSE;
subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
if (subtitle_list == NULL)
return;
- count = ghb_array_len(subtitle_list);
- tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
- g_return_if_fail(tv != NULL);
- for (ii = count-1; ii >= 0; ii--)
+ int mux = ghb_settings_combo_int(ud->settings, "FileFormat");
+
+ for (ii = 0; ii < ghb_array_len(subtitle_list); )
{
gboolean burned;
- GValue *settings;
+ int source;
- settings = ghb_array_get_nth(subtitle_list, ii);
- burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
- if (burned)
+ subsettings = ghb_array_get_nth(subtitle_list, ii);
+ burned = ghb_settings_get_boolean(subsettings, "SubtitleBurned");
+ source = ghb_settings_get_boolean(subsettings, "SubtitleSource");
+ burned = burned || !hb_subtitle_can_pass(source, mux);
+ if (burned && one_burned)
{
- first_track = ii;
- one_burned++;
+ ghb_array_remove(subtitle_list, ii);
+ continue;
}
+ one_burned = one_burned || burned;
+ ghb_settings_set_boolean(subsettings, "SubtitleBurned", burned);
+ ii++;
}
- if (one_burned)
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
{
- ghb_subtitle_exclusive_burn(ud, first_track);
+ subtitle_update_dialog_widgets(ud, subsettings);
}
}
@@ -1421,10 +1206,10 @@ ghb_reset_subtitles(signal_user_data_t *ud, GValue *settings)
GValue *subtitle;
gint count, ii;
gint titleindex;
-
+
g_debug("ghb_reset_subtitles");
ghb_clear_subtitle_list_settings(ud->settings);
- ghb_clear_subtitle_list(ud);
+ ghb_clear_subtitle_list_ui(ud->builder);
titleindex = ghb_settings_combo_int(ud->settings, "title");
if (titleindex < 0)
return;
@@ -1433,18 +1218,335 @@ ghb_reset_subtitles(signal_user_data_t *ud, GValue *settings)
count = ghb_array_len(slist);
for (ii = 0; ii < count; ii++)
{
- int source;
-
subtitle = ghb_value_dup(ghb_array_get_nth(slist, ii));
- source = ghb_settings_get_int(subtitle, "SubtitleSource");
- if (source == SRTSUB)
- ghb_add_srt(ud, subtitle);
+ subtitle_add_to_settings(ud->settings, subtitle);
+ }
+ subtitle_refresh_list_ui(ud);
+}
+
+G_MODULE_EXPORT void
+subtitle_def_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ ghb_widget_to_setting(ud->settings, widget);
+ ghb_clear_presets_selection(ud);
+}
+
+static void
+subtitle_update_pref_lang(signal_user_data_t *ud, const iso639_lang_t *lang)
+{
+ GtkLabel *label;
+ GtkButton *button;
+ gchar *str;
+ const char * name = _("None");
+ const char * code = "und";
+
+ label = GTK_LABEL(GHB_WIDGET(ud->builder, "subtitle_preferred_language"));
+ if (lang != NULL)
+ {
+ code = lang->iso639_2;
+ if (strncmp(code, "und", 4))
+ {
+ name = lang->native_name && lang->native_name[0] ?
+ lang->native_name : lang->eng_name;
+ }
+ }
+
+ str = g_strdup_printf(_("Preferred Language: %s"), name);
+ gtk_label_set_text(label, str);
+ g_free(str);
+
+ ghb_settings_set_string(ud->settings, "PreferredLanguage", code);
+
+ button = GTK_BUTTON(GHB_WIDGET(ud->builder,
+ "SubtitleAddForeignAudioSubtitle"));
+ str = g_strdup_printf(_("Add %s subtitle track if default audio is not %s"),
+ name, name);
+ gtk_button_set_label(button, str);
+ g_free(str);
+
+ // If there is no preferred language, hide options that require
+ // a preferred language to be set.
+ gboolean visible = !(lang == NULL || !strncmp(code, "und", 4));
+ gtk_widget_set_visible(GTK_WIDGET(button), visible);
+ button = GTK_BUTTON(GHB_WIDGET(ud->builder,
+ "SubtitleAddForeignAudioSearch"));
+ gtk_widget_set_visible(GTK_WIDGET(button), visible);
+}
+
+G_MODULE_EXPORT void
+subtitle_add_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ GtkListBox *avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang"));
+ GtkListBox *selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang"));
+ GtkListBoxRow *row;
+ GtkWidget *label;
+
+ row = gtk_list_box_get_selected_row(avail);
+ if (row != NULL)
+ {
+ int idx;
+ const iso639_lang_t *lang;
+ GValue *glang, *lang_list;
+
+ // Remove from UI available language list box
+ label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ // Add to UI selected language list box
+ gtk_list_box_insert(selected, label, -1);
+
+ // Add to preset language list
+ idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx");
+ lang = ghb_iso639_lookup_by_int(idx);
+ glang = ghb_string_value_new(lang->iso639_2);
+ lang_list = ghb_settings_get_value(ud->settings, "SubtitleLanguageList");
+ if (ghb_array_len(lang_list) == 0)
+ {
+ subtitle_update_pref_lang(ud, lang);
+ }
+ ghb_array_append(lang_list, glang);
+ ghb_clear_presets_selection(ud);
+ }
+}
+
+G_MODULE_EXPORT void
+subtitle_remove_lang_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+
+ GtkListBox *avail, *selected;
+ GtkListBoxRow *row;
+ GtkWidget *label;
+
+ avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang"));
+ selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang"));
+ row = gtk_list_box_get_selected_row(selected);
+ if (row != NULL)
+ {
+ gint index;
+ GValue *lang_list;
+
+ index = gtk_list_box_row_get_index(row);
+
+ // Remove from UI selected language list box
+ label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx");
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ // Add to UI available language list box
+ gtk_list_box_insert(avail, label, idx);
+
+ // Remove from preset language list
+ lang_list = ghb_settings_get_value(ud->settings, "SubtitleLanguageList");
+ ghb_array_remove(lang_list, index);
+ ghb_clear_presets_selection(ud);
+
+ if (ghb_array_len(lang_list) > 0)
+ {
+ const iso639_lang_t *lang;
+ GValue *entry = ghb_array_get_nth(lang_list, 0);
+ lang = ghb_iso639_lookup_by_int(ghb_lookup_audio_lang(entry));
+ subtitle_update_pref_lang(ud, lang);
+ }
+ else
+ {
+ subtitle_update_pref_lang(ud, NULL);
+ }
+ }
+}
+
+static void subtitle_def_lang_list_clear_cb(GtkWidget *row, gpointer data)
+{
+ GtkListBox *avail = (GtkListBox*)data;
+ GtkWidget *label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ int idx = (intptr_t)g_object_get_data(G_OBJECT(label), "lang_idx");
+ gtk_list_box_insert(avail, label, idx);
+}
+
+static void subtitle_def_selected_lang_list_clear(signal_user_data_t *ud)
+{
+ GtkListBox *avail, *selected;
+ avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang"));
+ selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang"));
+ gtk_container_foreach(GTK_CONTAINER(selected),
+ subtitle_def_lang_list_clear_cb, (gpointer)avail);
+}
+
+static void subtitle_def_lang_list_init(signal_user_data_t *ud)
+{
+ GValue *lang_list;
+
+ // Clear selected languages.
+ subtitle_def_selected_lang_list_clear(ud);
+
+ lang_list = ghb_settings_get_value(ud->settings, "SubtitleLanguageList");
+ if (lang_list == NULL)
+ {
+ lang_list = ghb_array_value_new(8);
+ ghb_settings_set_value(ud->settings, "SubtitleLanguageList", lang_list);
+ }
+
+ int ii, count;
+ count = ghb_array_len(lang_list);
+ for (ii = 0; ii < count; )
+ {
+ GValue *lang_val = ghb_array_get_nth(lang_list, ii);
+ int idx = ghb_lookup_audio_lang(lang_val);
+ if (ii == 0)
+ {
+ const iso639_lang_t *lang;
+ lang = ghb_iso639_lookup_by_int(idx);
+ subtitle_update_pref_lang(ud, lang);
+ }
+
+ GtkListBox *avail, *selected;
+ GtkListBoxRow *row;
+ avail = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang"));
+ selected = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_selected_lang"));
+ row = ghb_find_lang_row(avail, idx);
+ if (row)
+ {
+ GtkWidget *label = gtk_bin_get_child(GTK_BIN(row));
+ g_object_ref(G_OBJECT(label));
+ gtk_widget_destroy(GTK_WIDGET(row));
+ gtk_widget_show(label);
+ gtk_list_box_insert(selected, label, -1);
+ ii++;
+ }
+ else
+ {
+ // Error in list. Probably duplicate languages. Remove
+ // this item from the list.
+ ghb_array_remove(lang_list, ii);
+ count--;
+ }
+ }
+ if (count == 0)
+ {
+ subtitle_update_pref_lang(ud, NULL);
+ }
+}
+
+void ghb_subtitle_def_settings_init(signal_user_data_t *ud)
+{
+ subtitle_def_lang_list_init(ud);
+}
+
+void ghb_init_subtitle_defaults_ui(signal_user_data_t *ud)
+{
+ GtkListBox *list_box;
+
+ list_box = GTK_LIST_BOX(GHB_WIDGET(ud->builder, "subtitle_avail_lang"));
+ ghb_init_lang_list_box(list_box);
+}
+
+G_MODULE_EXPORT void
+subtitle_edit_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
+{
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeModel *tm;
+ GtkTreeSelection *ts;
+ GtkTreeIter ti;
+
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ tm = gtk_tree_view_get_model(tv);
+ tp = gtk_tree_path_new_from_string (path);
+ if (gtk_tree_path_get_depth(tp) > 1) return;
+ if (gtk_tree_model_get_iter(tm, &ti, tp))
+ {
+ GValue *subsettings, *backup;
+
+ gtk_tree_selection_select_iter(ts, &ti);
+
+ // Back up settings in case we need to revert.
+ backup = ghb_value_dup(
+ ghb_settings_get_value(ud->settings, "subtitle_list"));
+
+ // Pop up the edit dialog
+ GtkResponseType response;
+ GtkWidget *dialog = GHB_WIDGET(ud->builder, "subtitle_dialog");
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_hide(dialog);
+ if (response != GTK_RESPONSE_OK)
+ {
+ ghb_settings_take_value(ud->settings, "subtitle_list", backup);
+ subsettings = subtitle_get_selected_settings(ud, NULL);
+ if (subsettings != NULL)
+ {
+ subtitle_update_dialog_widgets(ud, subsettings);
+ }
+ subtitle_refresh_list_ui(ud);
+ }
+ else
+ {
+ ghb_value_free(backup);
+ }
+ }
+}
+
+G_MODULE_EXPORT void
+subtitle_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
+{
+ GtkTreeView *tv;
+ GtkTreePath *tp;
+ GtkTreeModel *tm;
+ GtkTreeSelection *ts;
+ GtkTreeIter ti, nextIter;
+ gint row;
+ gint *indices;
+ GValue *subtitle_list;
+
+ tv = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
+ ts = gtk_tree_view_get_selection(tv);
+ tm = gtk_tree_view_get_model(tv);
+ tp = gtk_tree_path_new_from_string (path);
+ if (gtk_tree_path_get_depth(tp) > 1) return;
+ if (gtk_tree_model_get_iter(tm, &ti, tp))
+ {
+ nextIter = ti;
+ if (!gtk_tree_model_iter_next(tm, &nextIter))
+ {
+ nextIter = ti;
+ if (gtk_tree_model_get_iter_first(tm, &nextIter))
+ {
+ gtk_tree_selection_select_iter(ts, &nextIter);
+ }
+ }
else
{
- if (!ghb_add_subtitle_to_settings(ud->settings, subtitle))
- return;
- ghb_add_subtitle_to_ui(ud, subtitle);
+ gtk_tree_selection_select_iter(ts, &nextIter);
+ }
+
+ subtitle_list = ghb_settings_get_value(ud->settings, "subtitle_list");
+
+ // Get the row number
+ indices = gtk_tree_path_get_indices (tp);
+ row = indices[0];
+ if (row < 0 || row >= ghb_array_len(subtitle_list))
+ {
+ gtk_tree_path_free(tp);
+ return;
}
+
+ // Update our settings list before removing the row from the
+ // treeview. Removing from the treeview sometimes provokes an
+ // immediate selection change, so the list needs to be up to date
+ // when this happens.
+ GValue *old = ghb_array_get_nth(subtitle_list, row);
+ ghb_value_free(old);
+ ghb_array_remove(subtitle_list, row);
+
+ // Remove the selected item
+ gtk_tree_store_remove(GTK_TREE_STORE(tm), &ti);
+
+ ghb_live_reset(ud);
}
+ gtk_tree_path_free(tp);
}
diff --git a/gtk/src/subtitlehandler.h b/gtk/src/subtitlehandler.h
index b63b169c6..e1f261d3c 100644
--- a/gtk/src/subtitlehandler.h
+++ b/gtk/src/subtitlehandler.h
@@ -28,16 +28,14 @@
#include "settings.h"
void ghb_set_pref_subtitle(gint titleindex, signal_user_data_t *ud);
-void ghb_set_pref_subtitle_settings(gint titleindex, GValue *settings);
+void ghb_set_pref_subtitle_settings(hb_title_t *title, GValue *settings);
void ghb_set_subtitle(signal_user_data_t *ud, gint track, GValue *settings);
-GValue* ghb_selected_subtitle_settings(signal_user_data_t *ud);
-gint ghb_selected_subtitle_row(signal_user_data_t *ud);
void ghb_reset_subtitles(signal_user_data_t *ud, GValue *settings);
void ghb_subtitle_prune(signal_user_data_t *ud);
-gboolean ghb_soft_in_subtitle_list(GValue *subtitle_list);
-gboolean ghb_canBurnSub(int source);
-gboolean ghb_canForceSub(int source);
-gboolean ghb_canPassSub(int source, int mux);
void ghb_subtitle_list_refresh_selected(signal_user_data_t *ud);
+void ghb_subtitle_list_refresh_all(signal_user_data_t *ud);
+void ghb_init_subtitle_defaults_ui(signal_user_data_t *ud);
+void ghb_subtitle_def_settings_init(signal_user_data_t *ud);
+void ghb_subtitle_title_change(signal_user_data_t *ud, gboolean show);
#endif // _SUBTITLEHANDLER_H_
diff --git a/gtk/src/values.c b/gtk/src/values.c
index 149d371a8..2b253c0e6 100644
--- a/gtk/src/values.c
+++ b/gtk/src/values.c
@@ -14,6 +14,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "values.h"
diff --git a/gtk/src/widgetdeps.c b/gtk/src/widgetdeps.c
index f2c7c82ae..059390d7b 100644
--- a/gtk/src/widgetdeps.c
+++ b/gtk/src/widgetdeps.c
@@ -57,11 +57,11 @@ static dependency_t dep_map[] =
{"VideoEncoder", "x264_tab", "x264", FALSE, FALSE},
{"VideoEncoder", "x264_tab_label", "x264", FALSE, FALSE},
{"VideoEncoder", "Mp4iPodCompatible", "x264", FALSE, FALSE},
- {"AudioEncoderActual", "AudioBitrate", "ac3|dts", TRUE, FALSE},
- {"AudioEncoderActual", "AudioSamplerate", "ac3|dts", TRUE, FALSE},
- {"AudioEncoderActual", "AudioMixdown", "ac3|dts", TRUE, FALSE},
- {"AudioEncoderActual", "AudioTrackDRCSlider", "ac3|dts", TRUE, FALSE},
- {"AudioEncoderActual", "drc_label", "ac3|dts", TRUE, FALSE},
+ {"AudioEncoder", "AudioBitrate", "ac3|dts", TRUE, FALSE},
+ {"AudioEncoder", "AudioSamplerate", "ac3|dts", TRUE, FALSE},
+ {"AudioEncoder", "AudioMixdown", "ac3|dts", TRUE, FALSE},
+ {"AudioEncoder", "AudioTrackDRCSlider", "ac3|dts", TRUE, FALSE},
+ {"AudioEncoder", "drc_label", "ac3|dts", TRUE, FALSE},
{"x264_bframes", "x264_bpyramid", "<2", TRUE, FALSE},
{"x264_bframes", "x264_direct", "0", TRUE, FALSE},
{"x264_bframes", "x264_b_adapt", "0", TRUE, FALSE},