#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <gio/gio.h>
+#include <libnotify/notify.h>
#include "hb.h"
#include "callbacks.h"
static void update_chapter_list(signal_user_data_t *ud);
static GList* dvd_device_list();
static void prune_logs(signal_user_data_t *ud);
+void ghb_notify_done(signal_user_data_t *ud);
// This is a dependency map used for greying widgets
// that are dependent on the state of another widget.
}
static gboolean
-dep_check(signal_user_data_t *ud, const gchar *name)
+dep_check(signal_user_data_t *ud, const gchar *name, gboolean *out_hide)
{
GtkWidget *widget;
GObject *dep_object;
g_debug("dep_check () %s", name);
+ if (rev_map == NULL) return TRUE;
array = ghb_dict_lookup(rev_map, name);
count = ghb_array_len(array);
+ *out_hide = FALSE;
for (ii = 0; ii < count; ii++)
{
data = ghb_array_get_nth(array, ii);
widget = GHB_WIDGET(ud->builder, widget_name);
dep_object = gtk_builder_get_object(ud->builder, name);
g_free(widget_name);
+ if (!GTK_WIDGET_SENSITIVE(widget))
+ continue;
if (dep_object == NULL)
{
g_message("Failed to find widget");
gint jj = 0;
gchar **values;
gboolean sensitive = FALSE;
- gboolean die;
+ gboolean die, hide;
die = ghb_value_boolean(ghb_array_get_nth(data, 2));
+ hide = ghb_value_boolean(ghb_array_get_nth(data, 3));
value = ghb_value_string(ghb_array_get_nth(data, 1));
values = g_strsplit(value, "|", 10);
g_free(value);
jj++;
}
sensitive = die ^ sensitive;
- if (!sensitive) result = FALSE;
+ if (!sensitive)
+ {
+ result = FALSE;
+ *out_hide |= hide;
+ }
g_strfreev (values);
g_free(value);
}
name = gtk_widget_get_name(widget);
g_debug("ghb_check_dependency () %s", name);
+ if (dep_map == NULL) return;
array = ghb_dict_lookup(dep_map, name);
count = ghb_array_len(array);
for (ii = 0; ii < count; ii++)
{
gboolean sensitive;
+ gboolean hide;
data = ghb_array_get_nth(array, ii);
dep_name = ghb_value_string(data);
g_free(dep_name);
continue;
}
- sensitive = dep_check(ud, dep_name);
+ sensitive = dep_check(ud, dep_name, &hide);
g_free(dep_name);
if (GTK_IS_ACTION(dep_object))
+ {
gtk_action_set_sensitive(GTK_ACTION(dep_object), sensitive);
+ gtk_action_set_visible(GTK_ACTION(dep_object), sensitive || !hide);
+ }
else
+ {
gtk_widget_set_sensitive(GTK_WIDGET(dep_object), sensitive);
+ if (!sensitive && hide)
+ {
+ gtk_widget_hide(GTK_WIDGET(dep_object));
+ }
+ else
+ {
+ gtk_widget_show_now(GTK_WIDGET(dep_object));
+ }
+ }
}
}
GObject *dep_object;
g_debug("ghb_check_all_depencencies ()");
+ if (rev_map == NULL) return;
ghb_dict_iter_init(&iter, rev_map);
// middle (void*) cast prevents gcc warning "defreferencing type-punned
// pointer will break strict-aliasing rules"
&iter, (gpointer*)(void*)&dep_name, (gpointer*)(void*)&value))
{
gboolean sensitive;
+ gboolean hide;
+
dep_object = gtk_builder_get_object (ud->builder, dep_name);
if (dep_object == NULL)
{
g_message("Failed to find dependent widget %s", dep_name);
continue;
}
- sensitive = dep_check(ud, dep_name);
+ sensitive = dep_check(ud, dep_name, &hide);
if (GTK_IS_ACTION(dep_object))
+ {
gtk_action_set_sensitive(GTK_ACTION(dep_object), sensitive);
+ gtk_action_set_visible(GTK_ACTION(dep_object), sensitive || !hide);
+ }
else
+ {
gtk_widget_set_sensitive(GTK_WIDGET(dep_object), sensitive);
+ if (!sensitive && hide)
+ {
+ gtk_widget_hide(GTK_WIDGET(dep_object));
+ }
+ else
+ {
+ gtk_widget_show_now(GTK_WIDGET(dep_object));
+ }
+ }
}
}
return TRUE;
}
-static GtkWidget *dvd_device_combo = NULL;
-
void
-chooser_file_selected_cb(GtkFileChooser *dialog, GtkComboBox *combo)
+chooser_file_selected_cb(GtkFileChooser *dialog, signal_user_data_t *ud)
{
const gchar *name = gtk_file_chooser_get_filename (dialog);
GtkTreeModel *store;
GtkTreeIter iter;
const gchar *device;
gboolean foundit = FALSE;
+ GtkComboBox *combo;
if (name == NULL) return;
+ combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, "source_device"));
store = gtk_combo_box_get_model(combo);
if (gtk_tree_model_get_iter_first(store, &iter))
{
}
void
-dvd_device_changed_cb(GtkComboBox *combo, GtkWidget *dialog)
+dvd_device_changed_cb(GtkComboBox *combo, signal_user_data_t *ud)
{
- gint ii = gtk_combo_box_get_active (combo);
- if (ii != 0)
+ GtkWidget *dialog;
+ gint ii;
+
+ ii = gtk_combo_box_get_active (combo);
+ if (ii > 0)
{
- const gchar *device = gtk_combo_box_get_active_text (combo);
- const gchar *name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog));
+ const gchar *device, *name;
+
+ dialog = GHB_WIDGET(ud->builder, "source_dialog");
+ device = gtk_combo_box_get_active_text (combo);
+ name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog));
if (name == NULL || strcmp(name, device) != 0)
gtk_file_chooser_select_filename (GTK_FILE_CHOOSER(dialog), device);
}
}
void
-source_type_changed_cb(GtkToggleButton *toggle, GtkFileChooser *chooser)
+source_type_changed_cb(GtkToggleButton *toggle, signal_user_data_t *ud)
{
gchar *folder;
+ GtkFileChooser *chooser;
+ GtkWidget *dvd_device_combo;
g_debug("source_type_changed_cb ()");
+ chooser = GTK_FILE_CHOOSER(GHB_WIDGET(ud->builder, "source_dialog"));
+ dvd_device_combo = GHB_WIDGET(ud->builder, "source_device");
folder = gtk_file_chooser_get_current_folder (chooser);
if (gtk_toggle_button_get_active (toggle))
{
- gtk_file_chooser_set_action (chooser, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_file_chooser_set_action (chooser,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
gtk_widget_set_sensitive (dvd_device_combo, FALSE);
gtk_combo_box_set_active (GTK_COMBO_BOX(dvd_device_combo), 0);
}
}
}
-static GtkWidget*
-source_dialog_extra_widgets(GtkWidget *dialog, gboolean checkbutton_active)
+static void
+source_dialog_extra_widgets(
+ signal_user_data_t *ud,
+ GtkWidget *dialog,
+ gboolean checkbutton_active)
{
- GtkBox *vbox;
- GtkWidget *checkbutton;
-
- vbox = GTK_BOX(gtk_vbox_new (FALSE, 2));
- checkbutton = gtk_check_button_new_with_label ("Open VIDEO_TS folder");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(checkbutton), checkbutton_active);
- gtk_box_pack_start (vbox, checkbutton, FALSE, FALSE, 1);
- gtk_widget_show(checkbutton);
-
- GtkWidget *combo;
- GtkBox *hbox;
+ GtkToggleButton *checkbutton;
+ GtkComboBox *combo;
GList *drives, *link;
- GtkWidget *label, *blank;
+
+ checkbutton = GTK_TOGGLE_BUTTON(
+ GHB_WIDGET(ud->builder, "source_folder_flag"));
+ gtk_toggle_button_set_active(checkbutton, checkbutton_active);
+ combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, "source_device"));
+ gtk_list_store_clear(GTK_LIST_STORE(
+ gtk_combo_box_get_model(combo)));
- hbox = GTK_BOX(gtk_hbox_new (FALSE, 2));
- combo = gtk_combo_box_new_text();
- label = gtk_label_new("Detected DVD devices:");
- blank = gtk_label_new("");
link = drives = dvd_device_list();
- gtk_combo_box_append_text (GTK_COMBO_BOX(combo), "Not Selected");
+ gtk_combo_box_append_text (combo, "Not Selected");
while (link != NULL)
{
gchar *name = (gchar*)link->data;
- gtk_combo_box_append_text (GTK_COMBO_BOX(combo), name);
+ gtk_combo_box_append_text(combo, name);
g_free(name);
link = link->next;
}
g_list_free(drives);
- gtk_combo_box_set_active (GTK_COMBO_BOX(combo), 0);
- gtk_box_pack_start (vbox, GTK_WIDGET(hbox), FALSE, FALSE, 1);
- gtk_widget_show(GTK_WIDGET(hbox));
- gtk_box_pack_start (hbox, label, FALSE, FALSE, 1);
- gtk_widget_show(label);
- gtk_box_pack_start (hbox, combo, FALSE, FALSE, 2);
- gtk_widget_show(combo);
- gtk_box_pack_start (hbox, blank, TRUE, TRUE, 1);
- gtk_widget_show(blank);
-
- // Ugly hackish global alert
- dvd_device_combo = combo;
- g_signal_connect(combo, "changed", (GCallback)dvd_device_changed_cb, dialog);
- g_signal_connect(dialog, "selection-changed", (GCallback)chooser_file_selected_cb, combo);
-
- g_signal_connect(checkbutton, "toggled", (GCallback)source_type_changed_cb, dialog);
- return GTK_WIDGET(vbox);
}
extern GValue *ghb_queue_edit_settings;
static gchar *last_scan_file = NULL;
void
-ghb_do_scan(signal_user_data_t *ud, const gchar *filename, gboolean force)
+ghb_do_scan(
+ signal_user_data_t *ud,
+ const gchar *filename,
+ gint titlenum,
+ gboolean force)
{
if (!force && last_scan_file != NULL &&
strcmp(last_scan_file, filename) == 0)
path = ghb_settings_get_string( ud->settings, "source");
gtk_progress_bar_set_fraction (progress, 0);
gtk_progress_bar_set_text (progress, "Scanning ...");
- ghb_hb_cleanup(TRUE);
prune_logs(ud);
gint preview_count;
preview_count = ghb_settings_get_int(ud->settings, "preview_count");
- ghb_backend_scan(path, 0, preview_count);
+ ghb_backend_scan(path, titlenum, preview_count);
g_free(path);
}
else
}
}
-void
-source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
+static gboolean
+update_source_name(gpointer data)
+{
+ signal_user_data_t *ud = (signal_user_data_t*)data;
+ GtkWidget *dialog;
+ gchar *sourcename;
+
+ sourcename = ghb_settings_get_string(ud->settings, "source");
+ dialog = GHB_WIDGET(ud->builder, "source_dialog");
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sourcename);
+ g_free(sourcename);
+ return FALSE;
+}
+
+static void
+do_source_dialog(GtkButton *button, gboolean single, signal_user_data_t *ud)
{
GtkWidget *dialog;
- GtkWidget *widget;
gchar *sourcename;
gint response;
GtkFileChooserAction action;
{
action = GTK_FILE_CHOOSER_ACTION_OPEN;
}
- dialog = gtk_file_chooser_dialog_new ("Select Source",
- NULL,
- action,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
- widget = source_dialog_extra_widgets(dialog, checkbutton_active);
- gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), widget);
- gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sourcename);
+ GtkWidget *widget;
+ widget = GHB_WIDGET(ud->builder, "single_title_box");
+ if (single)
+ gtk_widget_show(widget);
+ else
+ gtk_widget_hide(widget);
+ dialog = GHB_WIDGET(ud->builder, "source_dialog");
+ source_dialog_extra_widgets(ud, dialog, checkbutton_active);
+ gtk_file_chooser_set_action(GTK_FILE_CHOOSER(dialog), action);
+ // Updating the filename in the file chooser dialog doesn't seem
+ // to work unless the dialog is running for some reason.
+ // So handle it in an "idle" event.
+ //gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sourcename);
+ g_idle_add((GSourceFunc)update_source_name, ud);
response = gtk_dialog_run(GTK_DIALOG (dialog));
gtk_widget_hide(dialog);
if (response == GTK_RESPONSE_ACCEPT)
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
if (filename != NULL)
{
- ghb_do_scan(ud, filename, TRUE);
+ gint titlenum;
+
+ if (single)
+ titlenum = ghb_settings_get_int(ud->settings, "single_title");
+ else
+ titlenum = 0;
+ ghb_do_scan(ud, filename, titlenum, TRUE);
if (strcmp(sourcename, filename) != 0)
{
- ghb_settings_set_string (ud->settings, "default_source", filename);
+ ghb_settings_set_string (ud->settings,
+ "default_source", filename);
ghb_pref_save (ud->settings, "default_source");
ghb_dvd_set_current (filename, ud);
}
}
}
g_free(sourcename);
- gtk_widget_destroy(dialog);
+}
+
+void
+source_button_clicked_cb(GtkButton *button, signal_user_data_t *ud)
+{
+ do_source_dialog(button, FALSE, ud);
+}
+
+void
+single_title_source_cb(GtkButton *button, signal_user_data_t *ud)
+{
+ do_source_dialog(button, TRUE, ud);
}
void
sourcename = ghb_settings_get_string(ud->settings, "source");
filename = gtk_action_get_name(action);
- ghb_do_scan(ud, filename, TRUE);
+ ghb_do_scan(ud, filename, 0, TRUE);
if (strcmp(sourcename, filename) != 0)
{
ghb_settings_set_string (ud->settings, "default_source", filename);
ghb_ui_update(ud, "scale_width",
ghb_int64_value(tinfo->width - tinfo->crop[2] - tinfo->crop[3]));
// If anamorphic or keep_aspect, the hight will be automatically calculated
- gboolean keep_aspect, anamorphic;
+ gboolean keep_aspect;
+ gint pic_par;
keep_aspect = ghb_settings_get_boolean(ud->settings, "PictureKeepRatio");
- anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
- if (!(keep_aspect || anamorphic))
+ pic_par = ghb_settings_combo_int(ud->settings, "PicturePAR");
+ if (!(keep_aspect || pic_par) || pic_par == 3)
{
ghb_ui_update(ud, "scale_height",
ghb_int64_value(tinfo->height - tinfo->crop[0] - tinfo->crop[1]));
gint preview_count;
preview_count = ghb_settings_get_int(ud->settings, "preview_count");
widget = GHB_WIDGET(ud->builder, "preview_frame");
- gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 1, preview_count);
+ gtk_range_set_range (GTK_RANGE(widget), 1, preview_count);
ghb_ui_update(ud, "preview_frame", ghb_int64_value(2));
ghb_set_preview_image (ud);
ghb_live_reset(ud);
}
-static void
-validate_filter_widget(signal_user_data_t *ud, const gchar *name)
-{
- GtkTreeModel *store;
- GtkTreeIter iter;
- const gchar *str;
- gboolean foundit = FALSE;
- GtkComboBox *combo = GTK_COMBO_BOX(GHB_WIDGET(ud->builder, name));
- if (gtk_combo_box_get_active(combo) < 0)
- { // Validate user input
- gchar *val = ghb_settings_get_string(ud->settings, name);
- store = gtk_combo_box_get_model(combo);
- // Check to see if user manually entered one of the combo options
- if (gtk_tree_model_get_iter_first(store, &iter))
- {
- do
- {
- gtk_tree_model_get(store, &iter, 0, &str, -1);
- if (strcasecmp(val, str) == 0)
- {
- gtk_combo_box_set_active_iter(combo, &iter);
- foundit = TRUE;
- break;
- }
- } while (gtk_tree_model_iter_next(store, &iter));
- }
- if (!foundit)
- { // validate format of filter string
- if (!ghb_validate_filter_string(val, -1))
- gtk_combo_box_set_active(combo, 0);
- }
- g_free(val);
- }
-}
-
-gboolean
-deint_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
- signal_user_data_t *ud)
+void
+vquality_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("deint_tweak_focus_out_cb ()");
- validate_filter_widget(ud, "tweak_PictureDeinterlace");
- return FALSE;
-}
+ ghb_widget_to_setting(ud->settings, widget);
+ ghb_check_dependency(ud, widget);
+ ghb_clear_presets_selection(ud);
+ ghb_live_reset(ud);
-gboolean
-denoise_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
- signal_user_data_t *ud)
-{
- g_debug("denoise_tweak_focus_out_cb ()");
- validate_filter_widget(ud, "tweak_PictureDenoise");
- return FALSE;
+ gint vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
+ gdouble step;
+ if (vcodec == HB_VCODEC_X264)
+ {
+ step = ghb_settings_combo_double(ud->settings,
+ "VideoQualityGranularity");
+ }
+ else
+ {
+ step = 1;
+ }
+ gdouble val = gtk_range_get_value(GTK_RANGE(widget));
+ val = ((int)((val + step / 2) / step)) * step;
+ gtk_range_set_value(GTK_RANGE(widget), val);
}
void
vcodec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
gdouble vqmin, vqmax, step, page;
+ gboolean inverted;
gint digits;
- gint vcodec;
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget);
ghb_clear_presets_selection(ud);
ghb_live_reset(ud);
- ghb_vquality_range(ud, &vqmin, &vqmax, &step, &page, &digits);
+ ghb_vquality_range(ud, &vqmin, &vqmax, &step, &page, &digits, &inverted);
GtkWidget *qp = GHB_WIDGET(ud->builder, "VideoQualitySlider");
gtk_range_set_range (GTK_RANGE(qp), vqmin, vqmax);
gtk_range_set_increments (GTK_RANGE(qp), step, page);
gtk_scale_set_digits(GTK_SCALE(qp), digits);
- vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
- if (vcodec != HB_VCODEC_X264 && vcodec != HB_VCODEC_FFMPEG)
- {
- ghb_ui_update(ud, "directqp", ghb_boolean_value(FALSE));
- }
+ gtk_range_set_inverted (GTK_RANGE(qp), inverted);
}
void
target_size_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
const gchar *name = gtk_widget_get_name(widget);
- g_debug("setting_widget_changed_cb () %s", name);
+ g_debug("target_size_changed_cb () %s", name);
ghb_widget_to_setting(ud->settings, widget);
ghb_check_dependency(ud, widget);
ghb_clear_presets_selection(ud);
text = ghb_settings_get_boolean(ud->settings, "autoscale") ? "On" : "Off";
widget = GHB_WIDGET (ud->builder, "scale_auto");
gtk_label_set_text (GTK_LABEL(widget), text);
- text = ghb_settings_get_boolean(ud->settings, "anamorphic") ? "On" : "Off";
+ switch (ghb_settings_combo_int(ud->settings, "PicturePAR"))
+ {
+ case 0:
+ text = "Off";
+ break;
+ case 1:
+ text = "Strict";
+ break;
+ case 2:
+ text = "Loose";
+ break;
+ case 3:
+ text = "Custom";
+ break;
+ default:
+ text = "Unknown";
+ break;
+ }
widget = GHB_WIDGET (ud->builder, "scale_anamorphic");
gtk_label_set_text (GTK_LABEL(widget), text);
}
gchar *ver_str;
ver_str = g_strdup_printf("Handbrake Version: %s (%d)\n",
- HB_VERSION, HB_BUILD);
+ hb_get_version(NULL), hb_get_build(NULL));
g_io_channel_write_chars (ud->job_activity_log, ver_str,
-1, NULL, NULL);
g_free(ver_str);
}
// Nothing pending
ghb_uninhibit_gpm();
+ ghb_notify_done(ud);
return NULL;
}
// Find the next pending item after the current running item
}
// Nothing found
ghb_uninhibit_gpm();
+ ghb_notify_done(ud);
return NULL;
}
va_end(args);
}
-void
-about_activate_cb(GtkWidget *xwidget, signal_user_data_t *ud)
-{
- GtkWidget *widget = GHB_WIDGET (ud->builder, "hb_about");
- gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), ghb_version());
- gtk_widget_show (widget);
-}
-
static void
browse_url(const gchar *url)
{
}
void
+about_web_hook(GtkAboutDialog *about, const gchar *link, gpointer data)
+{
+ browse_url(link);
+}
+
+void
+about_activate_cb(GtkWidget *xwidget, signal_user_data_t *ud)
+{
+ GtkWidget *widget = GHB_WIDGET (ud->builder, "hb_about");
+ gchar *ver;
+
+ ver = g_strdup_printf("%s (%s)", HB_PROJECT_VERSION, HB_PROJECT_BUILD_ARCH);
+ gtk_about_dialog_set_url_hook(about_web_hook, NULL, NULL);
+ gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(widget), ver);
+ g_free(ver);
+ gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(widget),
+ HB_PROJECT_URL_WEBSITE);
+ gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(widget),
+ HB_PROJECT_URL_WEBSITE);
+ gtk_widget_show (widget);
+}
+
+void
guide_activate_cb(GtkWidget *xwidget, signal_user_data_t *ud)
{
browse_url("http://trac.handbrake.fr/wiki/HandBrakeGuide");
if (ii < count)
{
- gchar *chapter;
+ gchar *chapter, *duration;
+ gint hh, mm, ss;
// Update row with settings data
g_debug("Updating row");
chapter = ghb_value_string(ghb_array_get_nth(chapters, ii));
+ ghb_get_chapter_duration(titleindex, ii, &hh, &mm, &ss);
+ duration = g_strdup_printf("%02d:%02d:%02d", hh, mm, ss);
gtk_list_store_set(store, &iter,
0, ii+1,
- 1, chapter,
- 2, TRUE,
+ 1, duration,
+ 2, chapter,
+ 3, TRUE,
-1);
g_free(chapter);
+ g_free(duration);
ii++;
done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
}
}
while (ii < count)
{
- gchar *chapter;
+ gchar *chapter, *duration;
+ gint hh, mm, ss;
// Additional settings, add row
g_debug("Adding row");
chapter = ghb_value_string(ghb_array_get_nth(chapters, ii));
+ ghb_get_chapter_duration(titleindex, ii, &hh, &mm, &ss);
+ duration = g_strdup_printf("%02d:%02d:%02d", hh, mm, ss);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, ii+1,
- 1, chapter,
- 2, TRUE,
+ 1, duration,
+ 2, chapter,
+ 3, TRUE,
-1);
g_free(chapter);
+ g_free(duration);
ii++;
}
}
row = pi[0];
gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, treepath);
gtk_list_store_set(store, &iter,
- 1, text,
- 2, TRUE,
+ 2, text,
+ 3, TRUE,
-1);
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &index, -1);
// I got industrious and made my own CellTextRendererText that
// passes on the key-press-event. So now I have much better
// control of this.
- column = gtk_tree_view_get_column(treeview, 1);
+ column = gtk_tree_view_get_column(treeview, 2);
gtk_tree_view_set_cursor(treeview, treepath, column, TRUE);
}
else if (chapter_edit_key == GDK_Up && row > 0)
{
GtkTreeViewColumn *column;
gtk_tree_path_prev(treepath);
- column = gtk_tree_view_get_column(treeview, 1);
+ column = gtk_tree_view_get_column(treeview, 2);
gtk_tree_view_set_cursor(treeview, treepath, column, TRUE);
}
gtk_tree_path_free (treepath);
}
void
+warn_log_handler(const gchar *domain, GLogLevelFlags flags, const gchar *msg, gpointer data)
+{
+ printf("mywarning\n");
+ printf("%s: %s\n", domain, msg);
+}
+
+void
ghb_hbfd(signal_user_data_t *ud, gboolean hbfd)
{
GtkWidget *widget;
}
void
-tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+vqual_granularity_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
- g_debug("tweaks_changed_cb");
+ g_debug("vqual_granularity_changed_cb");
ghb_widget_to_setting (ud->settings, widget);
+ ghb_check_dependency(ud, widget);
+
const gchar *name = gtk_widget_get_name(widget);
ghb_pref_save(ud->settings, name);
- gboolean tweaks = ghb_settings_get_boolean(ud->settings, "allow_tweaks");
- widget = GHB_WIDGET(ud->builder, "PictureDeinterlace");
- tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "tweak_PictureDeinterlace");
- !tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
+ gdouble vqmin, vqmax, step, page;
+ gboolean inverted;
+ gint digits;
- widget = GHB_WIDGET(ud->builder, "PictureDenoise");
- tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
- widget = GHB_WIDGET(ud->builder, "tweak_PictureDenoise");
- !tweaks ? gtk_widget_hide(widget) : gtk_widget_show(widget);
- if (tweaks)
- {
- const GValue *value;
- value = ghb_settings_get_value(ud->settings, "PictureDeinterlace");
- ghb_ui_update(ud, "tweak_PictureDeinterlace", value);
- value = ghb_settings_get_value(ud->settings, "PictureDenoise");
- ghb_ui_update(ud, "tweak_PictureDenoise", value);
- }
- else
- {
- const GValue *value;
- value = ghb_settings_get_value(ud->settings, "tweak_PictureDeinterlace");
- ghb_ui_update(ud, "PictureDeinterlace", value);
- value = ghb_settings_get_value(ud->settings, "tweak_PictureDenoise");
- ghb_ui_update(ud, "PictureDenoise", value);
- }
+ ghb_vquality_range(ud, &vqmin, &vqmax, &step, &page, &digits, &inverted);
+ GtkWidget *qp = GHB_WIDGET(ud->builder, "VideoQualitySlider");
+ gtk_range_set_increments (GTK_RANGE(qp), step, page);
+}
+
+void
+tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("tweaks_changed_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ const gchar *name = gtk_widget_get_name(widget);
+ ghb_pref_save(ud->settings, name);
}
void
gtk_progress_bar_set_text (progress, "Scanning ...");
gtk_progress_bar_set_fraction (progress, 0);
update_source_label(ud, device);
- ghb_hb_cleanup(TRUE);
prune_logs(ud);
gint preview_count;
preview_count = ghb_settings_get_int(ud->settings, "preview_count");
}
else
{
- ghb_hb_cleanup(TRUE);
prune_logs(ud);
ghb_backend_scan("/dev/null", 0, 1);
}
}
gchar*
-format_vquality_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
+format_drc_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
{
- if (ghb_settings_get_boolean(ud->settings, "directqp"))
+ if (val <= 0.0)
{
- gint vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
- // Only x264 and ffmpeg currently support direct qp/crf entry
- if (vcodec != HB_VCODEC_X264 && vcodec != HB_VCODEC_FFMPEG)
- {
- val *= 100;
- return g_strdup_printf("%.1f", val);
- }
- return g_strdup_printf("%d", (gint)val);
+ return g_strdup_printf("Off");
}
else
{
- val *= 100;
return g_strdup_printf("%.1f", val);
}
}
+gchar*
+format_vquality_cb(GtkScale *scale, gdouble val, signal_user_data_t *ud)
+{
+ gdouble percent;
+
+ gint vcodec = ghb_settings_combo_int(ud->settings, "VideoEncoder");
+ switch (vcodec)
+ {
+ case HB_VCODEC_X264:
+ {
+ gboolean crf;
+ crf = ghb_settings_get_boolean(ud->settings, "constant_rate_factor");
+ percent = 100. * (51 - val) / 51.;
+ if (crf)
+ return g_strdup_printf("RF: %.4g (%.0f%%)", val, percent);
+ else
+ return g_strdup_printf("QP: %.4g (%.0f%%)", val, percent);
+ } break;
+
+ case HB_VCODEC_XVID:
+ case HB_VCODEC_FFMPEG:
+ {
+ percent = 100. * (30 - (val - 1)) / 30.;
+ return g_strdup_printf("QP: %d (%.0f%%)", (int)val, percent);
+ } break;
+
+ case HB_VCODEC_THEORA:
+ {
+ percent = 100. * val / 63.;
+ return g_strdup_printf("QP: %d (%.0f%%)", (int)val, percent);
+ } break;
+
+ default:
+ {
+ percent = 0;
+ } break;
+ }
+ return g_strdup_printf("QP: %.1f / %.1f%%", val, percent);
+}
+
static void
html_link_cb(GtkHTML *html, const gchar *url, signal_user_data_t *ud)
{
if (ud->appcast == NULL || ud->appcast_len < 15 ||
strncmp(&(ud->appcast[9]), "200 OK", 6))
{
- if (!stable_update_lock && HB_BUILD % 100)
+ if (!stable_update_lock && hb_get_build(NULL) % 100)
g_idle_add((GSourceFunc)check_stable_update, ud);
goto done;
}
ibuild = g_strtod(build, NULL);
skip = ghb_settings_get_int(ud->settings, "update_skip_version");
if (description == NULL || build == NULL || version == NULL
- || ibuild <= HB_BUILD || skip == ibuild)
+ || ibuild <= hb_get_build(NULL) || skip == ibuild)
{
- if (!stable_update_lock && HB_BUILD % 100)
+ if (!stable_update_lock && hb_get_build(NULL) % 100)
g_thread_create((GThreadFunc)check_stable_update, ud, FALSE, NULL);
goto done;
}
msg = g_strdup_printf("HandBrake %s/%s is now available (you have %s/%d).",
- version, build, HB_VERSION, HB_BUILD);
+ version, build, hb_get_version(NULL), hb_get_build(NULL));
label = GHB_WIDGET(ud->builder, "update_message");
gtk_label_set_text(GTK_LABEL(label), msg);
html = gtk_html_new_from_string(description, -1);
GError *gerror = NULL;
g_debug("ghb_check_update");
- if (HB_BUILD % 100)
+ if (hb_get_build(NULL) % 100)
{
query =
"GET /appcast_unstable.xml HTTP/1.0\r\nHost: handbrake.fr\r\n\r\n";
return NULL;
}
+void
+status_activate_cb(GtkStatusIcon *si, signal_user_data_t *ud)
+{
+ GtkWindow *window;
+
+ window = GTK_WINDOW(GHB_WIDGET(ud->builder, "hb_window"));
+ gtk_window_present(window);
+}
+
+static void
+notify_closed_cb(NotifyNotification *notification, signal_user_data_t *ud)
+{
+ g_object_unref(G_OBJECT(notification));
+}
+
+void
+ghb_notify_done(signal_user_data_t *ud)
+{
+ NotifyNotification *notification;
+ GtkStatusIcon *si;
+
+ si = GTK_STATUS_ICON(GHB_OBJECT(ud->builder, "hb_status"));
+ gtk_status_icon_set_from_icon_name(si, "hb-status-empty");
+ notification = notify_notification_new(
+ "Encode Complete",
+ "Put down that cocktail, Your HandBrake queue is done!",
+ "hb-icon",
+ NULL);
+ notify_notification_attach_to_status_icon(notification, si);
+ g_signal_connect(notification, "closed", (GCallback)notify_closed_cb, ud);
+ notify_notification_show(notification, NULL);
+}