[brasero] Add support for icons for data projects through autorun.inf file
- From: Philippe Rouquier <philippr src gnome org>
- To: svn-commits-list gnome org
- Subject: [brasero] Add support for icons for data projects through autorun.inf file
- Date: Sat, 23 May 2009 11:29:29 -0400 (EDT)
commit bdde2bec642087968b642f886e0dac4153beb766
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date: Sat May 23 15:38:35 2009 +0200
Add support for icons for data projects through autorun.inf file
Fix #438859 â?? Allow burned disk icon customization
Also fixes a few memory leaks
---
libbrasero-burn/brasero-burn-options.c | 3 +-
libbrasero-burn/brasero-data-project.c | 516 +++++++++++++++++++------
libbrasero-burn/brasero-data-project.h | 14 +
libbrasero-burn/brasero-data-tree-model.c | 9 +
libbrasero-burn/brasero-data-vfs.c | 1 -
libbrasero-burn/brasero-file-node.c | 154 ++++++--
libbrasero-burn/brasero-file-node.h | 35 +-
libbrasero-burn/brasero-src-image.c | 3 +-
libbrasero-burn/brasero-track-data-cfg.c | 601 ++++++++++++++++++++++++-----
libbrasero-burn/brasero-track-data-cfg.h | 18 +-
libbrasero-burn/libbrasero-marshal.list | 1 +
src/brasero-data-disc.c | 81 ++++-
src/brasero-data-disc.h | 7 +
src/brasero-project-parse.c | 17 +
src/brasero-project-parse.h | 1 +
src/brasero-project.c | 153 ++++++++
16 files changed, 1346 insertions(+), 268 deletions(-)
diff --git a/libbrasero-burn/brasero-burn-options.c b/libbrasero-burn/brasero-burn-options.c
index cb3d550..8a52682 100644
--- a/libbrasero-burn/brasero-burn-options.c
+++ b/libbrasero-burn/brasero-burn-options.c
@@ -427,7 +427,8 @@ brasero_burn_options_update_valid (BraseroBurnOptions *self)
if (priv->message_input) {
gtk_widget_show (priv->message_input);
message = brasero_notify_message_add (BRASERO_NOTIFY (priv->message_input),
- _("Please select another image."),
+ /* Translators: this is a disc image not a picture */
+ C_("disc", "Please select another image."),
_("It doesn't appear to be a valid image or a valid cue file."),
-1,
BRASERO_NOTIFY_CONTEXT_SIZE);
diff --git a/libbrasero-burn/brasero-data-project.c b/libbrasero-burn/brasero-data-project.c
index 11473e1..6661b7c 100644
--- a/libbrasero-burn/brasero-data-project.c
+++ b/libbrasero-burn/brasero-data-project.c
@@ -111,6 +111,7 @@ enum {
DEEP_DIRECTORY_SIGNAL,
G2_FILE_SIGNAL,
PROJECT_LOADED_SIGNAL,
+ VIRTUAL_SIBLING_SIGNAL,
LAST_SIGNAL
};
@@ -126,6 +127,90 @@ typedef gboolean (*BraseroDataNodeAddedFunc) (BraseroDataProject *project,
BraseroFileNode *node,
const gchar *uri);
+static void
+brasero_data_project_virtual_sibling (BraseroDataProject *self,
+ BraseroFileNode *node,
+ BraseroFileNode *sibling)
+{
+ BraseroDataProjectPrivate *priv;
+ BraseroFileTreeStats *stats;
+ BraseroFileNode *children;
+ BraseroFileNode *iter;
+
+ if (sibling == node)
+ return;
+
+ priv = BRASERO_DATA_PROJECT_PRIVATE (self);
+
+ g_signal_emit (self,
+ brasero_data_project_signals [VIRTUAL_SIBLING_SIGNAL],
+ 0,
+ node,
+ sibling);
+
+ stats = brasero_file_node_get_tree_stats (priv->root, NULL);
+ if (node) {
+ /* we remove the virtual node, BUT, we keep its
+ * virtual children that will be appended to the
+ * node being moved in replacement. */
+ /* NOTE: children MUST all be virtual */
+ children = BRASERO_FILE_NODE_CHILDREN (sibling);
+ for (iter = children; iter; iter = iter->next)
+ brasero_file_node_add (node, iter, NULL);
+
+ sibling->union2.children = NULL;
+ }
+ else {
+ /* Remove the virtual node. This should never happens */
+ g_warning ("Virtual nodes could not be transfered");
+ }
+
+ /* Just destroy the node as it has no other
+ * existence nor goal in existence but to create
+ * a collision. */
+ brasero_file_node_destroy (sibling, stats);
+}
+
+static gboolean
+brasero_data_project_node_signal (BraseroDataProject *self,
+ guint signal,
+ BraseroFileNode *node)
+{
+ GValue instance_and_params [2];
+ GValue return_value;
+ GValue *params;
+
+ /* object which signalled */
+ instance_and_params->g_type = 0;
+ g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (self));
+ g_value_set_instance (instance_and_params, self);
+
+ /* arguments of signal (name) */
+ params = instance_and_params + 1;
+ params->g_type = 0;
+ g_value_init (params, G_TYPE_POINTER);
+ g_value_set_pointer (params, node);
+
+ /* default to FALSE */
+ return_value.g_type = 0;
+ g_value_init (&return_value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&return_value, FALSE);
+
+ g_signal_emitv (instance_and_params,
+ brasero_data_project_signals [signal],
+ 0,
+ &return_value);
+
+ g_value_unset (instance_and_params);
+ g_value_unset (params);
+
+ /* In this case always remove the sibling */
+ if (signal == NAME_COLLISION_SIGNAL && BRASERO_FILE_NODE_VIRTUAL (node))
+ return FALSE;
+
+ return g_value_get_boolean (&return_value);
+}
+
static gboolean
brasero_data_project_file_signal (BraseroDataProject *self,
guint signal,
@@ -1300,6 +1385,53 @@ brasero_data_project_is_deep (BraseroDataProject *self,
return TRUE;
}
+static void
+brasero_data_project_remove_sibling (BraseroDataProject *self,
+ BraseroFileNode *sibling,
+ BraseroFileNode *replacement)
+{
+ BraseroDataProjectPrivate *priv;
+
+ if (sibling != replacement)
+ return;
+
+ priv = BRASERO_DATA_PROJECT_PRIVATE (self);
+
+ if (BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ BraseroFileTreeStats *stats;
+ BraseroFileNode *children;
+ BraseroFileNode *iter;
+
+ stats = brasero_file_node_get_tree_stats (priv->root, NULL);
+ if (replacement) {
+ /* we remove the virtual node, BUT, we keep its
+ * virtual children that will be appended to the
+ * node being moved in replacement. */
+ /* NOTE: children MUST all be virtual */
+ children = BRASERO_FILE_NODE_CHILDREN (sibling);
+ for (iter = children; iter; iter = iter->next)
+ brasero_file_node_add (replacement, iter, NULL);
+
+ sibling->union2.children = NULL;
+ }
+ else {
+ /* Remove the virtual node. This should never happens */
+ g_warning ("Virtual nodes could not be transfered");
+ }
+
+ /* Just destroy the node as it has no other
+ * existence nor goal in existence but to create
+ * a collision. */
+ brasero_file_node_destroy (sibling, stats);
+ }
+ else {
+ /* The node existed and the user wants the existing to
+ * be replaced, so we delete that node (since the new
+ * one would have the old one's children otherwise). */
+ brasero_data_project_remove_real (self, sibling);
+ }
+}
+
gboolean
brasero_data_project_move_node (BraseroDataProject *self,
BraseroFileNode *node,
@@ -1336,9 +1468,14 @@ brasero_data_project_move_node (BraseroDataProject *self,
/* One case could make us fail: if there is the same name in
* the directory: in that case return FALSE; check now. */
target_sibling = brasero_file_node_check_name_existence (parent, BRASERO_FILE_NODE_NAME (node));
- if (target_sibling
- && brasero_data_project_file_signal (self, NAME_COLLISION_SIGNAL, BRASERO_FILE_NODE_NAME (node)))
- return FALSE;
+ if (target_sibling) {
+ if (BRASERO_FILE_NODE_VIRTUAL (target_sibling)) {
+ brasero_data_project_virtual_sibling (self, node, target_sibling);
+ target_sibling = NULL;
+ }
+ else if (brasero_data_project_node_signal (self, NAME_COLLISION_SIGNAL, target_sibling))
+ return FALSE;
+ }
/* If node was in the joliet incompatible table, remove it */
brasero_data_project_joliet_remove_node (self, node);
@@ -1383,12 +1520,10 @@ brasero_data_project_move_node (BraseroDataProject *self,
if (former_parent && klass->node_removed)
klass->node_removed (self, former_parent, former_position, node);
- if (target_sibling) {
- /* The node existed and the user wants the existing to
- * be replaced, so we delete that node (since the new
- * one would have the old one's children otherwise). */
- brasero_data_project_remove_real (self, target_sibling);
- }
+ if (target_sibling)
+ brasero_data_project_remove_sibling (self,
+ target_sibling,
+ node);
brasero_file_node_move_to (node, parent, priv->sort_func);
@@ -1436,6 +1571,7 @@ brasero_data_project_rename_node (BraseroDataProject *self,
BraseroFileNode *node,
const gchar *name)
{
+ BraseroFileNode *imported_sibling;
BraseroDataProjectPrivate *priv;
BraseroFileNode *sibling;
@@ -1445,11 +1581,16 @@ brasero_data_project_rename_node (BraseroDataProject *self,
* simply not possible to rename. */
sibling = brasero_file_node_check_name_existence (node->parent, name);
if (sibling) {
- if (brasero_data_project_file_signal (self, NAME_COLLISION_SIGNAL, name))
+ if (BRASERO_FILE_NODE_VIRTUAL (sibling))
+ brasero_data_project_virtual_sibling (self, node, sibling);
+ else if (brasero_data_project_node_signal (self, NAME_COLLISION_SIGNAL, sibling))
return FALSE;
-
- if (sibling != node)
+ else if (sibling != node) {
+ /* The node existed and the user wants the existing to
+ * be replaced, so we delete that node (since the new
+ * one would have the old one's children otherwise). */
brasero_data_project_remove_real (self, sibling);
+ }
}
/* If node was in the joliet incompatible table, remove it */
@@ -1457,7 +1598,7 @@ brasero_data_project_rename_node (BraseroDataProject *self,
/* see if this node didn't replace an imported one. If so the old
* imported node must re-appear in the tree. */
- sibling = brasero_file_node_check_imported_sibling (node);
+ imported_sibling = brasero_file_node_check_imported_sibling (node);
if (!node->is_grafted) {
gchar *uri;
@@ -1495,14 +1636,14 @@ brasero_data_project_rename_node (BraseroDataProject *self,
brasero_data_project_node_changed (self, node);
- if (sibling) {
+ if (imported_sibling) {
BraseroDataProjectClass *klass;
klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
- brasero_file_node_add (sibling->parent, sibling, priv->sort_func);
+ brasero_file_node_add (sibling->parent, imported_sibling, priv->sort_func);
if (klass->node_added)
- brasero_data_project_add_node_and_children (self, sibling, klass->node_added);
+ brasero_data_project_add_node_and_children (self, imported_sibling, klass->node_added);
}
return TRUE;
@@ -1624,7 +1765,8 @@ brasero_data_project_restore_uri (BraseroDataProject *self,
if (brasero_file_node_check_name_existence (parent, name))
continue;
- node = brasero_file_node_new_loading (name, parent, priv->sort_func);
+ node = brasero_file_node_new_loading (name);
+ brasero_file_node_add (parent, node, priv->sort_func);
brasero_data_project_add_node_real (self, node, graft, uri);
}
g_slist_free (nodes);
@@ -1660,6 +1802,7 @@ brasero_data_project_add_imported_session_file (BraseroDataProject *self,
BraseroFileNode *parent)
{
BraseroFileNode *node;
+ BraseroFileNode *sibling;
BraseroDataProjectClass *klass;
BraseroDataProjectPrivate *priv;
@@ -1671,54 +1814,62 @@ brasero_data_project_add_imported_session_file (BraseroDataProject *self,
if (!parent)
parent = priv->root;
- node = brasero_file_node_check_name_existence (parent, g_file_info_get_name (info));
- if (node) {
+ sibling = brasero_file_node_check_name_existence (parent, g_file_info_get_name (info));
+ if (sibling) {
/* The node exists but it may be that we've loaded the project
* before. Then the necessary directories to hold the grafted
* files will have been created as fake directories. We need to
* replace those whenever we run into one but not lose their
* children. */
- if (node->is_fake && node->is_tmp_parent) {
+ if (BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ node = brasero_file_node_new_imported_session_file (info);
+ brasero_data_project_virtual_sibling (self, node, sibling);
+ }
+ else if (sibling->is_fake && sibling->is_tmp_parent) {
BraseroGraft *graft;
BraseroURINode *uri_node;
- graft = BRASERO_FILE_NODE_GRAFT (node);
+ graft = BRASERO_FILE_NODE_GRAFT (sibling);
uri_node = graft->node;
/* NOTE after this function graft is invalid */
- brasero_file_node_ungraft (node);
+ brasero_file_node_ungraft (sibling);
/* see if uri_node is still needed */
if (!uri_node->nodes
&& !brasero_data_project_uri_has_parent (self, uri_node->uri))
brasero_data_project_uri_remove_graft (self, uri_node->uri);
- if (node->is_file)
- node->is_fake = FALSE;
+ if (sibling->is_file)
+ sibling->is_fake = FALSE;
else
- node->union3.imported_address = g_file_info_get_attribute_int64 (info, BRASERO_IO_DIR_CONTENTS_ADDR);
+ sibling->union3.imported_address = g_file_info_get_attribute_int64 (info, BRASERO_IO_DIR_CONTENTS_ADDR);
- node->is_imported = TRUE;
- node->is_tmp_parent = FALSE;
+ sibling->is_imported = TRUE;
+ sibling->is_tmp_parent = FALSE;
/* Something has changed, tell the tree */
klass = BRASERO_DATA_PROJECT_GET_CLASS (self);
if (klass->node_changed)
- klass->node_changed (self, node);
+ klass->node_changed (self, sibling);
- return node;
+ return sibling;
}
-
- if (brasero_data_project_file_signal (self, NAME_COLLISION_SIGNAL, BRASERO_FILE_NODE_NAME (node)))
+ else if (brasero_data_project_node_signal (self, NAME_COLLISION_SIGNAL, sibling))
return NULL;
-
- /* The node existed and the user wants the existing to
- * be replaced, so we delete that node (since the new
- * one would have the old one's children otherwise). */
- brasero_data_project_remove_real (self, node);
+ else {
+ /* The node existed and the user wants the existing to
+ * be replaced, so we delete that node (since the new
+ * one would have the old one's children otherwise). */
+ brasero_data_project_remove_real (self, sibling);
+ node = brasero_file_node_new_imported_session_file (info);
+ }
}
+ else
+ node = brasero_file_node_new_imported_session_file (info);
- node = brasero_file_node_new_imported_session_file (info, parent, priv->sort_func);
+ /* Add it (we must add a graft) */
+ brasero_file_node_add (parent, node, priv->sort_func);
/* In this case, there can be no graft, and furthermore the
* lengths of the names are not our problem. Just signal that
@@ -1737,6 +1888,7 @@ brasero_data_project_add_empty_directory (BraseroDataProject *self,
{
BraseroFileNode *node;
BraseroURINode *graft;
+ BraseroFileNode *sibling;
BraseroDataProjectPrivate *priv;
g_return_val_if_fail (BRASERO_IS_DATA_PROJECT (self), NULL);
@@ -1751,18 +1903,26 @@ brasero_data_project_add_empty_directory (BraseroDataProject *self,
if (!brasero_data_project_is_deep (self, parent, name, FALSE))
return NULL;
- node = brasero_file_node_check_name_existence (parent, name);
- if (node) {
- if (brasero_data_project_file_signal (self, NAME_COLLISION_SIGNAL, BRASERO_FILE_NODE_NAME (node)))
+ sibling = brasero_file_node_check_name_existence (parent, name);
+ if (sibling) {
+ if (BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ node = brasero_file_node_new_empty_folder (name);
+ brasero_data_project_virtual_sibling (self, node, sibling);
+ }
+ else if (brasero_data_project_node_signal (self, NAME_COLLISION_SIGNAL, sibling))
return NULL;
-
- /* The node existed and the user wants the existing to
- * be replaced, so we delete that node (since the new
- * one would have the old one's children otherwise). */
- brasero_data_project_remove_real (self, node);
+ else {
+ /* The node existed and the user wants the existing to
+ * be replaced, so we delete that node (since the new
+ * one would have the old one's children otherwise). */
+ brasero_data_project_remove_real (self, sibling);
+ node = brasero_file_node_new_empty_folder (name);
+ }
}
+ else
+ node = brasero_file_node_new_empty_folder (name);
- node = brasero_file_node_new_empty_folder (name, parent, priv->sort_func);
+ brasero_file_node_add (parent, node, priv->sort_func);
/* Add it (we must add a graft) */
graft = g_hash_table_lookup (priv->grafts, NEW_FOLDER);
@@ -1998,52 +2158,87 @@ brasero_data_project_node_reloaded (BraseroDataProject *self,
0);
}
-BraseroFileNode *
-brasero_data_project_add_loading_node (BraseroDataProject *self,
- const gchar *uri,
- BraseroFileNode *parent)
+static BraseroFileNode *
+brasero_data_project_add_loading_node_real (BraseroDataProject *self,
+ const gchar *uri,
+ const gchar *name_arg,
+ gboolean is_hidden,
+ BraseroFileNode *parent)
{
gchar *name;
BraseroFileNode *node;
BraseroURINode *graft;
+ BraseroFileNode *sibling;
BraseroDataProjectPrivate *priv;
- g_return_val_if_fail (BRASERO_IS_DATA_PROJECT (self), NULL);
- g_return_val_if_fail (uri != NULL, NULL);
-
priv = BRASERO_DATA_PROJECT_PRIVATE (self);
graft = g_hash_table_lookup (priv->grafts, uri);
if (!parent)
parent = priv->root;
- /* NOTE: find the name of the node through the URI */
- name = brasero_utils_get_uri_name (uri);
+ if (!name_arg) {
+ /* NOTE: find the name of the node through the URI */
+ name = brasero_utils_get_uri_name (uri);
+ }
+ else
+ name = g_strdup (name_arg);
/* make sure that name doesn't exist */
- node = brasero_file_node_check_name_existence (parent, name);
- if (node) {
- if (brasero_data_project_file_signal (self,
- NAME_COLLISION_SIGNAL,
- BRASERO_FILE_NODE_NAME (node))) {
+ sibling = brasero_file_node_check_name_existence (parent, name);
+ if (sibling) {
+ if (BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ node = brasero_file_node_new_loading (name);
+ brasero_data_project_virtual_sibling (self, node, sibling);
+ }
+ else if (brasero_data_project_node_signal (self, NAME_COLLISION_SIGNAL, sibling)) {
g_free (name);
return NULL;
}
-
- /* The node existed and the user wants the existing to
- * be replaced, so we delete that node (since the new
- * one would have the old one's children otherwise). */
- brasero_data_project_remove_real (self, node);
- graft = g_hash_table_lookup (priv->grafts, uri);
+ else {
+ /* The node existed and the user wants the existing to
+ * be replaced, so we delete that node (since the new
+ * one would have the old one's children otherwise). */
+ brasero_data_project_remove_real (self, sibling);
+ node = brasero_file_node_new_loading (name);
+ graft = g_hash_table_lookup (priv->grafts, uri);
+ }
}
+ else
+ node = brasero_file_node_new_loading (name);
- node = brasero_file_node_new_loading (name, parent, priv->sort_func);
+ brasero_file_node_add (parent, node, priv->sort_func);
+
+ node->is_hidden = is_hidden;
brasero_data_project_add_node_real (self, node, graft, uri);
g_free (name);
return node;
}
+BraseroFileNode *
+brasero_data_project_add_loading_node (BraseroDataProject *self,
+ const gchar *uri,
+ BraseroFileNode *parent)
+{
+ g_return_val_if_fail (BRASERO_IS_DATA_PROJECT (self), NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ return brasero_data_project_add_loading_node_real (self, uri, NULL, FALSE, parent);
+}
+
+BraseroFileNode *
+brasero_data_project_add_hidden_node (BraseroDataProject *self,
+ const gchar *uri,
+ const gchar *name,
+ BraseroFileNode *parent)
+{
+ g_return_val_if_fail (BRASERO_IS_DATA_PROJECT (self), NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ return brasero_data_project_add_loading_node_real (self, uri, name, TRUE, parent);
+}
+
/**
* This function is only used by brasero-data-vfs.c to add the contents of a
* directory. That's why if a node with the same name is already grafted we
@@ -2086,6 +2281,7 @@ brasero_data_project_add_node_from_info (BraseroDataProject *self,
const gchar *name;
BraseroFileNode *node;
BraseroURINode *graft;
+ BraseroFileNode *sibling;
BraseroDataProjectPrivate *priv;
g_return_val_if_fail (BRASERO_IS_DATA_PROJECT (self), NULL);
@@ -2124,20 +2320,9 @@ brasero_data_project_add_node_from_info (BraseroDataProject *self,
if (!parent)
parent = priv->root;
- /* make sure that name doesn't exist */
name = g_file_info_get_name (info);
- node = brasero_file_node_check_name_existence (parent, name);
- if (node) {
- if (brasero_data_project_file_signal (self, NAME_COLLISION_SIGNAL, BRASERO_FILE_NODE_NAME (node)))
- return NULL;
-
- /* The node existed and the user wants the existing to
- * be replaced, so we delete that node (since the new
- * one would have the old one's children otherwise). */
- brasero_data_project_remove_real (self, node);
- graft = g_hash_table_lookup (priv->grafts, uri);
- }
+ /* Run a few checks */
type = g_file_info_get_file_type (info);
if (type != G_FILE_TYPE_DIRECTORY) {
guint64 size;
@@ -2157,9 +2342,40 @@ brasero_data_project_add_node_from_info (BraseroDataProject *self,
return NULL;
}
- node = brasero_file_node_new_from_info (info,
- parent,
- priv->sort_func);
+ /* make sure that name doesn't exist */
+ sibling = brasero_file_node_check_name_existence (parent, name);
+ if (sibling) {
+ BraseroFileTreeStats *stats;
+
+ stats = brasero_file_node_get_tree_stats (priv->root, NULL);
+
+ if (BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ node = brasero_file_node_new (g_file_info_get_name (info));
+ brasero_file_node_set_from_info (node, stats, info);
+ brasero_data_project_virtual_sibling (self, node, sibling);
+ }
+ else if (brasero_data_project_node_signal (self, NAME_COLLISION_SIGNAL, sibling))
+ return NULL;
+ else {
+ /* The node existed and the user wants the existing to
+ * be replaced, so we delete that node (since the new
+ * one would have the old one's children otherwise). */
+ node = brasero_file_node_new (g_file_info_get_name (info));
+ brasero_file_node_set_from_info (node, stats, info);
+
+ brasero_data_project_remove_real (self, sibling);
+ graft = g_hash_table_lookup (priv->grafts, uri);
+ }
+ }
+ else {
+ BraseroFileTreeStats *stats;
+
+ node = brasero_file_node_new (g_file_info_get_name (info));
+ stats = brasero_file_node_get_tree_stats (priv->root, NULL);
+ brasero_file_node_set_from_info (node, stats, info);
+ }
+
+ brasero_file_node_add (parent, node, priv->sort_func);
if (g_file_info_get_is_symlink (info)
&& g_file_info_get_file_type (info) != G_FILE_TYPE_SYMBOLIC_LINK) {
@@ -2213,6 +2429,7 @@ brasero_data_project_add_node_from_info (BraseroDataProject *self,
*/
struct _MakeTrackData {
gboolean append_slash;
+ gboolean hidden_nodes;
GSList *grafts;
GSList *excluded;
@@ -2221,7 +2438,7 @@ struct _MakeTrackData {
};
typedef struct _MakeTrackData MakeTrackData;
-static gchar *
+gchar *
brasero_data_project_node_to_path (BraseroDataProject *self,
BraseroFileNode *node)
{
@@ -2274,18 +2491,7 @@ _foreach_grafts_make_list_cb (const gchar *uri,
MakeTrackData *data)
{
GSList *iter;
-
- /* Each URI in this table must be excluded. Then each node in
- * this list will be grafted. That way only those that we are
- * interested in will be in the tree. */
-
- /* Add to the unreadable. This could be further improved by
- * checking if there is a parent in the hash for this URI. If
- * not that's no use adding this URI to unreadable. */
- /* NOTE: if that the created directories URI, then there is no
- * need to add it to excluded */
- if (uri != NEW_FOLDER)
- data->excluded = g_slist_prepend (data->excluded, g_strdup (uri));
+ gboolean add_to_excluded = FALSE;
/* add each node */
for (iter = uri_node->nodes; iter; iter = iter->next) {
@@ -2293,7 +2499,10 @@ _foreach_grafts_make_list_cb (const gchar *uri,
BraseroGraftPt *graft;
node = iter->data;
+ if (!data->hidden_nodes && node->is_hidden)
+ continue;
+ add_to_excluded = TRUE;
graft = g_new0 (BraseroGraftPt, 1);
/* if URI is a created directory set URI to NULL */
@@ -2315,6 +2524,18 @@ _foreach_grafts_make_list_cb (const gchar *uri,
data->grafts = g_slist_prepend (data->grafts, graft);
}
+
+ /* Each URI in this table must be excluded. Then each node in
+ * this list will be grafted. That way only those that we are
+ * interested in will be in the tree. */
+
+ /* Add to the unreadable. This could be further improved by
+ * checking if there is a parent in the hash for this URI. If
+ * not that's no use adding this URI to unreadable. */
+ /* NOTE: if that the created directories URI, then there is no
+ * need to add it to excluded */
+ if (uri != NEW_FOLDER && add_to_excluded)
+ data->excluded = g_slist_prepend (data->excluded, g_strdup (uri));
}
static void
@@ -2362,6 +2583,7 @@ gboolean
brasero_data_project_get_contents (BraseroDataProject *self,
GSList **grafts,
GSList **unreadable,
+ gboolean hidden_nodes,
gboolean joliet_compat,
gboolean append_slash)
{
@@ -2376,12 +2598,18 @@ brasero_data_project_get_contents (BraseroDataProject *self,
callback_data.project = self;
callback_data.grafts = NULL;
callback_data.excluded = NULL;
+ callback_data.hidden_nodes = hidden_nodes;
callback_data.append_slash = append_slash;
g_hash_table_foreach (priv->grafts,
(GHFunc) _foreach_grafts_make_list_cb,
&callback_data);
+ /* This is possible even if the GHashTable is empty since there could be
+ * only excluded URI inside or hidden nodes like autorun.inf. */
+ if (!grafts)
+ return FALSE;
+
if (joliet_compat) {
/* Make sure that all nodes with incompatible joliet names are
* added as graft points. */
@@ -2870,15 +3098,17 @@ brasero_data_project_create_path (BraseroDataProject *self,
end = g_utf8_strchr (path, -1, G_DIR_SEPARATOR);
while (end && end [1] != '\0') {
+ BraseroFileNode *node;
gchar *name;
gint len;
/* create the path */
len = end - path;
name = g_strndup (path, len);
- parent = brasero_file_node_new_loading (name,
- parent,
- priv->sort_func);
+
+ node = brasero_file_node_new_loading (name);
+ brasero_file_node_add (parent, node, priv->sort_func);
+ parent = node;
g_free (name);
/* check joliet compatibility; do it after node was created. */
@@ -3031,9 +3261,11 @@ brasero_data_project_add_path (BraseroDataProject *self,
* - we don't check for sibling
* - we set right from the start the right name */
if (uri != NEW_FOLDER)
- node = brasero_file_node_new_loading (path, parent, priv->sort_func);
+ node = brasero_file_node_new_loading (path);
else
- node = brasero_file_node_new_empty_folder (path, parent, priv->sort_func);
+ node = brasero_file_node_new_empty_folder (path);
+
+ brasero_file_node_add (parent, node, priv->sort_func);
/* the following function checks for joliet, graft it */
brasero_data_project_add_node_real (self,
@@ -3422,6 +3654,47 @@ brasero_data_project_get_root (BraseroDataProject *self)
return priv->root;
}
+/**
+ * This is to watch a still empty path and get a warning through the collision
+ * name signal when the node is created. If a node is already created for this
+ * path, then returns NULL.
+ */
+
+BraseroFileNode *
+brasero_data_project_watch_path (BraseroDataProject *project,
+ const gchar *path)
+{
+ BraseroDataProjectPrivate *priv;
+ BraseroFileNode *parent;
+ gchar **array;
+ gchar **iter;
+
+ priv = BRASERO_DATA_PROJECT_PRIVATE (project);
+ parent = brasero_data_project_skip_existing (project, priv->root, &path);
+
+ if (!path || path [0] == '\0')
+ return NULL;
+
+ /* Now add the virtual node */
+ if (g_str_has_prefix (path, G_DIR_SEPARATOR_S))
+ array = g_strsplit (path + 1, G_DIR_SEPARATOR_S, 0);
+ else
+ array = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
+
+ for (iter = array; iter && *iter && parent; iter ++) {
+ BraseroFileNode *node;
+
+ node = brasero_file_node_new_virtual (*iter);
+ brasero_file_node_add (parent, node, NULL);
+ parent = node;
+ }
+
+ g_strfreev (array);
+
+ /* This function shouldn't fail anyway */
+ return parent;
+}
+
static gboolean
brasero_data_project_clear_grafts_cb (gchar *key,
BraseroURINode *graft,
@@ -3580,14 +3853,17 @@ brasero_data_project_file_added (BraseroFileMonitor *monitor,
g_free (escaped_name);
g_free (parent_uri);
- if (sibling) {
- /* There is no way we can add the node to tree; so exclude it */
- brasero_data_project_exclude_uri (BRASERO_DATA_PROJECT (monitor), uri);
- }
- else
+ if (!sibling || BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ /* If there is a virtual node, get rid of it */
brasero_data_project_add_loading_node (BRASERO_DATA_PROJECT (monitor),
uri,
parent);
+ }
+ else {
+ /* There is no way we can add the node to tree; so exclude it */
+ brasero_data_project_exclude_uri (BRASERO_DATA_PROJECT (monitor), uri);
+ }
+
g_free (uri);
}
@@ -3731,7 +4007,7 @@ brasero_data_project_file_renamed (BraseroFileMonitor *monitor,
* simply not possible to rename. So if node is grafted it keeps its
* name if not, it's grafted with the old name. */
sibling = brasero_file_node_check_name_existence (node->parent, new_name);
- if (sibling) {
+ if (sibling && !BRASERO_FILE_NODE_VIRTUAL (sibling)) {
if (!node->is_grafted) {
brasero_data_project_file_graft (BRASERO_DATA_PROJECT (monitor), node, new_name);
return;
@@ -3748,6 +4024,11 @@ brasero_data_project_file_renamed (BraseroFileMonitor *monitor,
brasero_data_project_file_update_name (BRASERO_DATA_PROJECT (monitor), node, new_name);
}
+ if (sibling && BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ /* Signal collision and remove virtual node but ignore result */
+ brasero_data_project_virtual_sibling (BRASERO_DATA_PROJECT (monitor), node, sibling);
+ }
+
if (node->is_grafted) {
BraseroURINode *uri_node;
BraseroGraft *graft;
@@ -3829,11 +4110,16 @@ brasero_data_project_file_moved (BraseroFileMonitor *monitor,
* that's simply not possible to rename. So if node is grafted
* it keeps its name; if not, it's grafted with the old name. */
sibling = brasero_file_node_check_name_existence (parent, name_dest);
- if (sibling) {
+ if (sibling && !BRASERO_FILE_NODE_VIRTUAL (sibling)) {
brasero_data_project_file_graft (BRASERO_DATA_PROJECT (monitor), node, name_dest);
return;
}
+ if (sibling && BRASERO_FILE_NODE_VIRTUAL (sibling)) {
+ /* Signal collision and remove virtual node but ignore result */
+ brasero_data_project_virtual_sibling (BRASERO_DATA_PROJECT (monitor), node, sibling);
+ }
+
/* If node was in the joliet incompatible table, remove it */
brasero_data_project_joliet_remove_node (BRASERO_DATA_PROJECT (monitor), node);
@@ -3976,10 +4262,10 @@ brasero_data_project_class_init (BraseroDataProjectClass *klass)
G_SIGNAL_RUN_LAST|G_SIGNAL_NO_RECURSE,
0,
NULL, NULL,
- brasero_marshal_BOOLEAN__STRING,
+ brasero_marshal_BOOLEAN__POINTER,
G_TYPE_BOOLEAN,
1,
- G_TYPE_STRING);
+ G_TYPE_POINTER);
brasero_data_project_signals [SIZE_CHANGED_SIGNAL] =
g_signal_new ("size_changed",
G_TYPE_FROM_CLASS (klass),
@@ -4021,6 +4307,18 @@ brasero_data_project_class_init (BraseroDataProjectClass *klass)
1,
G_TYPE_INT);
+ brasero_data_project_signals [VIRTUAL_SIBLING_SIGNAL] =
+ g_signal_new ("virtual-sibling",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST|G_SIGNAL_NO_RECURSE,
+ 0,
+ NULL, NULL,
+ brasero_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
#ifdef BUILD_INOTIFY
BraseroFileMonitorClass *monitor_class = BRASERO_FILE_MONITOR_CLASS (klass);
diff --git a/libbrasero-burn/brasero-data-project.h b/libbrasero-burn/brasero-data-project.h
index 873d969..2515633 100644
--- a/libbrasero-burn/brasero-data-project.h
+++ b/libbrasero-burn/brasero-data-project.h
@@ -133,6 +133,7 @@ gboolean
brasero_data_project_get_contents (BraseroDataProject *project,
GSList **grafts,
GSList **unreadable,
+ gboolean hidden_nodes,
gboolean joliet_compat,
gboolean append_slash);
@@ -154,6 +155,12 @@ brasero_data_project_load_contents (BraseroDataProject *project,
GSList *excluded);
BraseroFileNode *
+brasero_data_project_add_hidden_node (BraseroDataProject *project,
+ const gchar *uri,
+ const gchar *name,
+ BraseroFileNode *parent);
+
+BraseroFileNode *
brasero_data_project_add_loading_node (BraseroDataProject *project,
const gchar *uri,
BraseroFileNode *parent);
@@ -225,12 +232,19 @@ brasero_data_project_get_root (BraseroDataProject *project);
gchar *
brasero_data_project_node_to_uri (BraseroDataProject *project,
BraseroFileNode *node);
+gchar *
+brasero_data_project_node_to_path (BraseroDataProject *self,
+ BraseroFileNode *node);
void
brasero_data_project_set_sort_function (BraseroDataProject *project,
GtkSortType sort_type,
GCompareFunc sort_func);
+BraseroFileNode *
+brasero_data_project_watch_path (BraseroDataProject *project,
+ const gchar *path);
+
BraseroBurnResult
brasero_data_project_span (BraseroDataProject *project,
goffset max_sectors,
diff --git a/libbrasero-burn/brasero-data-tree-model.c b/libbrasero-burn/brasero-data-tree-model.c
index 6343625..5520c80 100644
--- a/libbrasero-burn/brasero-data-tree-model.c
+++ b/libbrasero-burn/brasero-data-tree-model.c
@@ -66,6 +66,9 @@ brasero_data_tree_model_node_added (BraseroDataProject *project,
const gchar *uri)
{
/* see if we really need to tell the treeview we changed */
+ if (node->is_hidden)
+ goto end;
+
if (node->parent
&& !node->parent->is_root
&& !node->parent->is_visible)
@@ -91,6 +94,9 @@ brasero_data_tree_model_node_removed (BraseroDataProject *project,
BraseroFileNode *node)
{
/* see if we really need to tell the treeview we changed */
+ if (node->is_hidden)
+ goto end;
+
if (!node->is_visible
&& former_parent
&& !former_parent->is_root
@@ -118,6 +124,9 @@ brasero_data_tree_model_node_changed (BraseroDataProject *project,
BraseroFileNode *node)
{
/* see if we really need to tell the treeview we changed */
+ if (node->is_hidden)
+ goto end;
+
if (node->parent
&& !node->parent->is_root
&& !node->parent->is_visible)
diff --git a/libbrasero-burn/brasero-data-vfs.c b/libbrasero-burn/brasero-data-vfs.c
index 87bc61b..e526887 100644
--- a/libbrasero-burn/brasero-data-vfs.c
+++ b/libbrasero-burn/brasero-data-vfs.c
@@ -436,7 +436,6 @@ brasero_data_vfs_directory_load_result (GObject *owner,
}
}
-
/* add node for all parents */
nodes = g_hash_table_lookup (priv->directories, parent_uri);
for (iter = nodes; iter; iter = iter->next) {
diff --git a/libbrasero-burn/brasero-file-node.c b/libbrasero-burn/brasero-file-node.c
index 0e91ade..3a7867d 100644
--- a/libbrasero-burn/brasero-file-node.c
+++ b/libbrasero-burn/brasero-file-node.c
@@ -196,6 +196,32 @@ brasero_file_node_insert (BraseroFileNode *head,
return node;
}
+ /* Set hidden nodes (whether virtual or not) always last */
+ if (head->is_hidden) {
+ node->next = head;
+ if (newpos)
+ *newpos = 0;
+
+ return node;
+ }
+
+ if (node->is_hidden) {
+ iter = head;
+ n = 1;
+ while (iter->next) {
+ iter = iter->next;
+ n ++;
+ }
+
+ iter->next = node;
+
+ if (newpos)
+ *newpos = n;
+
+ return head;
+ }
+
+ /* regular node, regular head node */
if (sort_func (head, node) > 0) {
/* head is after node */
node->next = head;
@@ -242,6 +268,9 @@ brasero_file_node_need_resort (BraseroFileNode *node,
guint oldpos;
guint size;
+ if (node->is_hidden)
+ return NULL;
+
parent = node->parent;
head = BRASERO_FILE_NODE_CHILDREN (parent);
@@ -272,6 +301,7 @@ brasero_file_node_need_resort (BraseroFileNode *node,
parent->union2.children = head;
/* create an array to reflect the changes */
+ /* NOTE: hidden nodes are not taken into account. */
size = brasero_file_node_get_n_children (parent);
array = g_new0 (gint, size);
@@ -284,7 +314,8 @@ brasero_file_node_need_resort (BraseroFileNode *node,
array [i] = i;
}
}
- else if (node->next && sort_func (node, node->next) > 0) {
+ /* Hidden nodes stay at the end, hence the !node->next->is_hidden */
+ else if (node->next && !node->next->is_hidden && sort_func (node, node->next) > 0) {
gint i;
/* move on the right */
@@ -302,7 +333,8 @@ brasero_file_node_need_resort (BraseroFileNode *node,
/* we started from oldpos so newpos needs updating */
newpos += oldpos;
- /* create an array to reflect the changes */
+ /* create an array to reflect the changes. */
+ /* NOTE: hidden nodes are not taken into account. */
size = brasero_file_node_get_n_children (parent);
array = g_new0 (gint, size);
@@ -331,9 +363,11 @@ brasero_file_node_sort_children (BraseroFileNode *parent,
guint oldpos = 1;
guint newpos;
- new_order = BRASERO_FILE_NODE_CHILDREN (parent);
-
/* check for some special cases */
+ if (parent->is_hidden)
+ return NULL;
+
+ new_order = BRASERO_FILE_NODE_CHILDREN (parent);
if (!new_order)
return NULL;
@@ -483,8 +517,11 @@ brasero_file_node_get_n_children (const BraseroFileNode *node)
if (!node)
return 0;
- for (children = BRASERO_FILE_NODE_CHILDREN (node); children; children = children->next)
+ for (children = BRASERO_FILE_NODE_CHILDREN (node); children; children = children->next) {
+ if (children->is_hidden)
+ continue;
num ++;
+ }
return num;
}
@@ -523,6 +560,24 @@ brasero_file_node_is_ancestor (BraseroFileNode *parent,
}
BraseroFileNode *
+brasero_file_node_check_name_existence_case (BraseroFileNode *parent,
+ const gchar *name)
+{
+ BraseroFileNode *iter;
+
+ if (name && name [0] == '\0')
+ return NULL;
+
+ iter = BRASERO_FILE_NODE_CHILDREN (parent);
+ for (; iter; iter = iter->next) {
+ if (!strcasecmp (name, BRASERO_FILE_NODE_NAME (iter)))
+ return iter;
+ }
+
+ return NULL;
+}
+
+BraseroFileNode *
brasero_file_node_check_name_existence (BraseroFileNode *parent,
const gchar *name)
{
@@ -541,6 +596,35 @@ brasero_file_node_check_name_existence (BraseroFileNode *parent,
}
BraseroFileNode *
+brasero_file_node_get_from_path (BraseroFileNode *root,
+ const gchar *path)
+{
+ gchar **array;
+ gchar **iter;
+
+ if (!path)
+ return NULL;
+
+ /* If we don't do that array[0] == '\0' */
+ if (g_str_has_prefix (path, G_DIR_SEPARATOR_S))
+ array = g_strsplit (path + 1, G_DIR_SEPARATOR_S, 0);
+ else
+ array = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
+
+ if (!array)
+ return NULL;
+
+ for (iter = array; iter && *iter; iter++) {
+ root = brasero_file_node_check_name_existence (root, *iter);
+ if (!root)
+ break;
+ }
+ g_strfreev (array);
+
+ return root;
+}
+
+BraseroFileNode *
brasero_file_node_check_imported_sibling (BraseroFileNode *node)
{
BraseroFileNode *parent;
@@ -683,6 +767,10 @@ brasero_file_node_add (BraseroFileNode *parent,
sort_func,
NULL);
node->parent = parent;
+
+ if (BRASERO_FILE_NODE_VIRTUAL (node))
+ return;
+
if (!node->is_imported) {
/* NOTE: parent will be changed afterwards !!! */
if (!node->is_grafted) {
@@ -695,7 +783,8 @@ brasero_file_node_add (BraseroFileNode *parent,
}
}
- /* even imported should be included */
+ /* Even imported should be included. The only type of nodes that are not
+ * heeded are the virtual nodes. */
stats = brasero_file_node_get_tree_stats (node->parent, &depth);
if (node->is_file) {
if (depth < 6)
@@ -727,7 +816,8 @@ brasero_file_node_set_from_info (BraseroFileNode *node,
stats->children ++;
}
- if (!node->is_symlink && (g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK)) {
+ if (!node->is_symlink
+ && (g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK)) {
/* only count files */
stats->num_sym ++;
}
@@ -810,9 +900,7 @@ brasero_file_node_get_uri_name (const gchar *uri)
}
BraseroFileNode *
-brasero_file_node_new_loading (const gchar *name,
- BraseroFileNode *parent,
- GCompareFunc sort_func)
+brasero_file_node_new_loading (const gchar *name)
{
BraseroFileNode *node;
@@ -820,35 +908,39 @@ brasero_file_node_new_loading (const gchar *name,
node->union1.name = g_strdup (name);
node->is_loading = TRUE;
- brasero_file_node_add (parent, node, sort_func);
-
return node;
}
BraseroFileNode *
-brasero_file_node_new_from_info (GFileInfo *info,
- BraseroFileNode *parent,
- GCompareFunc sort_func)
+brasero_file_node_new_virtual (const gchar *name)
{
BraseroFileNode *node;
- BraseroFileTreeStats *stats;
+ /* virtual nodes are nodes that "don't exist". They appear as temporary
+ * parents (and therefore replacable) and hidden (not displayed in the
+ * GtkTreeModel). They are used as 'placeholders' to trigger
+ * name-collision signal. */
node = g_new0 (BraseroFileNode, 1);
- node->union1.name = g_strdup (g_file_info_get_name (info));
+ node->union1.name = g_strdup (name);
+ node->is_fake = TRUE;
+ node->is_hidden = TRUE;
- stats = brasero_file_node_get_tree_stats (parent, NULL);
- brasero_file_node_set_from_info (node, stats, info);
+ return node;
+}
- /* This must be done after above function */
- brasero_file_node_add (parent, node, sort_func);
+BraseroFileNode *
+brasero_file_node_new (const gchar *name)
+{
+ BraseroFileNode *node;
+
+ node = g_new0 (BraseroFileNode, 1);
+ node->union1.name = g_strdup (name);
return node;
}
BraseroFileNode *
-brasero_file_node_new_imported_session_file (GFileInfo *info,
- BraseroFileNode *parent,
- GCompareFunc sort_func)
+brasero_file_node_new_imported_session_file (GFileInfo *info)
{
BraseroFileNode *node;
@@ -865,15 +957,11 @@ brasero_file_node_new_imported_session_file (GFileInfo *info,
else
node->union3.sectors = BRASERO_BYTES_TO_SECTORS (g_file_info_get_size (info), 2048);
- /* Add it (we must add a graft) */
- brasero_file_node_add (parent, node, sort_func);
return node;
}
BraseroFileNode *
-brasero_file_node_new_empty_folder (const gchar *name,
- BraseroFileNode *parent,
- GCompareFunc sort_func)
+brasero_file_node_new_empty_folder (const gchar *name)
{
BraseroFileNode *node;
@@ -882,8 +970,6 @@ brasero_file_node_new_empty_folder (const gchar *name,
node->union1.name = g_strdup (name);
node->is_fake = TRUE;
- /* Add it (we must add a graft) */
- brasero_file_node_add (parent, node, sort_func);
return node;
}
@@ -899,7 +985,9 @@ brasero_file_node_unlink (BraseroFileNode *node)
iter = BRASERO_FILE_NODE_CHILDREN (node->parent);
/* handle the size change for previous parent */
- if (!node->is_grafted && !node->is_imported) {
+ if (!node->is_grafted
+ && !node->is_imported
+ && !BRASERO_FILE_NODE_VIRTUAL (node)) {
BraseroFileNode *parent;
/* handle the size change if it wasn't grafted */
@@ -1028,7 +1116,7 @@ brasero_file_node_destroy_with_children (BraseroFileNode *node,
}
/* update all statistics on tree if any */
- if (stats) {
+ if (!BRASERO_FILE_NODE_VIRTUAL (node) && stats) {
/* check if that's a 2 GiB file */
if (node->is_2GiB)
stats->num_2GiB --;
diff --git a/libbrasero-burn/brasero-file-node.h b/libbrasero-burn/brasero-file-node.h
index fc216b0..685b4d2 100644
--- a/libbrasero-burn/brasero-file-node.h
+++ b/libbrasero-burn/brasero-file-node.h
@@ -147,8 +147,8 @@ struct _BraseroFileNode {
* parent with the same name*/
guint is_tmp_parent:1;
- /* this should be set by BraseroDataDisc */
- guint is_selected:1; /* Used to determne if the name is editable */
+ /* Used to determine if is should be shown */
+ guint is_hidden:1;
/* Used by the model */
/* This is a workaround for a warning in gailtreeview.c line 2946 where
@@ -187,6 +187,9 @@ struct _BraseroFileNode {
#define BRASERO_FILE_NODE_STATS(MACRO_root) \
((MACRO_root)->is_root?(MACRO_root)->union3.stats:NULL)
+#define BRASERO_FILE_NODE_VIRTUAL(MACRO_node) \
+ ((MACRO_node)->is_hidden && (MACRO_node)->is_fake)
+
#define BRASERO_FILE_NODE_IMPORTED_ADDRESS(MACRO_node) \
((MACRO_node) && (MACRO_node)->is_imported && (MACRO_node)->is_fake?(MACRO_node)->union3.imported_address:-1)
@@ -223,9 +226,15 @@ gboolean
brasero_file_node_is_ancestor (BraseroFileNode *parent,
BraseroFileNode *node);
BraseroFileNode *
+brasero_file_node_get_from_path (BraseroFileNode *root,
+ const gchar *path);
+BraseroFileNode *
brasero_file_node_check_name_existence (BraseroFileNode *parent,
const gchar *name);
BraseroFileNode *
+brasero_file_node_check_name_existence_case (BraseroFileNode *parent,
+ const gchar *name);
+BraseroFileNode *
brasero_file_node_check_imported_sibling (BraseroFileNode *node);
/**
@@ -238,21 +247,19 @@ brasero_file_node_add (BraseroFileNode *parent,
GCompareFunc sort_func);
BraseroFileNode *
-brasero_file_node_new_loading (const gchar *name,
- BraseroFileNode *parent,
- GCompareFunc sort_func);
+brasero_file_node_new (const gchar *name);
+
BraseroFileNode *
-brasero_file_node_new_from_info (GFileInfo *info,
- BraseroFileNode *parent,
- GCompareFunc sort_func);
+brasero_file_node_new_virtual (const gchar *name);
+
BraseroFileNode *
-brasero_file_node_new_empty_folder (const gchar *name,
- BraseroFileNode *parent,
- GCompareFunc sort_func);
+brasero_file_node_new_loading (const gchar *name);
+
+BraseroFileNode *
+brasero_file_node_new_empty_folder (const gchar *name);
+
BraseroFileNode *
-brasero_file_node_new_imported_session_file (GFileInfo *info,
- BraseroFileNode *parent,
- GCompareFunc sort_func);
+brasero_file_node_new_imported_session_file (GFileInfo *info);
/**
* If there are any change in the order it cannot be handled in these functions
diff --git a/libbrasero-burn/brasero-src-image.c b/libbrasero-burn/brasero-src-image.c
index d0e001a..bd49515 100644
--- a/libbrasero-burn/brasero-src-image.c
+++ b/libbrasero-burn/brasero-src-image.c
@@ -162,7 +162,8 @@ brasero_src_image_error (BraseroSrcImage *self,
return;
brasero_utils_message_dialog (toplevel,
- _("Please select another image."),
+ /* Translators: this is a disc image, not a picture */
+ C_("disc", "Please select another image."),
error->message,
GTK_MESSAGE_ERROR);
}
diff --git a/libbrasero-burn/brasero-track-data-cfg.c b/libbrasero-burn/brasero-track-data-cfg.c
index dad9514..c4d4030 100644
--- a/libbrasero-burn/brasero-track-data-cfg.c
+++ b/libbrasero-burn/brasero-track-data-cfg.c
@@ -59,8 +59,9 @@ struct _BraseroTrackDataCfgPrivate
BraseroImageFS forced_fs;
BraseroImageFS banned_fs;
- gchar *icon_path;
- gchar *autorun_path;
+ BraseroFileNode *autorun;
+ BraseroFileNode *icon;
+ gchar *image_path;
BraseroDataTreeModel *tree;
guint stamp;
@@ -119,6 +120,7 @@ enum {
RECURSIVE,
UNKNOWN,
G2_FILE,
+ ICON_CHANGED,
NAME_COLLISION,
DEEP_DIRECTORY,
SOURCE_LOADED,
@@ -133,9 +135,34 @@ static gulong brasero_track_data_cfg_signals [LAST_SIGNAL] = { 0 };
* GtkTreeModel part
*/
+static guint
+brasero_track_data_cfg_get_pos_as_child (BraseroFileNode *node)
+{
+ BraseroFileNode *parent;
+ BraseroFileNode *peers;
+ guint pos = 0;
+
+ if (!node)
+ return 0;
+
+ parent = node->parent;
+ for (peers = BRASERO_FILE_NODE_CHILDREN (parent); peers; peers = peers->next) {
+ if (peers == node)
+ break;
+
+ /* Don't increment when is_hidden */
+ if (peers->is_hidden)
+ continue;
+
+ pos ++;
+ }
+
+ return pos;
+}
+
static GtkTreePath *
brasero_track_data_cfg_node_to_path (BraseroTrackDataCfg *self,
- BraseroFileNode *node)
+ BraseroFileNode *node)
{
BraseroTrackDataCfgPrivate *priv;
GtkTreePath *path;
@@ -146,7 +173,7 @@ brasero_track_data_cfg_node_to_path (BraseroTrackDataCfg *self,
for (; node->parent && !node->is_root; node = node->parent) {
guint nth;
- nth = brasero_file_node_get_pos_as_child (node);
+ nth = brasero_track_data_cfg_get_pos_as_child (node);
gtk_tree_path_prepend_index (path, nth);
}
@@ -155,8 +182,8 @@ brasero_track_data_cfg_node_to_path (BraseroTrackDataCfg *self,
static gboolean
brasero_track_data_cfg_iter_parent (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreeIter *child)
+ GtkTreeIter *iter,
+ GtkTreeIter *child)
{
BraseroTrackDataCfgPrivate *priv;
BraseroFileNode *node;
@@ -188,11 +215,36 @@ brasero_track_data_cfg_iter_parent (GtkTreeModel *model,
return TRUE;
}
+static BraseroFileNode *
+brasero_track_data_cfg_nth_child (BraseroFileNode *parent,
+ guint nth)
+{
+ BraseroFileNode *peers;
+ guint pos;
+
+ if (!parent)
+ return NULL;
+
+ peers = BRASERO_FILE_NODE_CHILDREN (parent);
+ while (peers && peers->is_hidden)
+ peers = peers->next;
+
+ for (pos = 0; pos < nth && peers; pos ++) {
+ /* Don't include hidden */
+ if (peers->is_hidden)
+ pos --;
+
+ peers = peers->next;
+ }
+
+ return peers;
+}
+
static gboolean
brasero_track_data_cfg_iter_nth_child (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreeIter *parent,
- gint n)
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n)
{
BraseroTrackDataCfgPrivate *priv;
BraseroFileNode *node;
@@ -215,7 +267,7 @@ brasero_track_data_cfg_iter_nth_child (GtkTreeModel *model,
else
node = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
- iter->user_data = brasero_file_node_nth_child (node, n);
+ iter->user_data = brasero_track_data_cfg_nth_child (node, n);
if (!iter->user_data)
return FALSE;
@@ -224,6 +276,25 @@ brasero_track_data_cfg_iter_nth_child (GtkTreeModel *model,
return TRUE;
}
+static guint
+brasero_track_data_cfg_get_n_children (const BraseroFileNode *node)
+{
+ BraseroFileNode *children;
+ guint num = 0;
+
+ if (!node)
+ return 0;
+
+ for (children = BRASERO_FILE_NODE_CHILDREN (node); children; children = children->next) {
+ if (children->is_hidden)
+ continue;
+
+ num ++;
+ }
+
+ return num;
+}
+
static gint
brasero_track_data_cfg_iter_n_children (GtkTreeModel *model,
GtkTreeIter *iter)
@@ -236,7 +307,7 @@ brasero_track_data_cfg_iter_n_children (GtkTreeModel *model,
if (iter == NULL) {
/* special case */
node = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
- return brasero_file_node_get_n_children (node);
+ return brasero_track_data_cfg_get_n_children (node);
}
/* make sure that iter comes from us */
@@ -251,10 +322,10 @@ brasero_track_data_cfg_iter_n_children (GtkTreeModel *model,
return 0;
/* return at least one for the bogus row labelled "empty". */
- if (!BRASERO_FILE_NODE_CHILDREN (node))
+ if (!brasero_track_data_cfg_get_n_children (node))
return 1;
- return brasero_file_node_get_n_children (node);
+ return brasero_track_data_cfg_get_n_children (node);
}
static gboolean
@@ -309,7 +380,7 @@ brasero_track_data_cfg_iter_children (GtkTreeModel *model,
/* This is for the top directory */
root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
- if (!root || !BRASERO_FILE_NODE_CHILDREN (root))
+ if (!root || !brasero_track_data_cfg_get_n_children (root))
return FALSE;
iter->stamp = priv->stamp;
@@ -334,7 +405,7 @@ brasero_track_data_cfg_iter_children (GtkTreeModel *model,
}
iter->stamp = priv->stamp;
- if (!BRASERO_FILE_NODE_CHILDREN (node)) {
+ if (!brasero_track_data_cfg_get_n_children (node)) {
/* This is a directory but it hasn't got any child; yet
* we show a row written empty for that. Set bogus in
* user_data and put parent in user_data. */
@@ -371,7 +442,7 @@ brasero_track_data_cfg_iter_next (GtkTreeModel *model,
node = iter->user_data;
iter->user_data = node->next;
- if (!node->next)
+ if (!node->next || node->next->is_hidden)
return FALSE;
return TRUE;
@@ -702,7 +773,7 @@ brasero_track_data_cfg_get_value (GtkTreeModel *model,
return;
}
- nb_items = brasero_file_node_get_n_children (node);
+ nb_items = brasero_track_data_cfg_get_n_children (node);
if (!nb_items)
g_value_set_string (value, _("Empty"));
else {
@@ -803,7 +874,7 @@ brasero_track_data_cfg_get_value (GtkTreeModel *model,
static GtkTreePath *
brasero_track_data_cfg_get_path (GtkTreeModel *model,
- GtkTreeIter *iter)
+ GtkTreeIter *iter)
{
BraseroTrackDataCfgPrivate *priv;
BraseroFileNode *node;
@@ -847,7 +918,7 @@ brasero_track_data_cfg_path_to_node (BraseroTrackDataCfg *self,
BraseroFileNode *parent;
parent = node;
- node = brasero_file_node_nth_child (parent, indices [i]);
+ node = brasero_track_data_cfg_nth_child (parent, indices [i]);
if (!node)
return NULL;
}
@@ -876,7 +947,7 @@ brasero_track_data_cfg_get_iter (GtkTreeModel *model,
if (!root)
return FALSE;
- node = brasero_file_node_nth_child (root, indices [0]);
+ node = brasero_track_data_cfg_nth_child (root, indices [0]);
if (!node)
return FALSE;
@@ -884,13 +955,13 @@ brasero_track_data_cfg_get_iter (GtkTreeModel *model,
BraseroFileNode *parent;
parent = node;
- node = brasero_file_node_nth_child (parent, indices [i]);
+ node = brasero_track_data_cfg_nth_child (parent, indices [i]);
if (!node) {
/* There is one case where this can happen and
* is allowed: that's when the parent is an
* empty directory. Then index must be 0. */
if (!parent->is_file
- && !BRASERO_FILE_NODE_CHILDREN (parent)
+ && !brasero_track_data_cfg_get_n_children (parent)
&& indices [i] == 0) {
iter->stamp = priv->stamp;
iter->user_data = parent;
@@ -1198,8 +1269,8 @@ brasero_track_data_cfg_row_drop_possible (GtkTreeDragDest *drag_dest,
static gboolean
brasero_track_data_cfg_get_sort_column_id (GtkTreeSortable *sortable,
- gint *column,
- GtkSortType *type)
+ gint *column,
+ GtkSortType *type)
{
BraseroTrackDataCfgPrivate *priv;
@@ -1216,8 +1287,8 @@ brasero_track_data_cfg_get_sort_column_id (GtkTreeSortable *sortable,
static void
brasero_track_data_cfg_set_sort_column_id (GtkTreeSortable *sortable,
- gint column,
- GtkSortType type)
+ gint column,
+ GtkSortType type)
{
BraseroTrackDataCfgPrivate *priv;
@@ -1258,6 +1329,54 @@ brasero_track_data_cfg_has_default_sort_func (GtkTreeSortable *sortable)
return TRUE;
}
+
+static BraseroFileNode *
+brasero_track_data_cfg_autorun_inf_parse (BraseroTrackDataCfg *track,
+ const gchar *uri)
+{
+ BraseroTrackDataCfgPrivate *priv;
+ BraseroFileNode *root;
+ BraseroFileNode *node;
+ GKeyFile *key_file;
+ gchar *icon_path;
+ gchar *path;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+
+ path = g_filename_from_uri (uri, NULL, NULL);
+ key_file = g_key_file_new ();
+
+ if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, NULL)) {
+ g_key_file_free (key_file);
+ g_free (path);
+ return NULL;
+ }
+ g_free (path);
+
+ /* NOTE: icon_path is the ON DISC path of the icon */
+ icon_path = g_key_file_get_value (key_file, "autorun", "icon", NULL);
+ g_key_file_free (key_file);
+
+ if (icon_path && icon_path [0] == '\0') {
+ g_free (icon_path);
+ return NULL;
+ }
+
+ /* Get the node (hope it already exists) */
+ root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
+ node = brasero_file_node_get_from_path (root, icon_path);
+ if (node) {
+ g_free (icon_path);
+ return node;
+ }
+
+ /* Add a virtual node to get warned when/if the icon is added to the tree */
+ node = brasero_data_project_watch_path (BRASERO_DATA_PROJECT (priv->tree), icon_path);
+ g_free (icon_path);
+
+ return node;
+}
+
static void
brasero_track_data_cfg_node_added (BraseroDataProject *project,
BraseroFileNode *node,
@@ -1270,6 +1389,32 @@ brasero_track_data_cfg_node_added (BraseroDataProject *project,
priv = BRASERO_TRACK_DATA_CFG_PRIVATE (self);
+ if (priv->icon == node) {
+ /* Our icon node has showed up, signal that */
+ g_signal_emit (self,
+ brasero_track_data_cfg_signals [ICON_CHANGED],
+ 0);
+ }
+
+ /* Check if the parent is root */
+ if (node->parent->is_root) {
+ if (!strcasecmp (BRASERO_FILE_NODE_NAME (node), "autorun.inf")) {
+ gchar *uri;
+
+ /* This has been added by the user or by a project so
+ * we do display it; also we signal the change in icon.
+ * NOTE: if we had our own autorun.inf it was wiped out
+ * in the callback for "name-collision". */
+ uri = brasero_data_project_node_to_uri (BRASERO_DATA_PROJECT (priv->tree), node);
+ priv->icon = brasero_track_data_cfg_autorun_inf_parse (self, uri);
+ g_free (uri);
+
+ g_signal_emit (self,
+ brasero_track_data_cfg_signals [ICON_CHANGED],
+ 0);
+ }
+ }
+
iter.stamp = priv->stamp;
iter.user_data = node;
iter.user_data2 = GINT_TO_POINTER (BRASERO_ROW_REGULAR);
@@ -1309,7 +1454,7 @@ brasero_track_data_cfg_node_added (BraseroDataProject *project,
/* Check if the parent of this node is empty if so remove the BOGUS row.
* Do it afterwards to prevent the parent row to be collapsed if it was
* previously expanded. */
- if (parent && brasero_file_node_get_n_children (parent) == 1) {
+ if (parent && brasero_track_data_cfg_get_n_children (parent) == 1) {
gtk_tree_path_append_index (path, 1);
gtk_tree_model_row_deleted (GTK_TREE_MODEL (self), path);
}
@@ -1346,7 +1491,30 @@ brasero_track_data_cfg_node_removed (BraseroDataProject *project,
GtkTreePath *path;
priv = BRASERO_TRACK_DATA_CFG_PRIVATE (self);
-
+ /* NOTE: there is no special case of autorun.inf here when we created
+ * it as a temprary file since it's hidden and BraseroDataTreeModel
+ * won't emit a signal for removed file in this case.
+ * On the other hand we check for a node at root of the CD called
+ * "autorun.inf" just in case an autorun added by the user would be
+ * removed. Do it also for the icon node. */
+ if (former_parent->is_root) {
+ if (!strcasecmp (BRASERO_FILE_NODE_NAME (node), "autorun.inf")) {
+ priv->icon = NULL;
+ g_signal_emit (self,
+ brasero_track_data_cfg_signals [ICON_CHANGED],
+ 0);
+ }
+ else if (priv->icon == node
+ || (priv->icon && !priv->autorun && brasero_file_node_is_ancestor (node, priv->icon))) {
+ /* This icon had been added by the user. Do nothing but
+ * register that the icon is no more on the disc */
+ priv->icon = NULL;
+ g_signal_emit (self,
+ brasero_track_data_cfg_signals [ICON_CHANGED],
+ 0);
+ }
+ }
+
/* remove it from the shown list and all its children as well */
priv->shown = g_slist_remove (priv->shown, node);
for (iter = priv->shown; iter; iter = next) {
@@ -1362,7 +1530,7 @@ brasero_track_data_cfg_node_removed (BraseroDataProject *project,
* add a bogus row. If it hasn't got children then it only remains our
* node in the list.
* NOTE: parent has to be a directory. */
- if (!former_parent->is_root && !BRASERO_FILE_NODE_CHILDREN (former_parent)) {
+ if (!former_parent->is_root && !brasero_track_data_cfg_get_n_children (former_parent)) {
GtkTreeIter iter;
iter.stamp = priv->stamp;
@@ -1428,7 +1596,7 @@ brasero_track_data_cfg_node_changed (BraseroDataProject *project,
NULL);
/* add the row */
- if (!BRASERO_FILE_NODE_CHILDREN (node)) {
+ if (!brasero_track_data_cfg_get_n_children (node)) {
iter.user_data2 = GINT_TO_POINTER (BRASERO_ROW_BOGUS);
gtk_tree_path_append_index (path, 0);
@@ -1474,23 +1642,49 @@ brasero_track_data_cfg_node_reordered (BraseroDataProject *project,
}
static void
-brasero_track_data_cfg_finalize (GObject *object)
+brasero_track_data_clean_autorun (BraseroTrackDataCfg *track)
{
+ gchar *uri;
+ gchar *path;
BraseroTrackDataCfgPrivate *priv;
- priv = BRASERO_TRACK_DATA_CFG_PRIVATE (object);
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
- if (priv->icon_path) {
- g_remove (priv->icon_path);
- g_free (priv->icon_path);
- priv->icon_path = NULL;
+ if (priv->image_path) {
+ g_free (priv->image_path);
+ priv->image_path = NULL;
}
- if (priv->autorun_path) {
- g_remove (priv->autorun_path);
- g_free (priv->autorun_path);
- priv->autorun_path = NULL;
+ if (priv->autorun) {
+ /* ONLY remove icon if it's our own */
+ if (priv->icon) {
+ uri = brasero_data_project_node_to_uri (BRASERO_DATA_PROJECT (priv->tree), priv->icon);
+ path = g_filename_from_uri (uri, NULL, NULL);
+ g_free (uri);
+ g_remove (path);
+ g_free (path);
+ priv->icon = NULL;
+ }
+
+ uri = brasero_data_project_node_to_uri (BRASERO_DATA_PROJECT (priv->tree), priv->autorun);
+ path = g_filename_from_uri (uri, NULL, NULL);
+ g_free (uri);
+ g_remove (path);
+ g_free (path);
+ priv->autorun = NULL;
}
+ else
+ priv->icon = NULL;
+}
+
+static void
+brasero_track_data_cfg_finalize (GObject *object)
+{
+ BraseroTrackDataCfgPrivate *priv;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (object);
+
+ brasero_track_data_clean_autorun (BRASERO_TRACK_DATA_CFG (object));
if (priv->shown) {
g_slist_free (priv->shown);
@@ -1614,8 +1808,8 @@ brasero_track_data_cfg_add_empty_directory (BraseroTrackDataCfg *track,
const gchar *name,
GtkTreePath *parent)
{
+ BraseroFileNode *parent_node = NULL;
BraseroTrackDataCfgPrivate *priv;
- BraseroFileNode *parent_node;
gchar *default_name = NULL;
BraseroFileNode *node;
@@ -1630,7 +1824,8 @@ brasero_track_data_cfg_add_empty_directory (BraseroTrackDataCfg *track,
if (parent_node && (parent_node->is_file || parent_node->is_loading))
parent_node = parent_node->parent;
}
- else
+
+ if (!parent_node)
parent_node = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
if (!name) {
@@ -1704,8 +1899,11 @@ brasero_track_data_cfg_reset (BraseroTrackDataCfg *track)
if (priv->loading)
return FALSE;
+ /* Do it now */
+ brasero_track_data_clean_autorun (track);
+
root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
- num = brasero_file_node_get_n_children (root);
+ num = brasero_track_data_cfg_get_n_children (root);
brasero_data_project_reset (BRASERO_DATA_PROJECT (priv->tree));
@@ -1717,18 +1915,6 @@ brasero_track_data_cfg_reset (BraseroTrackDataCfg *track)
g_slist_free (priv->shown);
priv->shown = NULL;
- if (priv->icon_path) {
- g_remove (priv->icon_path);
- g_free (priv->icon_path);
- priv->icon_path = NULL;
- }
-
- if (priv->autorun_path) {
- g_remove (priv->autorun_path);
- g_free (priv->autorun_path);
- priv->autorun_path = NULL;
- }
-
priv->G2_files = FALSE;
priv->deep_directory = FALSE;
@@ -1923,6 +2109,26 @@ brasero_track_data_cfg_get_fs (BraseroTrackData *track)
return fs_type;
}
+gboolean
+brasero_track_data_cfg_get_contents (BraseroTrackData *track,
+ GSList **grafts,
+ GSList **excluded)
+{
+ BraseroTrackDataCfgPrivate *priv;
+
+ g_return_val_if_fail (BRASERO_IS_TRACK_DATA_CFG (track), FALSE);
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+
+ /* append a slash for mkisofs */
+ brasero_data_project_get_contents (BRASERO_DATA_PROJECT (priv->tree),
+ grafts,
+ excluded,
+ FALSE, /* no hidden node */
+ FALSE, /* no grafts for joliet incompatible nodes */
+ FALSE); /* no final slash for names */
+ return TRUE;
+}
+
static GSList *
brasero_track_data_cfg_get_grafts (BraseroTrackData *track)
{
@@ -1937,6 +2143,7 @@ brasero_track_data_cfg_get_grafts (BraseroTrackData *track)
brasero_data_project_get_contents (BRASERO_DATA_PROJECT (priv->tree),
&grafts,
NULL,
+ TRUE, /* include hidden nodes */
(fs_type & BRASERO_IMAGE_FS_JOLIET) != 0,
TRUE);
return grafts;
@@ -1956,6 +2163,7 @@ brasero_track_data_cfg_get_excluded (BraseroTrackData *track)
brasero_data_project_get_contents (BRASERO_DATA_PROJECT (priv->tree),
NULL,
&unreadable,
+ TRUE, /* include hidden nodes */
(fs_type & BRASERO_IMAGE_FS_JOLIET) != 0,
TRUE);
return unreadable;
@@ -2170,8 +2378,90 @@ brasero_track_data_cfg_unknown_uri_cb (BraseroDataVFS *vfs,
}
static gboolean
+brasero_track_data_cfg_autorun_inf_update (BraseroTrackDataCfg *self)
+{
+ BraseroTrackDataCfgPrivate *priv;
+ gchar *icon_path = NULL;
+ gsize data_size = 0;
+ GKeyFile *key_file;
+ gchar *data = NULL;
+ gchar *path = NULL;
+ gchar *uri;
+ int fd;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (self);
+
+ uri = brasero_data_project_node_to_uri (BRASERO_DATA_PROJECT (priv->tree), priv->autorun);
+ path = g_filename_from_uri (uri, NULL, NULL);
+ g_free (uri);
+
+ fd = open (path, O_WRONLY|O_TRUNC);
+ g_free (path);
+
+ if (fd == -1)
+ return FALSE;
+
+ icon_path = brasero_data_project_node_to_path (BRASERO_DATA_PROJECT (priv->tree), priv->icon);
+
+ /* Write the autorun.inf if we don't have one yet */
+ key_file = g_key_file_new ();
+ g_key_file_set_value (key_file, "autorun", "icon", icon_path);
+ g_free (icon_path);
+
+ data = g_key_file_to_data (key_file, &data_size, NULL);
+ g_key_file_free (key_file);
+
+ if (write (fd, data, data_size) == -1) {
+ g_free (data);
+ close (fd);
+ return FALSE;
+ }
+
+ g_free (data);
+ close (fd);
+ return TRUE;
+}
+
+static gchar *
+brasero_track_data_cfg_find_icon_name (BraseroTrackDataCfg *track)
+{
+ BraseroTrackDataCfgPrivate *priv;
+ BraseroFileNode *root;
+ gchar *name = NULL;
+ int i = 0;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+
+ root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
+ do {
+ g_free (name);
+ name = g_strdup_printf ("Autorun%i.ico", i);
+ } while (brasero_file_node_check_name_existence (root, name));
+
+ return name;
+}
+
+static void
+brasero_track_data_cfg_virtual_sibling_cb (BraseroDataProject *project,
+ BraseroFileNode *node,
+ BraseroFileNode *sibling,
+ BraseroTrackDataCfg *self)
+{
+ BraseroTrackDataCfgPrivate *priv;
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (self);
+ if (sibling == priv->icon) {
+ /* This is a warning that the icon has been added. Update our
+ * icon node and wait for it to appear in the callback for the
+ * 'node-added' signal. Then we'll be able to fire the "icon-
+ * changed" signal. */
+ priv->icon = node;
+ }
+}
+
+static gboolean
brasero_track_data_cfg_name_collision_cb (BraseroDataProject *project,
- const gchar *name,
+ BraseroFileNode *node,
BraseroTrackDataCfg *self)
{
BraseroTrackDataCfgPrivate *priv;
@@ -2179,6 +2469,51 @@ brasero_track_data_cfg_name_collision_cb (BraseroDataProject *project,
priv = BRASERO_TRACK_DATA_CFG_PRIVATE (self);
+ /* some names are interesting for us */
+ if (node == priv->autorun) {
+ BraseroFileNode *icon;
+
+ /* An autorun.inf has been added by the user. Whether or not we
+ * are loading a project, if there is an autorun.inf file, then
+ * wipe it, parse the new and signal */
+
+ /* Save icon node as we'll need it afterwards to remove it */
+ icon = priv->icon;
+
+ /* Do it now as this is the hidden temporarily created
+ * graft point whose deletion won't be signalled by
+ * BraseroDataTreeModel */
+ brasero_track_data_clean_autorun (self);
+ brasero_data_project_remove_node (BRASERO_DATA_PROJECT (priv->tree), icon);
+
+ g_signal_emit (self,
+ brasero_track_data_cfg_signals [ICON_CHANGED],
+ 0);
+
+ return FALSE;
+ }
+ else if (node == priv->icon) {
+ gchar *uri;
+ gchar *name = NULL;
+ BraseroFileNode *root;
+
+ /* we need to recreate another one with a different name */
+ uri = brasero_data_project_node_to_uri (BRASERO_DATA_PROJECT (priv->tree), node);
+ root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
+ name = brasero_track_data_cfg_find_icon_name (self);
+
+ priv->icon = brasero_data_project_add_hidden_node (BRASERO_DATA_PROJECT (priv->tree),
+ uri,
+ name,
+ root);
+ g_free (name);
+ g_free (uri);
+
+ /* Update our autorun.inf */
+ brasero_track_data_cfg_autorun_inf_update (self);
+ return FALSE;
+ }
+
if (priv->loading) {
/* don't do anything accept replacement */
return FALSE;
@@ -2187,7 +2522,7 @@ brasero_track_data_cfg_name_collision_cb (BraseroDataProject *project,
g_signal_emit (self,
brasero_track_data_cfg_signals [NAME_COLLISION],
0,
- name,
+ BRASERO_FILE_NODE_NAME (node),
&result);
return result;
}
@@ -2423,124 +2758,179 @@ brasero_track_data_cfg_span_stop (BraseroTrackDataCfg *track)
}
/**
- * This is to handle icons
+ * This is to handle the icon for the image
*/
-BraseroBurnResult
+gchar *
+brasero_track_data_cfg_get_scaled_icon_path (BraseroTrackDataCfg *track)
+{
+ BraseroTrackDataCfgPrivate *priv;
+ gchar *path;
+ gchar *uri;
+
+ g_return_val_if_fail (BRASERO_IS_TRACK_DATA_CFG (track), NULL);
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+ if (!priv->icon || BRASERO_FILE_NODE_VIRTUAL (priv->icon))
+ return NULL;
+
+ uri = brasero_data_project_node_to_uri (BRASERO_DATA_PROJECT (priv->tree), priv->icon);
+ path = g_filename_from_uri (uri, NULL, NULL);
+ g_free (uri);
+
+ return path;
+}
+
+const gchar *
+brasero_track_data_cfg_get_icon_path (BraseroTrackDataCfg *track)
+{
+ BraseroTrackDataCfgPrivate *priv;
+
+ g_return_val_if_fail (BRASERO_IS_TRACK_DATA_CFG (track), NULL);
+
+ priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+ return priv->image_path;
+}
+
+gboolean
brasero_track_data_cfg_set_icon (BraseroTrackDataCfg *track,
- const gchar *path)
+ const gchar *icon_path,
+ GError **error)
{
gboolean result;
GdkPixbuf *pixbuf;
- GError *error = NULL;
BraseroFileNode *root;
BraseroTrackDataCfgPrivate *priv;
+ g_return_val_if_fail (BRASERO_IS_TRACK_DATA_CFG (track), FALSE);
+
priv = BRASERO_TRACK_DATA_CFG_PRIVATE (track);
+ /* Check whether we don't have an added (by the user) autorun.inf as it
+ * won't be possible to edit it. */
+ root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
+
+ if (!priv->autorun) {
+ if (brasero_file_node_check_name_existence_case (root, "autorun.inf")) {
+ /* There is a native autorun.inf file. That's why we can't edit
+ * it; even if we were to create a temporary file with just the
+ * icon changed then we could not save it as a project later.
+ * If I change my mind, I should remember that it the path is
+ * the value ON DISC. */
+ return FALSE;
+ }
+ }
+
/* Load and convert (48x48) the image into a pixbuf */
- pixbuf = gdk_pixbuf_new_from_file_at_scale (path,
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (icon_path,
48,
48,
FALSE,
- &error);
+ error);
if (!pixbuf)
- return BRASERO_BURN_ERR;
-
- root = brasero_data_project_get_root (BRASERO_DATA_PROJECT (priv->tree));
+ return FALSE;
/* See if we already have an icon set. If we do, reuse the tmp file */
- if (!priv->icon_path) {
- BraseroFileNode *node;
+ if (!priv->icon) {
gchar *buffer = NULL;
gchar *path = NULL;
+ gchar *name = NULL;
gsize buffer_size;
int icon_fd;
gchar *uri;
icon_fd = g_file_open_tmp (BRASERO_BURN_TMP_FILE_NAME,
&path,
- NULL);
+ error);
if (icon_fd == -1) {
g_object_unref (pixbuf);
- return BRASERO_BURN_ERR;
+ return FALSE;
}
/* Add it as a graft to the project */
uri = g_filename_to_uri (path, NULL, NULL);
- node = brasero_data_project_add_loading_node (BRASERO_DATA_PROJECT (priv->tree), uri, root);
- brasero_data_project_rename_node (BRASERO_DATA_PROJECT (priv->tree), node, "Autorun.ico");
- g_free (uri);
+ g_free (path);
- /* That's just to be able to remove it later */
- priv->icon_path = path;
+ name = brasero_track_data_cfg_find_icon_name (track);
+ priv->icon = brasero_data_project_add_hidden_node (BRASERO_DATA_PROJECT (priv->tree),
+ uri,
+ name,
+ root);
+ g_free (name);
+ g_free (uri);
/* Write it as an "ico" file (or a png?) */
result = gdk_pixbuf_save_to_buffer (pixbuf,
&buffer,
&buffer_size,
"ico",
- NULL,
+ error,
NULL);
if (!result) {
close (icon_fd);
g_object_unref (pixbuf);
- return BRASERO_BURN_ERR;
+ return FALSE;
}
if (write (icon_fd, buffer, buffer_size) == -1) {
g_object_unref (pixbuf);
g_free (buffer);
close (icon_fd);
- return BRASERO_BURN_ERR;
+ return FALSE;
}
g_free (buffer);
close (icon_fd);
}
else {
+ gchar *path;
+
+ path = brasero_track_data_cfg_get_scaled_icon_path (track);
+
/* Write it as an "ico" file (or a png?) */
result = gdk_pixbuf_save (pixbuf,
- priv->icon_path,
+ path,
"ico",
- &error,
+ error,
NULL);
+ g_free (path);
+
+ if (!result) {
+ g_object_unref (pixbuf);
+ return FALSE;
+ }
}
g_object_unref (pixbuf);
- /* Get a temporary file if we don't have one yet */
- if (!priv->autorun_path) {
- const char *line = "[autorun]\nicon=Autorun.ico";
- BraseroFileNode *node;
+ if (!priv->autorun) {
gchar *path = NULL;
gchar *uri;
int fd;
+ /* Get a temporary file if we don't have one yet */
fd = g_file_open_tmp (BRASERO_BURN_TMP_FILE_NAME,
&path,
- NULL);
- if (fd == -1)
- return BRASERO_BURN_ERR;
-
- /* Write the autorun.inf if we don't have one yet */
- if (write (fd, line, sizeof (line)) == -1) {
- close (fd);
- return BRASERO_BURN_ERR;
- }
+ error);
close (fd);
/* Add it as a graft to the project */
uri = g_filename_to_uri (path, NULL, NULL);
- node = brasero_data_project_add_loading_node (BRASERO_DATA_PROJECT (priv->tree), uri, root);
- brasero_data_project_rename_node (BRASERO_DATA_PROJECT (priv->tree), node, "Autorun.inf");
+ priv->autorun = brasero_data_project_add_hidden_node (BRASERO_DATA_PROJECT (priv->tree),
+ uri,
+ "autorun.inf",
+ root);
g_free (uri);
- /* That's just to be able to remove it later */
- priv->autorun_path = path;
+ /* write the autorun.inf */
+ brasero_track_data_cfg_autorun_inf_update (track);
}
- return BRASERO_BURN_OK;
+ priv->image_path = g_strdup (icon_path);
+ g_signal_emit (track,
+ brasero_track_data_cfg_signals [ICON_CHANGED],
+ 0);
+ return TRUE;
}
static void
@@ -2626,6 +3016,10 @@ brasero_track_data_cfg_init (BraseroTrackDataCfg *object)
G_CALLBACK (brasero_track_data_cfg_image_uri_cb),
object);
g_signal_connect (priv->tree,
+ "virtual-sibling",
+ G_CALLBACK (brasero_track_data_cfg_virtual_sibling_cb),
+ object);
+ g_signal_connect (priv->tree,
"name-collision",
G_CALLBACK (brasero_track_data_cfg_name_collision_cb),
object);
@@ -2795,6 +3189,17 @@ brasero_track_data_cfg_class_init (BraseroTrackDataCfgClass *klass)
G_TYPE_NONE,
1,
G_TYPE_POINTER);
+
+ brasero_track_data_cfg_signals [ICON_CHANGED] =
+ g_signal_new ("icon_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST|G_SIGNAL_NO_RECURSE,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0,
+ G_TYPE_NONE);
}
BraseroTrackDataCfg *
diff --git a/libbrasero-burn/brasero-track-data-cfg.h b/libbrasero-burn/brasero-track-data-cfg.h
index 5a860d2..ec39ccf 100644
--- a/libbrasero-burn/brasero-track-data-cfg.h
+++ b/libbrasero-burn/brasero-track-data-cfg.h
@@ -89,6 +89,11 @@ BraseroTrackDataCfg *
brasero_track_data_cfg_new (void);
gboolean
+brasero_track_data_cfg_get_contents (BraseroTrackData *track,
+ GSList **grafts,
+ GSList **excluded);
+
+gboolean
brasero_track_data_cfg_add (BraseroTrackDataCfg *track,
const gchar *uri,
GtkTreePath *parent);
@@ -148,9 +153,6 @@ brasero_track_data_cfg_restore (BraseroTrackDataCfg *track,
GtkTreeModel *
brasero_track_data_cfg_get_filtered_model (BraseroTrackDataCfg *track);
-BraseroBurnResult
-brasero_track_data_cfg_set_icon (BraseroTrackDataCfg *track,
- const gchar *path);
/**
* Track Spanning
@@ -173,10 +175,16 @@ brasero_track_data_cfg_span_stop (BraseroTrackDataCfg *track);
/**
* Icon
*/
+gchar *
+brasero_track_data_cfg_get_scaled_icon_path (BraseroTrackDataCfg *track);
-BraseroBurnResult
+const gchar *
+brasero_track_data_cfg_get_icon_path (BraseroTrackDataCfg *track);
+
+gboolean
brasero_track_data_cfg_set_icon (BraseroTrackDataCfg *track,
- const gchar *path);
+ const gchar *path,
+ GError **error);
G_END_DECLS
diff --git a/libbrasero-burn/libbrasero-marshal.list b/libbrasero-burn/libbrasero-marshal.list
index 63dee6b..69bfeb8 100644
--- a/libbrasero-burn/libbrasero-marshal.list
+++ b/libbrasero-burn/libbrasero-marshal.list
@@ -4,6 +4,7 @@ INT:STRING
INT:OBJECT,INT,INT
INT:POINTER,BOOLEAN
BOOLEAN:STRING
+BOOLEAN:POINTER
VOID:INT,STRING
VOID:POINTER,STRING
VOID:POINTER,POINTER
diff --git a/src/brasero-data-disc.c b/src/brasero-data-disc.c
index 1fc0e6d..35fd842 100644
--- a/src/brasero-data-disc.c
+++ b/src/brasero-data-disc.c
@@ -168,6 +168,13 @@ static GtkTargetEntry ntables_source [] = {
static guint nb_targets_source = sizeof (ntables_source) / sizeof (ntables_source[0]);
enum {
+ ICON_CHANGED,
+ LAST_SIGNAL
+};
+
+static gulong brasero_data_disc_signals [LAST_SIGNAL] = { 0 };
+
+enum {
PROP_NONE,
PROP_REJECT_FILE,
};
@@ -322,6 +329,8 @@ brasero_data_disc_new_folder_clicked_cb (GtkButton *button,
parent = brasero_data_disc_get_parent (disc);
treepath = brasero_track_data_cfg_add_empty_directory (BRASERO_TRACK_DATA_CFG (priv->project), NULL, parent);
+ gtk_tree_path_free (parent);
+
gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 1);
/* grab focus must be called before next function to avoid
@@ -497,8 +506,10 @@ brasero_data_disc_name_edited_cb (GtkCellRendererText *cellrenderertext,
if (name && !strcmp (name, text)) {
gtk_tree_path_free (path);
+ g_free (name);
return;
}
+ g_free (name);
/* NOTE: BraseroDataProject is where we handle name collisions,
* UTF-8 validity, ...
@@ -1137,6 +1148,15 @@ brasero_data_disc_session_available_cb (BraseroTrackDataCfg *session,
}
static void
+brasero_data_disc_icon_changed_cb (BraseroTrackDataCfg *session,
+ BraseroDataDisc *self)
+{
+ g_signal_emit (self,
+ brasero_data_disc_signals [ICON_CHANGED],
+ 0);
+}
+
+static void
brasero_data_disc_session_loaded_cb (BraseroTrackDataCfg *session,
BraseroMedium *medium,
gboolean loaded,
@@ -1321,18 +1341,23 @@ static BraseroDiscResult
brasero_data_disc_get_track (BraseroDisc *disc,
BraseroDiscTrack *track)
{
+ gboolean res;
GSList *grafts = NULL;
+ GSList *excluded = NULL;
BraseroDataDiscPrivate *priv;
priv = BRASERO_DATA_DISC_PRIVATE (disc);
- grafts = brasero_track_data_get_grafts (BRASERO_TRACK_DATA (priv->project));
- if (!grafts)
+ res = brasero_track_data_cfg_get_contents (BRASERO_TRACK_DATA (priv->project),
+ &grafts,
+ &excluded);
+ if (!res)
return BRASERO_DISC_ERROR_EMPTY_SELECTION;
+ track->contents.data.icon = g_strdup (brasero_track_data_cfg_get_icon_path (priv->project));
track->type = BRASERO_PROJECT_TYPE_DATA;
track->contents.data.grafts = grafts;
- track->contents.data.excluded = brasero_track_data_get_excluded (BRASERO_TRACK_DATA (priv->project), TRUE);
+ track->contents.data.excluded = excluded;
/* get restored */
track->contents.data.restored = brasero_track_data_cfg_get_restored_list (BRASERO_TRACK_DATA_CFG (priv->project));
@@ -1387,7 +1412,7 @@ brasero_data_disc_load_track (BraseroDisc *disc,
gchar *uri;
uri = iter->data;
- brasero_track_data_cfg_dont_filter_uri (BRASERO_TRACK_DATA_CFG (priv->project), uri);
+ brasero_track_data_cfg_dont_filter_uri (priv->project, uri);
}
res = brasero_track_data_set_source (BRASERO_TRACK_DATA (priv->project),
@@ -1435,6 +1460,11 @@ brasero_data_disc_load_track (BraseroDisc *disc,
gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 1);
brasero_status_free (status);
+
+ /* The icon */
+ if (track->contents.data.icon)
+ brasero_track_data_cfg_set_icon (priv->project, track->contents.data.icon, NULL);
+
return BRASERO_DISC_OK;
}
@@ -2067,13 +2097,33 @@ brasero_data_disc_contents_removed_cb (GtkTreeModel *model,
BraseroDataDiscPrivate *priv;
priv = BRASERO_DATA_DISC_PRIVATE (self);
-
brasero_disc_contents_changed (BRASERO_DISC (self), gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->project), NULL));
}
/**
- * Object creation/destruction
+ * Misc functions
*/
+
+gboolean
+brasero_data_disc_set_icon_path (BraseroDataDisc *self,
+ const gchar *path,
+ GError **error)
+{
+ BraseroDataDiscPrivate *priv;
+
+ priv = BRASERO_DATA_DISC_PRIVATE (self);
+ return brasero_track_data_cfg_set_icon (priv->project, path, error);
+}
+
+gchar *
+brasero_data_disc_get_scaled_icon_path (BraseroDataDisc *disc)
+{
+ BraseroDataDiscPrivate *priv;
+
+ priv = BRASERO_DATA_DISC_PRIVATE (disc);
+ return brasero_track_data_cfg_get_scaled_icon_path (priv->project);
+}
+
void
brasero_data_disc_set_right_button_group (BraseroDataDisc *self,
GtkSizeGroup *size_group)
@@ -2084,6 +2134,9 @@ brasero_data_disc_set_right_button_group (BraseroDataDisc *self,
brasero_file_filtered_set_right_button_group (BRASERO_FILE_FILTERED (priv->filter), size_group);
}
+/**
+ * Object creation/destruction
+ */
static void
brasero_data_disc_init (BraseroDataDisc *object)
{
@@ -2182,6 +2235,11 @@ brasero_data_disc_init (BraseroDataDisc *object)
G_CALLBACK (brasero_data_disc_session_loaded_cb),
object);
+ g_signal_connect (priv->project,
+ "icon-changed",
+ G_CALLBACK (brasero_data_disc_icon_changed_cb),
+ object);
+
/* Tree */
priv->tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->project));
gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (priv->tree), TRUE);
@@ -2419,6 +2477,17 @@ brasero_data_disc_class_init (BraseroDataDiscClass *klass)
object_class->set_property = brasero_data_disc_set_property;
object_class->get_property = brasero_data_disc_get_property;
+ brasero_data_disc_signals [ICON_CHANGED] =
+ g_signal_new ("icon_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST|G_SIGNAL_NO_RECURSE,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0,
+ G_TYPE_NONE);
+
g_object_class_install_property (object_class,
PROP_REJECT_FILE,
g_param_spec_boolean
diff --git a/src/brasero-data-disc.h b/src/brasero-data-disc.h
index b640bb7..504273d 100644
--- a/src/brasero-data-disc.h
+++ b/src/brasero-data-disc.h
@@ -56,6 +56,13 @@ GType brasero_data_disc_get_type (void) G_GNUC_CONST;
GtkWidget *
brasero_data_disc_new (void);
+gboolean
+brasero_data_disc_set_icon_path (BraseroDataDisc *disc,
+ const gchar *path,
+ GError **error);
+gchar *
+brasero_data_disc_get_scaled_icon_path (BraseroDataDisc *disc);
+
void
brasero_data_disc_set_right_button_group (BraseroDataDisc *disc,
GtkSizeGroup *size_group);
diff --git a/src/brasero-project-parse.c b/src/brasero-project-parse.c
index e0a4c2a..f3e9b34 100644
--- a/src/brasero-project-parse.c
+++ b/src/brasero-project-parse.c
@@ -113,6 +113,9 @@ brasero_track_clear (BraseroDiscTrack *track)
g_slist_free (track->contents.tracks);
}
else if (track->type == BRASERO_PROJECT_TYPE_DATA) {
+ g_free (track->contents.data.icon);
+ track->contents.data.icon = NULL;
+
g_slist_foreach (track->contents.data.grafts, (GFunc) brasero_graft_point_free, NULL);
g_slist_free (track->contents.data.grafts);
g_slist_foreach (track->contents.data.restored, (GFunc) g_free, NULL);
@@ -212,6 +215,20 @@ _read_data_track (xmlDocPtr project,
if (!_read_graft_point (project, item->xmlChildrenNode, track))
goto error;
}
+ else if (!xmlStrcmp (item->name, (const xmlChar *) "icon")) {
+ xmlChar *icon_path;
+
+ icon_path = xmlNodeListGetString (project,
+ item->xmlChildrenNode,
+ 1);
+ if (!icon_path)
+ goto error;
+
+ if (track->contents.data.icon)
+ g_free (track->contents.data.icon);
+
+ track->contents.data.icon = (gchar *) icon_path;
+ }
else if (!xmlStrcmp (item->name, (const xmlChar *) "restored")) {
xmlChar *restored;
diff --git a/src/brasero-project-parse.h b/src/brasero-project-parse.h
index 3e365a6..e00593e 100644
--- a/src/brasero-project-parse.h
+++ b/src/brasero-project-parse.h
@@ -78,6 +78,7 @@ typedef struct {
GSList *grafts;
GSList *excluded;
GSList *restored;
+ gchar *icon;
} data;
GSList *tracks; /* BraseroDiscSong */
diff --git a/src/brasero-project.c b/src/brasero-project.c
index 928374c..b2a2ddc 100644
--- a/src/brasero-project.c
+++ b/src/brasero-project.c
@@ -154,6 +154,8 @@ typedef enum {
struct BraseroProjectPrivate {
GtkWidget *name_display;
+ GtkWidget *button_img;
+ GtkWidget *icon_img;
GtkWidget *discs;
GtkWidget *audio;
GtkWidget *data;
@@ -417,10 +419,121 @@ brasero_project_name_changed_cb (BraseroProjectName *name,
}
static void
+brasero_project_data_icon_error (BraseroProject *project,
+ GError *error)
+{
+ if (error) {
+ brasero_app_alert (brasero_app_get_default (),
+ /* Translators: this is a picture not
+ * a disc image */
+ C_("picture", "Please select another image."),
+ error->message,
+ GTK_MESSAGE_ERROR);
+ }
+ else {
+ brasero_app_alert (brasero_app_get_default (),
+ /* Translators: this is a picture not
+ * a disc image */
+ C_("picture", "Please select another image."),
+ _("Unknown error"),
+ GTK_MESSAGE_ERROR);
+ }
+}
+
+static void
+brasero_project_icon_changed_cb (BraseroDisc *disc,
+ BraseroProject *project)
+{
+ GError *error = NULL;
+ GdkPixbuf *pixbuf;
+ gchar *icon;
+
+ icon = brasero_data_disc_get_scaled_icon_path (BRASERO_DATA_DISC (project->priv->current));
+ if (!icon) {
+ gtk_image_set_from_icon_name (GTK_IMAGE (project->priv->icon_img),
+ "media-optical",
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ return;
+ }
+
+ /* Load and convert (48x48) the image into a pixbuf */
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (icon,
+ 48,
+ 48,
+ FALSE,
+ &error);
+ g_free (icon);
+
+ if (!pixbuf) {
+ gtk_image_set_from_icon_name (GTK_IMAGE (project->priv->icon_img),
+ "media-optical",
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+ brasero_project_data_icon_error (project, error);
+ g_error_free (error);
+ return;
+ }
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (project->priv->icon_img), pixbuf);
+ g_object_unref (pixbuf);
+}
+
+static void
+brasero_project_icon_button_clicked (GtkWidget *button,
+ BraseroProject *project)
+{
+ GtkFileFilter *filter;
+ GError *error = NULL;
+ GtkWidget *chooser;
+ gchar *path;
+ gint res;
+
+ if (!BRASERO_IS_DATA_DISC (project->priv->current))
+ return;
+
+ chooser = gtk_file_chooser_dialog_new (_("Medium Icon"),
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (project))),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("All files"));
+ gtk_file_filter_add_pattern (filter, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+ filter = gtk_file_filter_new ();
+ /* Translators: this is an image, a picture, not a "Disc Image" */
+ gtk_file_filter_set_name (filter, C_("picture", "Image files"));
+ gtk_file_filter_add_mime_type (filter, "image/*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+ gtk_widget_show (chooser);
+ res = gtk_dialog_run (GTK_DIALOG (chooser));
+ if (res != GTK_RESPONSE_OK) {
+ gtk_widget_destroy (chooser);
+ return;
+ }
+
+ path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
+ gtk_widget_destroy (chooser);
+
+ if (!brasero_data_disc_set_icon_path (BRASERO_DATA_DISC (project->priv->current), path, &error)) {
+ if (error) {
+ brasero_project_data_icon_error (project, error);
+ g_error_free (error);
+ }
+ }
+ g_free (path);
+}
+
+static void
brasero_project_init (BraseroProject *obj)
{
GtkSizeGroup *size_group;
GtkWidget *alignment;
+ GtkWidget *button;
+ GtkWidget *image;
GtkWidget *label;
GtkWidget *box;
@@ -441,6 +554,25 @@ brasero_project_init (BraseroProject *obj)
gtk_widget_show (box);
gtk_box_pack_end (GTK_BOX (obj), box, FALSE, TRUE, 0);
+ /* Icon button */
+ image = gtk_image_new_from_icon_name ("media-optical", GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_widget_show (image);
+ obj->priv->icon_img = image;
+
+ button = gtk_button_new ();
+ gtk_widget_show (button);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ obj->priv->button_img = button;
+
+ gtk_widget_set_tooltip_text (button, _("Select an icon for the disc that will appear in file managers"));
+
+ g_signal_connect (button,
+ "clicked",
+ G_CALLBACK (brasero_project_icon_button_clicked),
+ obj);
+
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, TRUE, 0);
+
/* Name widget */
label = gtk_label_new_with_mnemonic (_("_Name:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
@@ -517,6 +649,10 @@ brasero_project_init (BraseroProject *obj)
"selection-changed",
G_CALLBACK (brasero_project_selection_changed_cb),
obj);
+ g_signal_connect (obj->priv->data,
+ "icon-changed",
+ G_CALLBACK (brasero_project_icon_changed_cb),
+ obj);
obj->priv->video = brasero_video_disc_new ();
gtk_widget_show (obj->priv->video);
@@ -1015,6 +1151,10 @@ brasero_project_switch (BraseroProject *project, BraseroProjectType type)
project->priv->project_status = NULL;
}
+ gtk_image_set_from_icon_name (GTK_IMAGE (project->priv->icon_img),
+ "media-optical",
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+
if (project->priv->current)
brasero_disc_reset (project->priv->current);
@@ -1046,6 +1186,7 @@ brasero_project_switch (BraseroProject *project, BraseroProjectType type)
project->priv->merge_id);
if (type == BRASERO_PROJECT_TYPE_AUDIO) {
+ gtk_widget_hide (project->priv->button_img);
project->priv->current = BRASERO_DISC (project->priv->audio);
project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
project->priv->manager,
@@ -1055,6 +1196,7 @@ brasero_project_switch (BraseroProject *project, BraseroProjectType type)
brasero_project_update_project_size (project, 0);
}
else if (type == BRASERO_PROJECT_TYPE_DATA) {
+ gtk_widget_show (project->priv->button_img);
project->priv->current = BRASERO_DISC (project->priv->data);
project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
project->priv->manager,
@@ -1064,6 +1206,7 @@ brasero_project_switch (BraseroProject *project, BraseroProjectType type)
brasero_project_update_project_size (project, 0);
}
else if (type == BRASERO_PROJECT_TYPE_VIDEO) {
+ gtk_widget_hide (project->priv->button_img);
project->priv->current = BRASERO_DISC (project->priv->video);
project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
project->priv->manager,
@@ -1979,6 +2122,13 @@ _save_data_track_xml (xmlTextWriter *project,
GSList *grafts;
BraseroGraftPt *graft;
+ if (track->contents.data.icon) {
+ /* Write the icon if any */
+ success = xmlTextWriterWriteElement (project, (xmlChar *) "icon", (xmlChar *) track->contents.data.icon);
+ if (success < 0)
+ return FALSE;
+ }
+
for (grafts = track->contents.data.grafts; grafts; grafts = grafts->next) {
graft = grafts->data;
@@ -2384,6 +2534,7 @@ brasero_project_save_project_real (BraseroProject *project,
return FALSE;
bzero (&track, sizeof (track));
+
result = brasero_disc_get_track (project->priv->current, &track);
if (result == BRASERO_DISC_ERROR_EMPTY_SELECTION) {
if (BRASERO_IS_AUDIO_DISC (project->priv->current))
@@ -2636,6 +2787,8 @@ brasero_project_save_session (BraseroProject *project,
bzero (&track, sizeof (track));
if (brasero_disc_get_track (project->priv->current, &track) == BRASERO_DISC_OK) {
+ /* NOTE: is this right? because brasero could not shut itself
+ * down if an error occurs. */
if (!brasero_project_save_project_xml (project,
uri,
&track,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]