1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ 2 /* 3 * Libbrasero-burn 4 * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr> 5 * 6 * Libbrasero-burn is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * The Libbrasero-burn authors hereby grant permission for non-GPL compatible 12 * GStreamer plugins to be used and distributed together with GStreamer 13 * and Libbrasero-burn. This permission is above and beyond the permissions granted 14 * by the GPL license by which Libbrasero-burn is covered. If you modify this code 15 * you may extend this exception to your version of the code, but you are not 16 * obligated to do so. If you do not wish to do so, delete this exception 17 * statement from your version. 18 * 19 * Libbrasero-burn is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU Library General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, write to: 26 * The Free Software Foundation, Inc., 27 * 51 Franklin Street, Fifth Floor 28 * Boston, MA 02110-1301, USA. 29 */ 30 31 #ifndef _BRASERO_FILE_NODE_H 32 #define _BRASERO_FILE_NODE_H 33 34 #include <glib.h> 35 36 #include <gio/gio.h> 37 38 #include "burn-volume.h" 39 40 G_BEGIN_DECLS 41 42 typedef struct _BraseroFileNode BraseroFileNode; 43 44 struct _BraseroURINode { 45 /* List of all nodes that share the same URI */ 46 GSList *nodes; 47 48 /* NOTE: uris are always escaped */ 49 gchar *uri; 50 }; 51 typedef struct _BraseroURINode BraseroURINode; 52 53 struct _BraseroGraft { 54 /* The name on CD (which could be different) from the original */ 55 gchar *name; 56 BraseroURINode *node; 57 }; 58 typedef struct _BraseroGraft BraseroGraft; 59 60 struct _BraseroImport { 61 gchar *name; 62 BraseroFileNode *replaced; 63 }; 64 typedef struct _BraseroImport BraseroImport; 65 66 /** 67 * NOTE: The root object keeps some statistics about its tree like 68 * - number of children (files+directories) 69 * - number of deep directories 70 * - number of files over 2 GiB 71 */ 72 73 struct _BraseroFileTreeStats { 74 guint children; 75 guint num_dir; 76 guint num_deep; 77 guint num_2GiB; 78 guint num_sym; 79 }; 80 typedef struct _BraseroFileTreeStats BraseroFileTreeStats; 81 82 struct _BraseroFileNode { 83 BraseroFileNode *parent; 84 BraseroFileNode *next; 85 86 /** 87 * This union can be: 88 * - the name of the file on file system and on disc 89 * - a pointer to the graft node for all grafted nodes 90 * - a pointer to saved imported session files 91 * Check is_grafted to determine. 92 */ 93 94 /* NOTE: names are unescaped (for display). */ 95 96 union { 97 BraseroImport *import; 98 BraseroGraft *graft; 99 gchar *name; 100 } union1; 101 102 union { 103 gchar *mime; 104 BraseroFileNode *children; 105 } union2; 106 107 /* NOTE: overflow for sectors will probably not be hit 108 * before a few years given that we store the size in 109 * sectors of 2048. For the time being DVD are usually 110 * 4.3 GiB. To overflow the following member (provided 111 * we are on a 32 architecture) they would have to be 112 * over 8192 GiB. I think it's reasonable to think we 113 * have time. And even then, by this time most of the 114 * computers will have switched to 64 architecture (in 115 * 2099) and I'll be dead anyway as well as optical 116 * discs. */ 117 union { 118 guint sectors; 119 120 /* stores the address of the children records in image */ 121 guint imported_address; 122 BraseroFileTreeStats *stats; 123 } union3; 124 125 /* type of node */ 126 guint is_root:1; 127 guint is_fake:1; 128 guint is_file:1; 129 guint is_symlink:1; 130 guint is_imported:1; 131 guint is_monitored:1; 132 133 /* status of union1 */ 134 guint is_grafted:1; 135 guint has_import:1; 136 137 /* VFS status of node */ 138 guint is_loading:1; 139 guint is_reloading:1; 140 guint is_exploring:1; 141 142 /* that's for some special nodes (usually counted in statistics) */ 143 guint is_2GiB:1; 144 guint is_deep:1; 145 146 /* This is for nodes created at project load time. This means 147 * that they can be replaced if a real directory is under the 148 * parent with the same name*/ 149 guint is_tmp_parent:1; 150 151 /* Used to determine if is should be shown */ 152 guint is_hidden:1; 153 154 /* Used by the model */ 155 /* This is a workaround for a warning in gailtreeview.c line 2946 where 156 * gail uses the GtkTreePath and not a copy which if the node inserted 157 * declares to have children and is not expanded leads to the path being 158 * upped and therefore wrong. */ 159 guint is_inserting:1; 160 161 guint is_expanded:1; /* Used to choose the icon for folders */ 162 163 /* this is a ref count a max of 255 should be enough */ 164 guint is_visible:7; 165 }; 166 167 /** Returns a const gchar* (it shouldn't be freed). */ 168 #define BRASERO_FILE_NODE_NAME(MACRO_node) \ 169 ((MACRO_node)->is_grafted?(MACRO_node)->union1.graft->name: \ 170 (MACRO_node)->has_import?(MACRO_node)->union1.import->name: \ 171 (MACRO_node)->union1.name) 172 173 #define BRASERO_FILE_NODE_GRAFT(MACRO_node) \ 174 ((MACRO_node)->is_grafted?(MACRO_node)->union1.graft:NULL) 175 176 #define BRASERO_FILE_NODE_IMPORT(MACRO_node) \ 177 ((MACRO_node)->has_import?(MACRO_node)->union1.import:NULL) 178 179 #define BRASERO_FILE_NODE_CHILDREN(MACRO_node) \ 180 ((MACRO_node)->is_file?NULL:(MACRO_node)->union2.children) 181 182 #define BRASERO_FILE_NODE_MIME(MACRO_node) \ 183 ((MACRO_node)->is_file?(MACRO_node)->union2.mime:"x-directory/normal") 184 185 #define BRASERO_FILE_NODE_SECTORS(MACRO_node) \ 186 ((guint64) ((MACRO_node)->is_root?0:(MACRO_node)->union3.sectors)) 187 188 #define BRASERO_FILE_NODE_STATS(MACRO_root) \ 189 ((MACRO_root)->is_root?(MACRO_root)->union3.stats:NULL) 190 191 #define BRASERO_FILE_NODE_VIRTUAL(MACRO_node) \ 192 ((MACRO_node)->is_hidden && (MACRO_node)->is_fake) 193 194 #define BRASERO_FILE_NODE_IMPORTED_ADDRESS(MACRO_node) \ 195 ((MACRO_node) && (MACRO_node)->is_imported && (MACRO_node)->is_fake?(MACRO_node)->union3.imported_address:-1) 196 197 #define BRASERO_FILE_2G_LIMIT 1048576 198 199 BraseroFileNode * 200 brasero_file_node_root_new (void); 201 202 BraseroFileNode * 203 brasero_file_node_get_root (BraseroFileNode *node, 204 guint *depth); 205 206 BraseroFileTreeStats * 207 brasero_file_node_get_tree_stats (BraseroFileNode *node, 208 guint *depth); 209 210 BraseroFileNode * 211 brasero_file_node_nth_child (BraseroFileNode *parent, 212 guint nth); 213 214 guint 215 brasero_file_node_get_depth (BraseroFileNode *node); 216 217 guint 218 brasero_file_node_get_pos_as_child (BraseroFileNode *node); 219 220 guint 221 brasero_file_node_get_n_children (const BraseroFileNode *node); 222 223 guint 224 brasero_file_node_get_pos_as_child (BraseroFileNode *node); 225 226 gboolean 227 brasero_file_node_is_ancestor (BraseroFileNode *parent, 228 BraseroFileNode *node); 229 BraseroFileNode * 230 brasero_file_node_get_from_path (BraseroFileNode *root, 231 const gchar *path); 232 BraseroFileNode * 233 brasero_file_node_check_name_existence (BraseroFileNode *parent, 234 const gchar *name); 235 BraseroFileNode * 236 brasero_file_node_check_name_existence_case (BraseroFileNode *parent, 237 const gchar *name); 238 BraseroFileNode * 239 brasero_file_node_check_imported_sibling (BraseroFileNode *node); 240 241 /** 242 * Nodes are strictly organised so there to be sort function all the time 243 */ 244 245 void 246 brasero_file_node_add (BraseroFileNode *parent, 247 BraseroFileNode *child, 248 GCompareFunc sort_func); 249 250 BraseroFileNode * 251 brasero_file_node_new (const gchar *name); 252 253 BraseroFileNode * 254 brasero_file_node_new_virtual (const gchar *name); 255 256 BraseroFileNode * 257 brasero_file_node_new_loading (const gchar *name); 258 259 BraseroFileNode * 260 brasero_file_node_new_empty_folder (const gchar *name); 261 262 BraseroFileNode * 263 brasero_file_node_new_imported_session_file (GFileInfo *info); 264 265 /** 266 * If there are any change in the order it cannot be handled in these functions 267 * A call to resort function must be made. 268 */ 269 void 270 brasero_file_node_rename (BraseroFileNode *node, 271 const gchar *name); 272 void 273 brasero_file_node_set_from_info (BraseroFileNode *node, 274 BraseroFileTreeStats *stats, 275 GFileInfo *info); 276 277 void 278 brasero_file_node_graft (BraseroFileNode *file_node, 279 BraseroURINode *uri_node); 280 void 281 brasero_file_node_ungraft (BraseroFileNode *node); 282 283 void 284 brasero_file_node_move_from (BraseroFileNode *node, 285 BraseroFileTreeStats *stats); 286 void 287 brasero_file_node_move_to (BraseroFileNode *node, 288 BraseroFileNode *parent, 289 GCompareFunc sort_func); 290 291 void 292 brasero_file_node_unlink (BraseroFileNode *node); 293 294 void 295 brasero_file_node_destroy (BraseroFileNode *node, 296 BraseroFileTreeStats *stats); 297 298 void 299 brasero_file_node_save_imported (BraseroFileNode *node, 300 BraseroFileTreeStats *stats, 301 BraseroFileNode *parent, 302 GCompareFunc sort_func); 303 304 gint 305 brasero_file_node_sort_name_cb (gconstpointer obj_a, gconstpointer obj_b); 306 gint 307 brasero_file_node_sort_size_cb (gconstpointer obj_a, gconstpointer obj_b); 308 gint 309 brasero_file_node_sort_mime_cb (gconstpointer obj_a, gconstpointer obj_b); 310 gint 311 brasero_file_node_sort_default_cb (gconstpointer obj_a, gconstpointer obj_b); 312 gint * 313 brasero_file_node_sort_children (BraseroFileNode *parent, 314 GCompareFunc sort_func); 315 gint * 316 brasero_file_node_need_resort (BraseroFileNode *node, 317 GCompareFunc sort_func); 318 gint * 319 brasero_file_node_reverse_children (BraseroFileNode *parent); 320 321 322 G_END_DECLS 323 324 #endif /* _BRASERO_FILE_NODE_H */ 325