control/tree.c: Add a new structure to work with tree.
[vlc.git] / src / control / tree.c
1 /*****************************************************************************
2  * media_list.c: libvlc tree functions
3  *****************************************************************************
4  * Copyright (C) 2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #include "libvlc_internal.h"
25 #include <vlc/libvlc.h>
26 #include <assert.h>
27 #include "vlc_arrays.h"
28
29 /*
30  * Private libvlc functions
31  */
32
33 /**************************************************************************
34  *       notify_subtree_addition (private)
35  *
36  * Do the appropriate action when a subtree is added.
37  **************************************************************************/
38 static void
39 notify_subtree_addition( libvlc_tree_t * p_tree,
40                          libvlc_tree_t * p_subtree,
41                          int index )
42 {
43
44 }
45
46 /**************************************************************************
47  *       notify_subtree_deletion (private)
48  *
49  * Do the appropriate action when a subtree is deleted.
50  **************************************************************************/
51 static void
52 notify_subtree_deletion( libvlc_tree_t * p_tree,
53                          libvlc_tree_t * p_subtree,
54                          int index )
55 {
56
57 }
58
59 /**************************************************************************
60  *       new (Private)
61  **************************************************************************/
62 static libvlc_tree_t *
63 libvlc_tree_new( libvlc_retain_function item_retain,
64                  libvlc_retain_function item_release,
65                  void * item,
66                  libvlc_exception_t * p_e )
67 {
68         (void)p_e;
69     libvlc_tree_t * p_tree;
70
71         p_tree = malloc(sizeof(libvlc_tree_t));
72
73         if( !p_tree )
74                 return NULL;
75
76     p_tree->i_refcount = 1;
77     p_tree->p_item = item;
78     ARRAY_INIT( p_tree->subtrees );
79         return p_tree;
80 }
81
82 /**************************************************************************
83  *        item (Private)
84  **************************************************************************/
85 static void *
86 libvlc_tree_item( libvlc_tree_t * p_tree,
87                   libvlc_exception_t * p_e )
88 {
89     if( p_tree->pf_item_retain ) p_tree->pf_item_retain( p_tree->p_item );
90     return p_tree->p_item;
91 }
92
93
94 /*
95  * Public libvlc functions
96  */
97
98
99 /**************************************************************************
100  *       new_with_media_list (Public)
101  **************************************************************************/
102 libvlc_tree_t *
103 libvlc_tree_new_with_media_list_as_item( libvlc_media_list_t * p_mlist,
104                                          libvlc_exception_t * p_e )
105 {
106         (void)p_e;
107     libvlc_tree_t * p_tree = libvlc_tree_new(
108         (libvlc_retain_function)libvlc_media_list_retain,
109         (libvlc_release_function)libvlc_media_list_release,
110         p_mlist,
111         p_e );
112     
113         return p_tree;
114 }
115
116 /**************************************************************************
117  *       new_with_string (Public)
118  **************************************************************************/
119 libvlc_tree_t *
120 libvlc_tree_new_with_string_as_item( const char * psz,
121                                      libvlc_exception_t * p_e )
122 {
123         (void)p_e;
124     libvlc_tree_t * p_tree = libvlc_tree_new( NULL,
125                                     (libvlc_release_function)free,
126                                     psz ? strdup( psz ): NULL,
127                                     p_e );
128     
129         return p_tree;
130 }
131
132 /**************************************************************************
133  *       release (Public)
134  **************************************************************************/
135 void libvlc_tree_release( libvlc_tree_t * p_tree )
136 {
137     libvlc_tree_t * p_subtree;
138
139     p_tree->i_refcount--;
140
141     if( p_tree->i_refcount > 0 )
142         return;
143
144     if( p_tree->pf_item_release && p_tree->p_item )
145         p_tree->pf_item_release( p_tree->p_item );
146
147     FOREACH_ARRAY( p_subtree, p_tree->subtrees )
148         libvlc_tree_release( p_subtree );
149     FOREACH_END()
150
151         free( p_tree );
152 }
153
154 /**************************************************************************
155  *       retain (Public)
156  **************************************************************************/
157 void libvlc_tree_retain( libvlc_tree_t * p_tree )
158 {
159         p_tree->i_refcount++;
160 }
161
162 /**************************************************************************
163  *        item_as_string (Public)
164  **************************************************************************/
165 char *
166 libvlc_tree_item_as_string( libvlc_tree_t * p_tree,
167                             libvlc_exception_t * p_e )
168 {
169         (void)p_e;
170     return p_tree->p_item ? strdup( p_tree->p_item ) : NULL;
171 }
172
173 /**************************************************************************
174  *        item_as_media_list (Public)
175  **************************************************************************/
176 libvlc_media_list_t *
177 libvlc_tree_item_as_media_list( libvlc_tree_t * p_tree,
178                                 libvlc_exception_t * p_e )
179 {
180     /* Automatically retained */
181     return libvlc_tree_item( p_tree, p_e );
182 }
183
184 /**************************************************************************
185  *        count (Public)
186  **************************************************************************/
187 int
188 libvlc_tree_subtree_count( libvlc_tree_t * p_tree, libvlc_exception_t * p_e )
189 {
190         (void)p_e;
191     return p_tree->subtrees.i_size;
192 }
193
194 /**************************************************************************
195  *        subtree_at_index (Public)
196  *
197  * Note: The subtree won't be retained
198  **************************************************************************/
199 libvlc_tree_t *
200 libvlc_tree_subtree_at_index( libvlc_tree_t * p_tree,
201                               int index,
202                               libvlc_exception_t * p_e )
203 {
204         (void)p_e;
205     libvlc_tree_t * p_subtree;
206
207     p_subtree = ARRAY_VAL( p_tree->subtrees, index );
208     libvlc_tree_retain( p_subtree );
209
210     return p_subtree;
211 }
212
213 /**************************************************************************
214  *        insert_subtree_at_index (Public)
215  *
216  * Note: The subtree won't be retained
217  **************************************************************************/
218 void
219 libvlc_tree_insert_subtree_at_index( libvlc_tree_t * p_tree,
220                                      libvlc_tree_t * p_subtree,
221                                      int index,
222                                      libvlc_exception_t * p_e )
223 {
224     (void)p_e;
225     libvlc_tree_retain( p_tree );
226
227     ARRAY_INSERT( p_tree->subtrees, p_subtree, index);
228     notify_subtree_addition( p_tree, p_subtree, index );
229 }
230
231 /**************************************************************************
232  *        remove_subtree_at_index (Public)
233  **************************************************************************/
234 void
235 libvlc_tree_remove_subtree_at_index( libvlc_tree_t * p_tree,
236                                      int index,
237                                      libvlc_exception_t * p_e )
238 {
239         (void)p_e;
240     libvlc_tree_t * p_subtree;
241
242     p_subtree = ARRAY_VAL( p_tree->subtrees, index );
243
244     ARRAY_REMOVE( p_tree->subtrees, index );
245     notify_subtree_deletion( p_tree, p_subtree, index );
246
247     libvlc_tree_release( p_subtree );
248 }