summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2008-09-13 20:04:28 +0000
committerjstebbins <[email protected]>2008-09-13 20:04:28 +0000
commit91ca41626288377d6a7c24bc76677e8f90378460 (patch)
treefab0e4f122b3fd80a580bdb685e8e060a3640153
parent3feae357a5d62add8c0bc32753b2b679bdb8aa9a (diff)
LinGui: Add queue drag n drop reordering
Also add option to add chapter numbers to auto-generated destination name git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1693 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--gtk/src/Makefile.am3
-rw-r--r--gtk/src/callbacks.c335
-rw-r--r--gtk/src/ghb.ui29
-rw-r--r--gtk/src/internal_defaults.xml2
-rw-r--r--gtk/src/main.c15
-rw-r--r--gtk/src/makedeps.c1
-rw-r--r--gtk/src/resource_data.h57
-rw-r--r--gtk/src/resources.plist43
-rw-r--r--gtk/src/values.c13
-rw-r--r--gtk/src/values.h1
-rw-r--r--gtk/src/widget_deps4
-rw-r--r--gtk/src/widget_reverse_deps8
12 files changed, 448 insertions, 63 deletions
diff --git a/gtk/src/Makefile.am b/gtk/src/Makefile.am
index e5bc963e0..0886e666c 100644
--- a/gtk/src/Makefile.am
+++ b/gtk/src/Makefile.am
@@ -146,6 +146,9 @@ resources.c: resource_data.h
resource_data.h: quotestring resources.plist
./quotestring resources.plist resource_data.h
+widget_deps: makewidgetdeps
+ ./makewidgetdeps
+
resources.plist: create_resources resources.list $(icons_dep) internal_defaults.xml standard_presets.xml ghb.ui widget_deps widget_reverse_deps
./create_resources resources.list resources.plist
diff --git a/gtk/src/callbacks.c b/gtk/src/callbacks.c
index 238f36f67..05a7cba73 100644
--- a/gtk/src/callbacks.c
+++ b/gtk/src/callbacks.c
@@ -41,6 +41,7 @@ static GList* dvd_device_list();
static gboolean cancel_encode();
static void audio_list_refresh_selected(signal_user_data_t *ud);
static GValue* get_selected_asettings(signal_user_data_t *ud);
+static gint find_last_finished(GValue *queue);
// This is a dependency map used for greying widgets
// that are dependent on the state of another widget.
@@ -260,16 +261,16 @@ on_quit1_activate(GtkMenuItem *quit, signal_user_data_t *ud)
{
gint state = ghb_get_queue_state();
g_debug("on_quit1_activate ()");
- if (state & GHB_STATE_WORKING)
- {
- if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
- {
+ if (state & GHB_STATE_WORKING)
+ {
+ if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
+ {
ghb_hb_cleanup(FALSE);
- gtk_main_quit();
- return;
- }
- return;
- }
+ gtk_main_quit();
+ return;
+ }
+ return;
+ }
ghb_hb_cleanup(FALSE);
gtk_main_quit();
}
@@ -287,7 +288,27 @@ set_destination(signal_user_data_t *ud)
extension = ghb_settings_get_string(ud->settings, "container");
dir = g_path_get_dirname (filename);
vol_name = ghb_settings_get_string(ud->settings, "volume_label");
- new_name = g_strdup_printf("%s/%s.%s", dir, vol_name, extension);
+ if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+ {
+ gint start, end;
+
+ start = ghb_settings_get_int(ud->settings, "start_chapter");
+ end = ghb_settings_get_int(ud->settings, "end_chapter");
+ if (start == end)
+ {
+ new_name = g_strdup_printf("%s/%s-%d.%s",
+ dir, vol_name, start, extension);
+ }
+ else
+ {
+ new_name = g_strdup_printf("%s/%s-%d-%d.%s",
+ dir, vol_name, start, end, extension);
+ }
+ }
+ else
+ {
+ new_name = g_strdup_printf("%s/%s.%s", dir, vol_name, extension);
+ }
ghb_ui_update(ud, "destination", ghb_string_value(new_name));
g_free(filename);
g_free(extension);
@@ -743,11 +764,11 @@ destination_browse_clicked_cb(GtkButton *button, signal_user_data_t *ud)
g_debug("destination_browse_clicked_cb ()");
destname = ghb_settings_get_string(ud->settings, "destination");
dialog = gtk_file_chooser_dialog_new ("Choose Destination",
- NULL,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), destname);
basename = g_path_get_basename(destname);
g_free(destname);
@@ -778,7 +799,7 @@ window_destroy_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *
g_debug("window_destroy_event_cb ()");
ghb_hb_cleanup(FALSE);
gtk_main_quit();
- return FALSE;
+ return FALSE;
}
gboolean
@@ -786,19 +807,19 @@ window_delete_event_cb(GtkWidget *widget, GdkEvent *event, signal_user_data_t *u
{
gint state = ghb_get_queue_state();
g_debug("window_delete_event_cb ()");
- if (state & GHB_STATE_WORKING)
- {
- if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
- {
+ if (state & GHB_STATE_WORKING)
+ {
+ if (cancel_encode("Closing HandBrake will terminate encoding.\n"))
+ {
ghb_hb_cleanup(FALSE);
- gtk_main_quit();
- return FALSE;
- }
- return TRUE;
- }
+ gtk_main_quit();
+ return FALSE;
+ }
+ return TRUE;
+ }
ghb_hb_cleanup(FALSE);
gtk_main_quit();
- return FALSE;
+ return FALSE;
}
static void
@@ -1292,7 +1313,7 @@ validate_filter_widget(signal_user_data_t *ud, const gchar *name)
gboolean
deint_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
- signal_user_data_t *ud)
+ signal_user_data_t *ud)
{
g_debug("deint_tweak_focus_out_cb ()");
validate_filter_widget(ud, "tweak_deinterlace");
@@ -1301,7 +1322,7 @@ deint_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
gboolean
denoise_tweak_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
- signal_user_data_t *ud)
+ signal_user_data_t *ud)
{
g_debug("denoise_tweak_focus_out_cb ()");
validate_filter_widget(ud, "tweak_noise");
@@ -1385,6 +1406,10 @@ start_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
start = ghb_settings_get_int(ud->settings, "start_chapter");
gtk_spin_button_set_range (GTK_SPIN_BUTTON(end_ch), start, end);
check_dependency(ud, widget);
+ if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+ {
+ set_destination(ud);
+ }
}
void
@@ -1399,6 +1424,10 @@ end_chapter_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
end = ghb_settings_get_int(ud->settings, "end_chapter");
gtk_spin_button_set_range (GTK_SPIN_BUTTON(start_ch), start, end);
check_dependency(ud, widget);
+ if (ghb_settings_get_boolean(ud->settings, "chapters_in_destination"))
+ {
+ set_destination(ud);
+ }
}
void
@@ -1513,7 +1542,7 @@ generic_entry_changed_cb(GtkEntry *entry, signal_user_data_t *ud)
gboolean
generic_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
- signal_user_data_t *ud)
+ signal_user_data_t *ud)
{
g_debug("generic_focus_out_cb ()");
ghb_widget_to_setting(ud->settings, widget);
@@ -1567,7 +1596,7 @@ x264_entry_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
gboolean
x264_focus_out_cb(GtkWidget *widget, GdkEventFocus *event,
- signal_user_data_t *ud)
+ signal_user_data_t *ud)
{
gchar *options, *sopts;
@@ -1689,7 +1718,7 @@ audio_list_refresh_selected(signal_user_data_t *ud)
gchar *track, *codec, *br, *sr, *mix, *drc;
gchar *s_track, *s_codec, *s_br, *s_sr, *s_mix;
gdouble s_drc;
- // Get the row number
+ // Get the row number
treepath = gtk_tree_model_get_path (store, &iter);
indices = gtk_tree_path_get_indices (treepath);
row = indices[0];
@@ -1763,7 +1792,7 @@ get_selected_asettings(signal_user_data_t *ud)
selection = gtk_tree_view_get_selection (treeview);
if (gtk_tree_selection_get_selected(selection, &store, &iter))
{
- // Get the row number
+ // Get the row number
treepath = gtk_tree_model_get_path (store, &iter);
indices = gtk_tree_path_get_indices (treepath);
row = indices[0];
@@ -1888,7 +1917,7 @@ audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
{
gtk_tree_selection_select_iter (selection, &nextIter);
}
- // Get the row number
+ // Get the row number
treepath = gtk_tree_model_get_path (store, &iter);
indices = gtk_tree_path_get_indices (treepath);
row = indices[0];
@@ -1902,6 +1931,8 @@ audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
audio_list = ghb_settings_get_value(ud->settings, "audio_list");
if (row >= ghb_array_len(audio_list))
return;
+ GValue *old = ghb_array_get_nth(audio_list, row);
+ ghb_value_free(old);
ghb_array_remove(audio_list, row);
}
}
@@ -2329,13 +2360,14 @@ queue_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t
}
static void
-add_to_queue_list(signal_user_data_t *ud, GValue *settings)
+add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
{
GtkTreeView *treeview;
GtkTreeIter iter;
GtkTreeStore *store;
gchar *info;
gint num_pass = 1;
+ gint status;
gint ii;
GtkTreeIter citer;
gchar *vcodec, *container, *acodec, *dest, *preset, *vol_name;
@@ -2360,8 +2392,31 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings)
pass2 ? 2:1, pass2 ? "Passes":"Pass"
);
- gtk_tree_store_append(store, &iter, NULL);
- gtk_tree_store_set(store, &iter, 0, "hb-queue-job", 1, info, 2, "hb-queue-delete", -1);
+ if (piter)
+ iter = *piter;
+ else
+ gtk_tree_store_append(store, &iter, NULL);
+
+ gtk_tree_store_set(store, &iter, 1, info, 2, "hb-queue-delete", -1);
+ status = ghb_settings_get_int(settings, "job_status");
+ switch (status)
+ {
+ case GHB_QUEUE_PENDING:
+ gtk_tree_store_set(store, &iter, 0, "hb-queue-job", -1);
+ break;
+ case GHB_QUEUE_CANCELED:
+ gtk_tree_store_set(store, &iter, 0, "hb-canceled", -1);
+ break;
+ case GHB_QUEUE_RUNNING:
+ gtk_tree_store_set(store, &iter, 0, "hb-working0", -1);
+ break;
+ case GHB_QUEUE_DONE:
+ gtk_tree_store_set(store, &iter, 0, "hb-complete", -1);
+ break;
+ default:
+ gtk_tree_store_set(store, &iter, 0, "hb-queue-job", -1);
+ break;
+ }
g_free(info);
vcodec = ghb_settings_get_combo_option(settings, "video_codec");
@@ -2722,7 +2777,7 @@ queue_add(signal_user_data_t *ud)
titlenum = ghb_get_title_number(titleindex);
ghb_settings_set_int(settings, "titlenum", titlenum);
ghb_array_append(ud->queue, settings);
- add_to_queue_list(ud, settings);
+ add_to_queue_list(ud, settings, NULL);
ghb_save_queue(ud->queue);
return TRUE;
@@ -2800,7 +2855,10 @@ queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
// Remove the selected item
gtk_tree_store_remove(GTK_TREE_STORE(store), &iter);
// Remove the corresponding item from the queue list
+ GValue *old = ghb_array_get_nth(ud->queue, row);
+ ghb_value_free(old);
ghb_array_remove(ud->queue, row);
+ ghb_save_queue(ud->queue);
}
else
{
@@ -2808,6 +2866,202 @@ queue_remove_clicked_cb(GtkWidget *widget, gchar *path, signal_user_data_t *ud)
}
}
+// This little bit is needed to prevent the default drag motion
+// handler from expanding rows if you hover over them while
+// dragging.
+// Also controls where valid drop locations are
+gboolean
+queue_drag_motion_cb(
+ GtkTreeView *tv,
+ GdkDragContext *ctx,
+ gint x,
+ gint y,
+ guint time,
+ signal_user_data_t *ud)
+{
+ GtkTreePath *path = NULL;
+ GtkTreeViewDropPosition pos;
+ gint *indices, row, status, finished;
+ GValue *js;
+ GtkTreeIter iter;
+ GtkTreeView *srctv;
+ GtkTreeModel *model;
+ GtkTreeSelection *select;
+
+ // This bit checks to see if the source is allowed to be
+ // moved. Only pending and canceled items may be moved.
+ srctv = GTK_TREE_VIEW(gtk_drag_get_source_widget(ctx));
+ select = gtk_tree_view_get_selection (srctv);
+ gtk_tree_selection_get_selected (select, &model, &iter);
+ path = gtk_tree_model_get_path (model, &iter);
+ indices = gtk_tree_path_get_indices(path);
+ row = indices[0];
+ gtk_tree_path_free(path);
+ js = ghb_array_get_nth(ud->queue, row);
+ status = ghb_settings_get_int(js, "job_status");
+ if (status != GHB_QUEUE_PENDING && status != GHB_QUEUE_CANCELED)
+ {
+ gdk_drag_status(ctx, 0, time);
+ return TRUE;
+ }
+
+ // The reset checks that the destination is a valid position
+ // in the list. Can not move above any finished or running items
+ gtk_tree_view_get_dest_row_at_pos (tv, x, y, &path, &pos);
+ if (path == NULL)
+ {
+ gdk_drag_status(ctx, GDK_ACTION_MOVE, time);
+ return TRUE;
+ }
+ indices = gtk_tree_path_get_indices(path);
+ row = indices[0];
+ js = ghb_array_get_nth(ud->queue, row);
+
+ finished = find_last_finished(ud->queue);
+ if (row < finished)
+ {
+ gtk_tree_path_free(path);
+ gdk_drag_status(ctx, 0, time);
+ return TRUE;
+ }
+ if (pos != GTK_TREE_VIEW_DROP_AFTER &&
+ row == finished)
+ {
+ gtk_tree_path_free(path);
+ gdk_drag_status(ctx, 0, time);
+ return TRUE;
+ }
+ gtk_tree_view_set_drag_dest_row(tv, path, pos);
+ gtk_tree_path_free(path);
+ gdk_drag_status(ctx, GDK_ACTION_MOVE, time);
+ return TRUE;
+}
+
+void
+queue_drag_cb(
+ GtkTreeView *dstwidget,
+ GdkDragContext *dc,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info, guint t,
+ signal_user_data_t *ud)
+{
+ GtkTreePath *path = NULL;
+ //GtkTreeModel *model;
+ GtkTreeViewDropPosition pos;
+ GtkTreeIter dstiter, srciter;
+ gint *indices, row;
+ GValue *js;
+
+ GtkTreeModel *dstmodel = gtk_tree_view_get_model(dstwidget);
+
+ g_debug("queue_drag_cb ()");
+ // This doesn't work here for some reason...
+ // gtk_tree_view_get_drag_dest_row(dstwidget, &path, &pos);
+ gtk_tree_view_get_dest_row_at_pos (dstwidget, x, y, &path, &pos);
+ // This little hack is needed because attempting to drop after
+ // the last item gives us no path or pos.
+ if (path == NULL)
+ {
+ gint n_children;
+
+ n_children = gtk_tree_model_iter_n_children(dstmodel, NULL);
+ if (n_children)
+ {
+ pos = GTK_TREE_VIEW_DROP_AFTER;
+ path = gtk_tree_path_new_from_indices(n_children-1, -1);
+ }
+ else
+ {
+ pos = GTK_TREE_VIEW_DROP_BEFORE;
+ path = gtk_tree_path_new_from_indices(0, -1);
+ }
+ }
+ if (path)
+ {
+ if (gtk_tree_path_get_depth(path) > 1)
+ gtk_tree_path_up(path);
+ if (gtk_tree_model_get_iter (dstmodel, &dstiter, path))
+ {
+ GtkTreeIter iter;
+ GtkTreeView *srcwidget;
+ GtkTreeModel *srcmodel;
+ GtkTreeSelection *select;
+ GtkTreePath *srcpath = NULL;
+ GtkTreePath *dstpath = NULL;
+
+ srcwidget = GTK_TREE_VIEW(gtk_drag_get_source_widget(dc));
+ //srcmodel = gtk_tree_view_get_model(srcwidget);
+ select = gtk_tree_view_get_selection (srcwidget);
+ gtk_tree_selection_get_selected (select, &srcmodel, &srciter);
+
+ srcpath = gtk_tree_model_get_path (srcmodel, &srciter);
+ indices = gtk_tree_path_get_indices(srcpath);
+ row = indices[0];
+ gtk_tree_path_free(srcpath);
+ js = ghb_array_get_nth(ud->queue, row);
+
+ switch (pos)
+ {
+ case GTK_TREE_VIEW_DROP_BEFORE:
+ case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
+ gtk_tree_store_insert_before (GTK_TREE_STORE (dstmodel),
+ &iter, NULL, &dstiter);
+ break;
+
+ case GTK_TREE_VIEW_DROP_AFTER:
+ case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
+ gtk_tree_store_insert_after (GTK_TREE_STORE (dstmodel),
+ &iter, NULL, &dstiter);
+ break;
+
+ default:
+ break;
+ }
+ // Reset job to pending
+ ghb_settings_set_int(js, "job_status", GHB_QUEUE_PENDING);
+ add_to_queue_list(ud, js, &iter);
+
+ dstpath = gtk_tree_model_get_path (dstmodel, &iter);
+ indices = gtk_tree_path_get_indices(dstpath);
+ row = indices[0];
+ gtk_tree_path_free(dstpath);
+ ghb_array_insert(ud->queue, row, js);
+
+ srcpath = gtk_tree_model_get_path (srcmodel, &srciter);
+ indices = gtk_tree_path_get_indices(srcpath);
+ row = indices[0];
+ gtk_tree_path_free(srcpath);
+ ghb_array_remove(ud->queue, row);
+ gtk_tree_store_remove (GTK_TREE_STORE (srcmodel), &srciter);
+ ghb_save_queue(ud->queue);
+ }
+ gtk_tree_path_free(path);
+ }
+}
+
+
+static gint
+find_last_finished(GValue *queue)
+{
+ GValue *js;
+ gint ii, count;
+ gint status;
+
+ g_debug("find_last_finished");
+ count = ghb_array_len(queue);
+ for (ii = 0; ii < count; ii++)
+ {
+ js = ghb_array_get_nth(queue, ii);
+ status = ghb_settings_get_int(js, "job_status");
+ if (status != GHB_QUEUE_DONE && status != GHB_QUEUE_RUNNING)
+ {
+ return ii-1;
+ }
+ }
+ return -1;
+}
+
static gint
find_queue_job(GValue *queue, gint unique_id, GValue **job)
{
@@ -3166,7 +3420,7 @@ ghb_backend_events(signal_user_data_t *ud)
queue_buttons_grey(ud, TRUE);
}
index = find_queue_job(ud->queue, status.unique_id, &js);
- if (index >= 0)
+ if (status.unique_id != 0 && index >= 0)
{
gchar working_icon[] = "hb-working0";
working_icon[10] = '0' + working;
@@ -3728,6 +3982,7 @@ pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
{
g_debug("pref_changed_cb");
ghb_widget_to_setting (ud->settings, widget);
+ check_dependency(ud, widget);
const gchar *name = gtk_widget_get_name(widget);
ghb_pref_save(ud->settings, name);
}
@@ -4112,6 +4367,8 @@ ghb_reload_queue(signal_user_data_t *ud)
status = ghb_settings_get_int(settings, "job_status");
if (status == GHB_QUEUE_DONE || status == GHB_QUEUE_CANCELED)
{
+ GValue *old = ghb_array_get_nth(queue, ii);
+ ghb_value_free(old);
ghb_array_remove(queue, ii);
}
}
@@ -4121,7 +4378,7 @@ ghb_reload_queue(signal_user_data_t *ud)
settings = ghb_array_get_nth(queue, ii);
ghb_settings_set_int(settings, "job_unique_id", 0);
ghb_settings_set_int(settings, "job_status", GHB_QUEUE_PENDING);
- add_to_queue_list(ud, settings);
+ add_to_queue_list(ud, settings, NULL);
}
queue_buttons_grey(ud, FALSE);
}
diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui
index 38657f8a8..53fb8dc87 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -3447,12 +3447,26 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1</property>
<property name="tooltip_text">The destination filename will be automatically
generated from the source filename or volume
label.</property>
- <property name="label" translatable="yes">Derive destination name from source</property>
+ <property name="label" translatable="yes">Automatically generate destination</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="pref_changed_cb"/>
</object>
</child>
<child>
+ <object class="GtkCheckButton" id="chapters_in_destination">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text">Add chapter numbers to the
+auto-generated destination name.</property>
+ <property name="label" translatable="yes">Add chapters to destination name</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="pref_changed_cb"/>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkCheckButton" id="linear_vquality">
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -3465,7 +3479,7 @@ video codecs.</property>
<signal name="toggled" handler="pref_changed_cb"/>
</object>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -3482,7 +3496,7 @@ the required multiple.</property>
<signal name="toggled" handler="pref_changed_cb"/>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child>
@@ -3501,7 +3515,7 @@ this setting.</property>
<signal name="toggled" handler="vcodec_changed_cb"/>
</object>
<packing>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
<child>
@@ -3512,7 +3526,7 @@ this setting.</property>
<signal name="toggled" handler="tweaks_changed_cb"/>
</object>
<packing>
- <property name="position">4</property>
+ <property name="position">5</property>
</packing>
</child>
<child>
@@ -3523,7 +3537,7 @@ this setting.</property>
<signal name="toggled" handler="hbfd_feature_changed_cb"/>
</object>
<packing>
- <property name="position">5</property>
+ <property name="position">6</property>
</packing>
</child>
</object>
@@ -3949,7 +3963,8 @@ this setting.</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">True</property>
+ <property name="headers_clickable">False</property>
+ <property name="hover_expand">False</property>
</object>
</child>
</object>
diff --git a/gtk/src/internal_defaults.xml b/gtk/src/internal_defaults.xml
index b3dc60d79..b562117e6 100644
--- a/gtk/src/internal_defaults.xml
+++ b/gtk/src/internal_defaults.xml
@@ -72,6 +72,8 @@
<dict>
<key>allow_tweaks</key>
<false />
+ <key>chapters_in_destination</key>
+ <false />
<key>default_preset</key>
<string>Normal</string>
<key>default_source</key>
diff --git a/gtk/src/main.c b/gtk/src/main.c
index 23ed044db..6dd4aa293 100644
--- a/gtk/src/main.c
+++ b/gtk/src/main.c
@@ -225,6 +225,8 @@ bind_chapter_tree_model (signal_user_data_t *ud)
extern void queue_list_selection_changed_cb(void);
extern void queue_remove_clicked_cb(void);
extern void queue_list_size_allocate_cb(void);
+extern void queue_drag_cb(void);
+extern void queue_drag_motion_cb(void);
// Create and bind the tree model to the tree view for the queue list
// Also, connect up the signal that lets us know the selection has changed
@@ -236,6 +238,9 @@ bind_queue_tree_model (signal_user_data_t *ud)
GtkTreeStore *treestore;
GtkTreeView *treeview;
GtkTreeSelection *selection;
+ GtkTargetEntry SrcEntry;
+ SrcEntry.target = "DATA";
+ SrcEntry.flags = GTK_TARGET_SAME_WIDGET;
g_debug("bind_queue_tree_model ()\n");
treeview = GTK_TREE_VIEW(GHB_WIDGET (ud->builder, "queue_list"));
@@ -265,9 +270,17 @@ bind_queue_tree_model (signal_user_data_t *ud)
gtk_tree_view_column_set_min_width (column, 24);
gtk_tree_view_append_column(treeview, GTK_TREE_VIEW_COLUMN(column));
+ gtk_tree_view_enable_model_drag_dest (treeview, &SrcEntry, 1,
+ GDK_ACTION_MOVE);
+ gtk_tree_view_enable_model_drag_source (treeview, GDK_BUTTON1_MASK,
+ &SrcEntry, 1, GDK_ACTION_MOVE);
+
g_signal_connect(selection, "changed", queue_list_selection_changed_cb, ud);
g_signal_connect(cell, "clicked", queue_remove_clicked_cb, ud);
- g_signal_connect(treeview, "size-allocate", queue_list_size_allocate_cb, textcell);
+ g_signal_connect(treeview, "size-allocate", queue_list_size_allocate_cb,
+ textcell);
+ g_signal_connect(treeview, "drag_data_received", queue_drag_cb, ud);
+ g_signal_connect(treeview, "drag_motion", queue_drag_motion_cb, ud);
}
extern void audio_list_selection_changed_cb(void);
diff --git a/gtk/src/makedeps.c b/gtk/src/makedeps.c
index 8637ccc2e..e3460ef14 100644
--- a/gtk/src/makedeps.c
+++ b/gtk/src/makedeps.c
@@ -69,6 +69,7 @@ static dependency_t dep_map[] =
{"x264_analyse", "x264_direct", "none", TRUE},
{"x264_me", "x264_merange", "umh|esa", FALSE},
{"chapter_markers", "chapters_list", "TRUE", FALSE},
+ {"use_source_name", "chapters_in_destination", "TRUE", FALSE},
};
int
diff --git a/gtk/src/resource_data.h b/gtk/src/resource_data.h
index c43133483..3fcad2968 100644
--- a/gtk/src/resource_data.h
+++ b/gtk/src/resource_data.h
@@ -5678,8 +5678,8 @@
"generated from the source filename or volume\n"
"label.&lt;/property&gt;\n"
" &lt;property name=&quot;label&quot; transla"
-"table=&quot;yes&quot;&gt;Derive destination name from source&lt;/proper"
-"ty&gt;\n"
+"table=&quot;yes&quot;&gt;Automatically generate destination&lt;/propert"
+"y&gt;\n"
" &lt;property name=&quot;draw_indicator&quot"
";&gt;True&lt;/property&gt;\n"
" &lt;signal name=&quot;toggled&quot; handler"
@@ -5688,6 +5688,29 @@
" &lt;/child&gt;\n"
" &lt;child&gt;\n"
" &lt;object class=&quot;GtkCheckButton&quot; i"
+"d=&quot;chapters_in_destination&quot;&gt;\n"
+" &lt;property name=&quot;visible&quot;&gt;Tr"
+"ue&lt;/property&gt;\n"
+" &lt;property name=&quot;can_focus&quot;&gt;"
+"True&lt;/property&gt;\n"
+" &lt;property name=&quot;tooltip_text&quot;&"
+"gt;Add chapter numbers to the \n"
+"auto-generated destination name.&lt;/property&gt;\n"
+" &lt;property name=&quot;label&quot; transla"
+"table=&quot;yes&quot;&gt;Add chapters to destination name&lt;/property&"
+"gt;\n"
+" &lt;property name=&quot;draw_indicator&quot"
+";&gt;True&lt;/property&gt;\n"
+" &lt;signal name=&quot;toggled&quot; handler"
+"=&quot;pref_changed_cb&quot;/&gt;\n"
+" &lt;/object&gt;\n"
+" &lt;packing&gt;\n"
+" &lt;property name=&quot;position&quot;&gt;1"
+"&lt;/property&gt;\n"
+" &lt;/packing&gt;\n"
+" &lt;/child&gt;\n"
+" &lt;child&gt;\n"
+" &lt;object class=&quot;GtkCheckButton&quot; i"
"d=&quot;linear_vquality&quot;&gt;\n"
" &lt;property name=&quot;visible&quot;&gt;Tr"
"ue&lt;/property&gt;\n"
@@ -5707,7 +5730,7 @@
"=&quot;pref_changed_cb&quot;/&gt;\n"
" &lt;/object&gt;\n"
" &lt;packing&gt;\n"
-" &lt;property name=&quot;position&quot;&gt;1"
+" &lt;property name=&quot;position&quot;&gt;2"
"&lt;/property&gt;\n"
" &lt;/packing&gt;\n"
" &lt;/child&gt;\n"
@@ -5732,7 +5755,7 @@
"=&quot;pref_changed_cb&quot;/&gt;\n"
" &lt;/object&gt;\n"
" &lt;packing&gt;\n"
-" &lt;property name=&quot;position&quot;&gt;2"
+" &lt;property name=&quot;position&quot;&gt;3"
"&lt;/property&gt;\n"
" &lt;/packing&gt;\n"
" &lt;/child&gt;\n"
@@ -5759,7 +5782,7 @@
"=&quot;vcodec_changed_cb&quot;/&gt;\n"
" &lt;/object&gt;\n"
" &lt;packing&gt;\n"
-" &lt;property name=&quot;position&quot;&gt;3"
+" &lt;property name=&quot;position&quot;&gt;4"
"&lt;/property&gt;\n"
" &lt;/packing&gt;\n"
" &lt;/child&gt;\n"
@@ -5776,7 +5799,7 @@
"=&quot;tweaks_changed_cb&quot;/&gt;\n"
" &lt;/object&gt;\n"
" &lt;packing&gt;\n"
-" &lt;property name=&quot;position&quot;&gt;4"
+" &lt;property name=&quot;position&quot;&gt;5"
"&lt;/property&gt;\n"
" &lt;/packing&gt;\n"
" &lt;/child&gt;\n"
@@ -5793,7 +5816,7 @@
"=&quot;hbfd_feature_changed_cb&quot;/&gt;\n"
" &lt;/object&gt;\n"
" &lt;packing&gt;\n"
-" &lt;property name=&quot;position&quot;&gt;5"
+" &lt;property name=&quot;position&quot;&gt;6"
"&lt;/property&gt;\n"
" &lt;/packing&gt;\n"
" &lt;/child&gt;\n"
@@ -6487,8 +6510,10 @@
"UTTON_RELEASE_MASK&lt;/property&gt;\n"
" &lt;property name=&quot;headers_visible&quot;&gt;False&"
"lt;/property&gt;\n"
-" &lt;property name=&quot;headers_clickable&quot;&gt;True"
-"&lt;/property&gt;\n"
+" &lt;property name=&quot;headers_clickable&quot;&gt;Fals"
+"e&lt;/property&gt;\n"
+" &lt;property name=&quot;hover_expand&quot;&gt;False&lt;"
+"/property&gt;\n"
" &lt;/object&gt;\n"
" &lt;/child&gt;\n"
" &lt;/object&gt;\n"
@@ -9988,6 +10013,8 @@
" <dict>\n"
" <key>allow_tweaks</key>\n"
" <false />\n"
+" <key>chapters_in_destination</key>\n"
+" <false />\n"
" <key>default_preset</key>\n"
" <string>Normal</string>\n"
" <key>default_source</key>\n"
@@ -11513,6 +11540,10 @@
" <array>\n"
" <string>turbo</string>\n"
" </array>\n"
+" <key>use_source_name</key>\n"
+" <array>\n"
+" <string>chapters_in_destination</string>\n"
+" </array>\n"
" <key>variable_frame_rate</key>\n"
" <array>\n"
" <string>framerate</string>\n"
@@ -11602,6 +11633,14 @@
" <true />\n"
" </array>\n"
" </array>\n"
+" <key>chapters_in_destination</key>\n"
+" <array>\n"
+" <array>\n"
+" <string>use_source_name</string>\n"
+" <string>TRUE</string>\n"
+" <false />\n"
+" </array>\n"
+" </array>\n"
" <key>chapters_label</key>\n"
" <array>\n"
" <array>\n"
diff --git a/gtk/src/resources.plist b/gtk/src/resources.plist
index 55fa5bbb5..788ed8f83 100644
--- a/gtk/src/resources.plist
+++ b/gtk/src/resources.plist
@@ -3452,12 +3452,26 @@ no-fast-pskip=0:no-dct-decimate=0:cabac=1&lt;/property&gt;
&lt;property name=&quot;tooltip_text&quot;&gt;The destination filename will be automatically
generated from the source filename or volume
label.&lt;/property&gt;
- &lt;property name=&quot;label&quot; translatable=&quot;yes&quot;&gt;Derive destination name from source&lt;/property&gt;
+ &lt;property name=&quot;label&quot; translatable=&quot;yes&quot;&gt;Automatically generate destination&lt;/property&gt;
&lt;property name=&quot;draw_indicator&quot;&gt;True&lt;/property&gt;
&lt;signal name=&quot;toggled&quot; handler=&quot;pref_changed_cb&quot;/&gt;
&lt;/object&gt;
&lt;/child&gt;
&lt;child&gt;
+ &lt;object class=&quot;GtkCheckButton&quot; id=&quot;chapters_in_destination&quot;&gt;
+ &lt;property name=&quot;visible&quot;&gt;True&lt;/property&gt;
+ &lt;property name=&quot;can_focus&quot;&gt;True&lt;/property&gt;
+ &lt;property name=&quot;tooltip_text&quot;&gt;Add chapter numbers to the
+auto-generated destination name.&lt;/property&gt;
+ &lt;property name=&quot;label&quot; translatable=&quot;yes&quot;&gt;Add chapters to destination name&lt;/property&gt;
+ &lt;property name=&quot;draw_indicator&quot;&gt;True&lt;/property&gt;
+ &lt;signal name=&quot;toggled&quot; handler=&quot;pref_changed_cb&quot;/&gt;
+ &lt;/object&gt;
+ &lt;packing&gt;
+ &lt;property name=&quot;position&quot;&gt;1&lt;/property&gt;
+ &lt;/packing&gt;
+ &lt;/child&gt;
+ &lt;child&gt;
&lt;object class=&quot;GtkCheckButton&quot; id=&quot;linear_vquality&quot;&gt;
&lt;property name=&quot;visible&quot;&gt;True&lt;/property&gt;
&lt;property name=&quot;can_focus&quot;&gt;True&lt;/property&gt;
@@ -3470,7 +3484,7 @@ video codecs.&lt;/property&gt;
&lt;signal name=&quot;toggled&quot; handler=&quot;pref_changed_cb&quot;/&gt;
&lt;/object&gt;
&lt;packing&gt;
- &lt;property name=&quot;position&quot;&gt;1&lt;/property&gt;
+ &lt;property name=&quot;position&quot;&gt;2&lt;/property&gt;
&lt;/packing&gt;
&lt;/child&gt;
&lt;child&gt;
@@ -3487,7 +3501,7 @@ the required multiple.&lt;/property&gt;
&lt;signal name=&quot;toggled&quot; handler=&quot;pref_changed_cb&quot;/&gt;
&lt;/object&gt;
&lt;packing&gt;
- &lt;property name=&quot;position&quot;&gt;2&lt;/property&gt;
+ &lt;property name=&quot;position&quot;&gt;3&lt;/property&gt;
&lt;/packing&gt;
&lt;/child&gt;
&lt;child&gt;
@@ -3506,7 +3520,7 @@ this setting.&lt;/property&gt;
&lt;signal name=&quot;toggled&quot; handler=&quot;vcodec_changed_cb&quot;/&gt;
&lt;/object&gt;
&lt;packing&gt;
- &lt;property name=&quot;position&quot;&gt;3&lt;/property&gt;
+ &lt;property name=&quot;position&quot;&gt;4&lt;/property&gt;
&lt;/packing&gt;
&lt;/child&gt;
&lt;child&gt;
@@ -3517,7 +3531,7 @@ this setting.&lt;/property&gt;
&lt;signal name=&quot;toggled&quot; handler=&quot;tweaks_changed_cb&quot;/&gt;
&lt;/object&gt;
&lt;packing&gt;
- &lt;property name=&quot;position&quot;&gt;4&lt;/property&gt;
+ &lt;property name=&quot;position&quot;&gt;5&lt;/property&gt;
&lt;/packing&gt;
&lt;/child&gt;
&lt;child&gt;
@@ -3528,7 +3542,7 @@ this setting.&lt;/property&gt;
&lt;signal name=&quot;toggled&quot; handler=&quot;hbfd_feature_changed_cb&quot;/&gt;
&lt;/object&gt;
&lt;packing&gt;
- &lt;property name=&quot;position&quot;&gt;5&lt;/property&gt;
+ &lt;property name=&quot;position&quot;&gt;6&lt;/property&gt;
&lt;/packing&gt;
&lt;/child&gt;
&lt;/object&gt;
@@ -3954,7 +3968,8 @@ this setting.&lt;/property&gt;
&lt;property name=&quot;can_focus&quot;&gt;True&lt;/property&gt;
&lt;property name=&quot;events&quot;&gt;GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK&lt;/property&gt;
&lt;property name=&quot;headers_visible&quot;&gt;False&lt;/property&gt;
- &lt;property name=&quot;headers_clickable&quot;&gt;True&lt;/property&gt;
+ &lt;property name=&quot;headers_clickable&quot;&gt;False&lt;/property&gt;
+ &lt;property name=&quot;hover_expand&quot;&gt;False&lt;/property&gt;
&lt;/object&gt;
&lt;/child&gt;
&lt;/object&gt;
@@ -4879,6 +4894,8 @@ R2RrUAAABBgBAQACAAAAQAAAABAAAAAQ////AP///wD///8A////AP///wD///8A////AP///wD///8A
<dict>
<key>allow_tweaks</key>
<false />
+ <key>chapters_in_destination</key>
+ <false />
<key>default_preset</key>
<string>Normal</string>
<key>default_source</key>
@@ -6361,6 +6378,10 @@ R2RrUAAABBgBAQACAAAAQAAAABAAAAAQ////AP///wD///8A////AP///wD///8A////AP///wD///8A
<array>
<string>turbo</string>
</array>
+ <key>use_source_name</key>
+ <array>
+ <string>chapters_in_destination</string>
+ </array>
<key>variable_frame_rate</key>
<array>
<string>framerate</string>
@@ -6450,6 +6471,14 @@ R2RrUAAABBgBAQACAAAAQAAAABAAAAAQ////AP///wD///8A////AP///wD///8A////AP///wD///8A
<true />
</array>
</array>
+ <key>chapters_in_destination</key>
+ <array>
+ <array>
+ <string>use_source_name</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
<key>chapters_label</key>
<array>
<array>
diff --git a/gtk/src/values.c b/gtk/src/values.c
index 0f6c43285..1d41d56a8 100644
--- a/gtk/src/values.c
+++ b/gtk/src/values.c
@@ -656,6 +656,19 @@ ghb_array_get_nth(const GValue *gval, gint ii)
}
void
+ghb_array_insert(GValue *gval, guint ii, GValue *val)
+{
+ GArray *arr = g_value_get_boxed(gval);
+ // A little nastyness here. The array pointer
+ // can change when the array changes size. So
+ // I must re-box it in the GValue each time.
+ arr = g_array_insert_val(arr, ii, val);
+ memset(gval, 0, sizeof(GValue));
+ g_value_init(gval, ghb_array_get_type());
+ g_value_take_boxed(gval, arr);
+}
+
+void
ghb_array_append(GValue *gval, GValue *val)
{
GArray *arr = g_value_get_boxed(gval);
diff --git a/gtk/src/values.h b/gtk/src/values.h
index e5b42a711..ceea09467 100644
--- a/gtk/src/values.h
+++ b/gtk/src/values.h
@@ -48,6 +48,7 @@ GType ghb_rawdata_get_type(void);
GType ghb_array_get_type(void);
GType ghb_dict_get_type(void);
GValue* ghb_array_get_nth(const GValue *array, gint ii);
+void ghb_array_insert(GValue *gval, guint ii, GValue *val);
void ghb_array_append(GValue *gval, GValue *val);
void ghb_array_remove(GValue *gval, guint ii);
gint ghb_array_len(const GValue *gval);
diff --git a/gtk/src/widget_deps b/gtk/src/widget_deps
index 228acd329..858175ad4 100644
--- a/gtk/src/widget_deps
+++ b/gtk/src/widget_deps
@@ -65,6 +65,10 @@
<array>
<string>turbo</string>
</array>
+ <key>use_source_name</key>
+ <array>
+ <string>chapters_in_destination</string>
+ </array>
<key>variable_frame_rate</key>
<array>
<string>framerate</string>
diff --git a/gtk/src/widget_reverse_deps b/gtk/src/widget_reverse_deps
index 6b876e952..fb269261f 100644
--- a/gtk/src/widget_reverse_deps
+++ b/gtk/src/widget_reverse_deps
@@ -34,6 +34,14 @@
<true />
</array>
</array>
+ <key>chapters_in_destination</key>
+ <array>
+ <array>
+ <string>use_source_name</string>
+ <string>TRUE</string>
+ <false />
+ </array>
+ </array>
<key>chapters_label</key>
<array>
<array>