[gthumb: 10/15] allow the user to write to disc the current folder recursively
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 10/15] allow the user to write to disc the current folder recursively
- Date: Sun, 28 Feb 2010 20:34:08 +0000 (UTC)
commit 9c490c08e4ae10b455b53af419735535ff1f06a1
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Feb 28 18:09:12 2010 +0100
allow the user to write to disc the current folder recursively
extensions/burn_disc/actions.c | 482 ++++++++++++++------
extensions/burn_disc/data/ui/Makefile.am | 2 +-
.../burn_disc/data/ui/burn-source-selector.ui | 88 ++++
3 files changed, 428 insertions(+), 144 deletions(-)
---
diff --git a/extensions/burn_disc/actions.c b/extensions/burn_disc/actions.c
index 5cdd609..b474ec0 100644
--- a/extensions/burn_disc/actions.c
+++ b/extensions/burn_disc/actions.c
@@ -33,6 +33,150 @@
#include <gthumb.h>
+typedef struct {
+ GthBrowser *browser;
+ GFile *location;
+ GList *files;
+ GtkWidget *dialog;
+ GtkBuilder *builder;
+ GthTest *test;
+ GthFileSource *file_source;
+ char *base_directory;
+ char *current_directory;
+ GHashTable *content;
+ GHashTable *parents;
+ BraseroSessionCfg *session;
+ BraseroTrackDataCfg *track;
+} BurnData;
+
+
+static void
+free_file_list_from_content (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ _g_object_list_unref (value);
+}
+
+
+static void
+burn_data_free (BurnData *data)
+{
+ g_hash_table_foreach (data->content, free_file_list_from_content, NULL);
+ g_hash_table_unref (data->content);
+ g_hash_table_unref (data->parents);
+ g_free (data->current_directory);
+ _g_object_unref (data->file_source);
+ _g_object_unref (data->test);
+ _g_object_unref (data->builder);
+ _g_object_list_unref (data->files);
+ g_free (data->base_directory);
+ g_object_unref (data->location);
+ g_object_unref (data->browser);
+ g_free (data);
+}
+
+
+static void
+add_file_to_track (BurnData *data,
+ const char *parent_uri,
+ const char *relative_subfolder,
+ GFile *file)
+{
+ char *relative_parent;
+ GtkTreePath *tree_path;
+ char *uri;
+
+ relative_parent = g_build_path ("/", parent_uri + strlen (data->base_directory), relative_subfolder, NULL);
+ if (relative_parent != NULL) {
+ char **subfolders;
+ int i;
+ char *subfolder;
+
+ /* add all the subfolders to the track data */
+
+ subfolder = NULL;
+ subfolders = g_strsplit (relative_parent, "/", -1);
+ for (i = 0; subfolders[i] != NULL; i++) {
+ char *subfolder_parent;
+
+ subfolder_parent = subfolder;
+ if (subfolder_parent != NULL)
+ subfolder = g_strconcat (subfolder_parent, "/", subfolders[i], NULL);
+ else
+ subfolder = g_strdup (subfolders[i]);
+
+ if ((strcmp (subfolder, "") != 0) && g_hash_table_lookup (data->parents, subfolder) == NULL) {
+ GtkTreePath *subfolder_parent_tpath;
+ GtkTreePath *subfolder_tpath;
+
+ if (subfolder_parent != NULL)
+ subfolder_parent_tpath = g_hash_table_lookup (data->parents, subfolder_parent);
+ else
+ subfolder_parent_tpath = NULL;
+ subfolder_tpath = brasero_track_data_cfg_add_empty_directory (data->track, _g_uri_get_basename (subfolder), subfolder_parent_tpath);
+ g_hash_table_insert (data->parents, g_strdup (subfolder), subfolder_tpath);
+ }
+
+ g_free (subfolder_parent);
+ }
+
+ g_free (subfolder);
+ g_strfreev (subfolders);
+ }
+
+ tree_path = NULL;
+ if (relative_parent != NULL)
+ tree_path = g_hash_table_lookup (data->parents, relative_parent);
+ uri = g_file_get_uri (file);
+ brasero_track_data_cfg_add (data->track, uri, tree_path);
+
+ g_free (uri);
+ g_free (relative_parent);
+}
+
+
+static void
+add_content_list (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ BurnData *data = user_data;
+ char *parent_uri = key;
+ GList *files = value;
+ GList *scan;
+
+ for (scan = files; scan; scan = scan->next)
+ add_file_to_track (data, parent_uri, NULL, (GFile *) scan->data);
+
+ for (scan = files; scan; scan = scan->next) {
+ GFile *file = scan->data;
+ GFile *file_parent;
+ GList *file_sidecars = NULL;
+ GList *scan_sidecars;
+
+ file_parent = g_file_get_parent (file);
+ gth_hook_invoke ("add-sidecars", file, &file_sidecars);
+ for (scan_sidecars = file_sidecars; scan_sidecars; scan_sidecars = scan_sidecars->next) {
+ GFile *sidecar = scan_sidecars->data;
+ char *relative_path;
+ char *subfolder_path;
+
+ relative_path = g_file_get_relative_path (file_parent, sidecar);
+ subfolder_path = _g_uri_get_parent (relative_path);
+ if (g_strcmp0 (subfolder_path, "") == 0) {
+ g_free (subfolder_path);
+ subfolder_path = NULL;
+ }
+ add_file_to_track (data, parent_uri, subfolder_path, sidecar);
+ }
+
+ _g_object_list_unref (file_sidecars);
+ g_object_unref (file_parent);
+ }
+}
+
+
static void
label_entry_changed_cb (GtkEntry *entry,
BraseroBurnSession *session)
@@ -41,13 +185,14 @@ label_entry_changed_cb (GtkEntry *entry,
}
-void
-gth_browser_activate_action_burn_disc (GtkAction *action,
- GthBrowser *browser)
+static void
+burn_content_to_disc (BurnData *data)
{
static gboolean initialized = FALSE;
- GList *items;
- GList *file_list;
+ GtkWidget *dialog;
+ GtkBuilder *builder;
+ GtkWidget *options;
+ GtkResponseType result;
if (! initialized) {
brasero_media_library_start ();
@@ -55,152 +200,203 @@ gth_browser_activate_action_burn_disc (GtkAction *action,
initialized = TRUE;
}
- items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
- if ((items == NULL) || (items->next == NULL))
- file_list = gth_file_store_get_visibles (GTH_FILE_STORE (gth_browser_get_file_store (browser)));
- else
- file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
+ data->session = brasero_session_cfg_new ();
+ data->track = brasero_track_data_cfg_new ();
+ brasero_burn_session_add_track (BRASERO_BURN_SESSION (data->session),
+ BRASERO_TRACK (data->track),
+ NULL);
+ g_object_unref (data->track);
+
+ g_hash_table_foreach (data->content, add_content_list, data);
+
+ dialog = brasero_burn_options_new (data->session);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), gtk_window_get_icon_name (GTK_WINDOW (data->browser)));
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Write to Disc"));
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
+
+ builder = _gtk_builder_new_from_file ("burn-disc-options.ui", "burn_disc");
+ options = _gtk_builder_get_widget (builder, "options");
+ gtk_entry_set_text (GTK_ENTRY (_gtk_builder_get_widget (builder, "label_entry")),
+ g_file_info_get_display_name (gth_browser_get_location_data (data->browser)->info));
+ g_signal_connect (_gtk_builder_get_widget (builder, "label_entry"),
+ "changed",
+ G_CALLBACK (label_entry_changed_cb),
+ data->session);
+ gtk_widget_show (options);
+ brasero_burn_options_add_options (BRASERO_BURN_OPTIONS (dialog), options);
+
+ result = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ if (result == GTK_RESPONSE_OK) {
+ dialog = brasero_burn_dialog_new ();
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), gtk_window_get_icon_name (GTK_WINDOW (data->browser)));
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Write to Disc"));
+ brasero_session_cfg_disable (data->session);
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->browser));
+ gtk_window_present (GTK_WINDOW (dialog));
+ brasero_burn_dialog_run (BRASERO_BURN_DIALOG (dialog),
+ BRASERO_BURN_SESSION (data->session));
- {
- BraseroSessionCfg *session;
- BraseroTrackDataCfg *track;
- GList *scan;
- GHashTable *parents;
- GtkWidget *dialog;
- GtkBuilder *builder;
- GtkWidget *options;
- GtkResponseType result;
-
- session = brasero_session_cfg_new ();
- track = brasero_track_data_cfg_new ();
- brasero_burn_session_add_track (BRASERO_BURN_SESSION (session),
- BRASERO_TRACK (track),
- NULL);
- g_object_unref (track);
-
- for (scan = file_list; scan; scan = scan->next) {
- GthFileData *file_data = scan->data;
- char *uri;
-
- uri = g_file_get_uri (file_data->file);
- brasero_track_data_cfg_add (track, uri, NULL);
-
- g_free (uri);
- }
+ gtk_widget_destroy (dialog);
+ }
- parents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gtk_tree_path_free);
- for (scan = file_list; scan; scan = scan->next) {
- GthFileData *file_data = scan->data;
- GFile *parent;
- GList *file_sidecars = NULL;
- GList *scan_sidecars;
-
- gth_hook_invoke ("add-sidecars", file_data->file, &file_sidecars);
- parent = g_file_get_parent (file_data->file);
- for (scan_sidecars = file_sidecars; scan_sidecars; scan_sidecars = scan_sidecars->next) {
- GFile *sidecar = scan_sidecars->data;
- char *relative_path;
- char *parent_path;
- GtkTreePath *tree_path;
- char *uri;
-
- relative_path = g_file_get_relative_path (parent, sidecar);
- parent_path = _g_uri_get_parent (relative_path);
-
- if (g_strcmp0 (parent_path, "") == 0) {
- g_free (parent_path);
- parent_path = NULL;
- }
-
- if (parent_path != NULL) {
- char **subfolders;
- int i;
- char *subfolder;
-
- /* add all the subfolders to the track data */
-
- subfolder = NULL;
- subfolders = g_strsplit (parent_path, "/", -1);
- for (i = 0; subfolders[i] != NULL; i++) {
- char *subfolder_parent;
-
- subfolder_parent = subfolder;
- if (subfolder_parent != NULL)
- subfolder = g_strconcat (subfolder_parent, "/", subfolders[i], NULL);
- else
- subfolder = g_strdup (subfolders[i]);
-
- tree_path = g_hash_table_lookup (parents, subfolder);
- if (tree_path == NULL) {
- GtkTreePath *subfolder_parent_tpath;
- GtkTreePath *subfolder_tpath;
-
- if (subfolder_parent != NULL)
- subfolder_parent_tpath = g_hash_table_lookup (parents, subfolder_parent);
- else
- subfolder_parent_tpath = NULL;
- subfolder_tpath = brasero_track_data_cfg_add_empty_directory (track, parent_path, subfolder_parent_tpath);
- g_hash_table_insert (parents, g_strdup (parent_path), subfolder_tpath);
- }
-
- g_free (subfolder_parent);
- }
-
- g_strfreev (subfolders);
- }
-
- tree_path = NULL;
- if (parent_path != NULL)
- tree_path = g_hash_table_lookup (parents, parent_path);
-
- uri = g_file_get_uri (sidecar);
- brasero_track_data_cfg_add (track, uri, tree_path);
-
- g_free (uri);
- g_free (parent_path);
- g_free (relative_path);
- }
+ g_object_unref (data->session);
+}
- g_object_unref (parent);
- _g_object_list_unref (file_sidecars);
- }
- dialog = brasero_burn_options_new (session);
- gtk_window_set_icon_name (GTK_WINDOW (dialog), gtk_window_get_icon_name (GTK_WINDOW (browser)));
- gtk_window_set_title (GTK_WINDOW (dialog), _("Write to Disc"));
- gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser));
-
- builder = _gtk_builder_new_from_file ("burn-disc-options.ui", "burn_disc");
- options = _gtk_builder_get_widget (builder, "options");
- gtk_entry_set_text (GTK_ENTRY (_gtk_builder_get_widget (builder, "label_entry")),
- g_file_info_get_display_name (gth_browser_get_location_data (browser)->info));
- g_signal_connect (_gtk_builder_get_widget (builder, "label_entry"),
- "changed",
- G_CALLBACK (label_entry_changed_cb),
- session);
- gtk_widget_show (options);
- brasero_burn_options_add_options (BRASERO_BURN_OPTIONS (dialog), options);
-
- result = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
+static void
+done_func (GObject *object,
+ GError *error,
+ gpointer user_data)
+{
+ BurnData *data = user_data;
+
+ if (error != NULL) {
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not get the file list"), &error);
+ burn_data_free (data);
+ return;
+ }
+
+ burn_content_to_disc (data);
+ burn_data_free (data);
+}
- if (result == GTK_RESPONSE_OK) {
- dialog = brasero_burn_dialog_new ();
- gtk_window_set_icon_name (GTK_WINDOW (dialog), gtk_window_get_icon_name (GTK_WINDOW (browser)));
- gtk_window_set_title (GTK_WINDOW (dialog), _("Write to Disc"));
- brasero_session_cfg_disable (session);
- gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser));
- gtk_window_present (GTK_WINDOW (dialog));
- brasero_burn_dialog_run (BRASERO_BURN_DIALOG (dialog),
- BRASERO_BURN_SESSION (session));
-
- gtk_widget_destroy (dialog);
- }
- g_hash_table_unref (parents);
- g_object_unref (session);
+static void
+for_each_file_func (GFile *file,
+ GFileInfo *info,
+ gpointer user_data)
+{
+ BurnData *data = user_data;
+ GthFileData *file_data;
+
+ if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
+ return;
+
+ file_data = gth_file_data_new (file, info);
+ if (gth_test_match (data->test, file_data)) {
+ GList *list;
+
+ list = g_hash_table_lookup (data->content, data->current_directory);
+ list = g_list_prepend (list, g_file_dup (file));
+ g_hash_table_insert (data->content, g_strdup (data->current_directory), list);
}
+ g_object_unref (file_data);
+}
+
+
+static DirOp
+start_dir_func (GFile *directory,
+ GFileInfo *info,
+ GError **error,
+ gpointer user_data)
+{
+ BurnData *data = user_data;
+ GFile *parent;
+ char *escaped;
+ GFile *destination;
+ char *uri;
+
+ g_free (data->current_directory);
+
+ parent = g_file_get_parent (directory);
+ escaped = _g_replace (g_file_info_get_display_name (info), "/", "-");
+ destination = g_file_get_child_for_display_name (parent, escaped, NULL);
+ uri = g_file_get_uri (destination);
+ data->current_directory = g_uri_unescape_string (uri, NULL);
+ g_hash_table_insert (data->content, g_strdup (data->current_directory), NULL);
+
+ g_free (uri);
+ g_object_unref (destination);
+ g_free (escaped);
+ g_object_unref (parent);
+
+ return DIR_OP_CONTINUE;
+}
+
+
+static void
+source_dialog_response_cb (GtkDialog *dialog,
+ int response,
+ BurnData *data)
+{
+ gtk_widget_hide (data->dialog);
+
+ if (response == GTK_RESPONSE_OK) {
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (data->builder, "selection_radiobutton")))) {
+ g_hash_table_replace (data->content, g_file_get_uri (data->location), g_list_reverse (data->files));
+ data->files = NULL;
+ burn_content_to_disc (data);
+ burn_data_free (data);
+ }
+ else {
+ gboolean recursive;
+
+ _g_object_list_unref (data->files);
+ data->files = NULL;
+
+ recursive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (data->builder, "folder_recursive_radiobutton")));
+ data->test = gth_main_get_general_filter ();
+ data->file_source = gth_main_get_file_source (data->location);
+ gth_file_source_for_each_child (data->file_source,
+ data->location,
+ recursive,
+ eel_gconf_get_boolean (PREF_FAST_FILE_TYPE, TRUE) ? GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE : GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE,
+ start_dir_func,
+ for_each_file_func,
+ done_func,
+ data);
+ }
+ }
+ else
+ burn_data_free (data);
+
+ gtk_widget_destroy (data->dialog);
+}
+
+
+void
+gth_browser_activate_action_burn_disc (GtkAction *action,
+ GthBrowser *browser)
+{
+ GList *items;
+ GList *file_list;
+ BurnData *data;
+
+ items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
+ if ((items != NULL) && (items->next != NULL))
+ file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
+ else
+ file_list = gth_file_store_get_visibles (GTH_FILE_STORE (gth_browser_get_file_store (browser)));
+
+ data = g_new0 (BurnData, 1);
+ data->browser = g_object_ref (browser);
+ data->location = g_file_dup (gth_browser_get_location (browser));
+ data->base_directory = g_file_get_uri (data->location);
+ data->files = gth_file_data_list_to_file_list (file_list);
+ data->content = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ data->parents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gtk_tree_path_free);
+ data->builder = _gtk_builder_new_from_file ("burn-source-selector.ui", "burn_disc");
+ data->dialog = gtk_dialog_new_with_buttons (_("Write to Disc"),
+ GTK_WINDOW (browser),
+ GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (data->dialog))), _gtk_builder_get_widget (data->builder, "source_selector"));
+ if (items == NULL)
+ gtk_widget_set_sensitive (_gtk_builder_get_widget (data->builder, "selection_radiobutton"), FALSE);
+ else if ((items != NULL) && (items->next != NULL))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (data->builder, "selection_radiobutton")), TRUE);
+
+ g_signal_connect (data->dialog,
+ "response",
+ G_CALLBACK (source_dialog_response_cb),
+ data);
+ gtk_widget_show_all (data->dialog);
+
_g_object_list_unref (file_list);
_gtk_tree_path_list_free (items);
}
diff --git a/extensions/burn_disc/data/ui/Makefile.am b/extensions/burn_disc/data/ui/Makefile.am
index f121c88..eac915e 100644
--- a/extensions/burn_disc/data/ui/Makefile.am
+++ b/extensions/burn_disc/data/ui/Makefile.am
@@ -1,5 +1,5 @@
uidir = $(pkgdatadir)/ui
-ui_DATA = burn-disc-options.ui
+ui_DATA = burn-disc-options.ui burn-source-selector.ui
EXTRA_DIST = $(ui_DATA)
-include $(top_srcdir)/git.mk
diff --git a/extensions/burn_disc/data/ui/burn-source-selector.ui b/extensions/burn_disc/data/ui/burn-source-selector.ui
new file mode 100644
index 0000000..2ac0be3
--- /dev/null
+++ b/extensions/burn_disc/data/ui/burn-source-selector.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkVBox" id="source_selector">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="folder_radiobutton">
+ <property name="label" translatable="yes">Current _folder</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="folder_recursive_radiobutton">
+ <property name="label" translatable="yes">Current folder and its s_ub-folders</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">folder_radiobutton</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="selection_radiobutton">
+ <property name="label" translatable="yes">_Selected files</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">folder_radiobutton</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Source</property>
+ <property name="use_markup">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]