]> git.sesse.net Git - vlc/blob - src/control/tree.c
control/tree.c: Notify subtree/addition removal.
[vlc] / 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     libvlc_event_t event;
44
45     /* Construct the event */
46     event.type = libvlc_TreeSubtreeAdded;
47     event.u.tree_subtree_added.subtree = p_subtree;
48     event.u.tree_subtree_added.index = index;
49
50     /* Send the event */
51     libvlc_event_send( p_tree->p_event_manager, &event );
52 }
53
54 /**************************************************************************
55  *       notify_subtree_deletion (private)
56  *
57  * Do the appropriate action when a subtree is deleted.
58  **************************************************************************/
59 static void
60 notify_subtree_deletion( libvlc_tree_t * p_tree,
61                          libvlc_tree_t * p_subtree,
62                          int index )
63 {
64     libvlc_event_t event;
65
66     /* Construct the event */
67     event.type = libvlc_TreeSubtreeDeleted;
68     event.u.tree_subtree_deleted.subtree = p_subtree;
69     event.u.tree_subtree_deleted.index = index;
70
71     /* Send the event */
72     libvlc_event_send( p_tree->p_event_manager, &event );
73 }
74
75 #ifdef NOT_USED
76 /**************************************************************************
77  *       notify_tree_item_value_changed (private)
78  *
79  * Do the appropriate action when a tree's item changes.
80  **************************************************************************/
81 static void
82 notify_tree_item_value_changed( libvlc_tree_t * p_tree,
83                                 libvlc_tree_t * p_subtree,
84                                 int index )
85 {
86     libvlc_event_t event;
87
88     /* Construct the event */
89     event.type = libvlc_TreeItemValueChanged;
90     event.u.tree_item_value_changed.new_value = p_tree->p_item;
91
92     /* Send the event */
93     libvlc_event_send( p_tree->p_event_manager, &event );
94 }
95 #endif
96
97 /**************************************************************************
98  *       new (Private)
99  **************************************************************************/
100 static libvlc_tree_t *
101 libvlc_tree_new( libvlc_retain_function item_retain,
102                  libvlc_retain_function item_release,
103                  void * item,
104                  libvlc_exception_t * p_e )
105 {
106         (void)p_e;
107     libvlc_tree_t * p_tree;
108
109         p_tree = malloc(sizeof(libvlc_tree_t));
110
111         if( !p_tree )
112                 return NULL;
113
114     p_tree->i_refcount = 1;
115     p_tree->p_item = item;
116     ARRAY_INIT( p_tree->subtrees );
117     
118     p_tree->p_event_manager = libvlc_event_manager_new( p_tree, NULL, p_e );
119     libvlc_event_manager_register_event_type( p_tree->p_event_manager,
120             libvlc_TreeSubtreeAdded, p_e );
121     libvlc_event_manager_register_event_type( p_tree->p_event_manager,
122             libvlc_TreeSubtreeDeleted, p_e );
123     libvlc_event_manager_register_event_type( p_tree->p_event_manager,
124             libvlc_TreeItemValueChanged, p_e );
125
126         return p_tree;
127 }
128
129 /**************************************************************************
130  *        item (Private)
131  **************************************************************************/
132 static void *
133 libvlc_tree_item( libvlc_tree_t * p_tree,
134                   libvlc_exception_t * p_e )
135 {
136     if( p_tree->pf_item_retain ) p_tree->pf_item_retain( p_tree->p_item );
137     return p_tree->p_item;
138 }
139
140
141 /*
142  * Public libvlc functions
143  */
144
145
146 /**************************************************************************
147  *       new_with_media_list (Public)
148  **************************************************************************/
149 libvlc_tree_t *
150 libvlc_tree_new_with_media_list_as_item( libvlc_media_list_t * p_mlist,
151                                          libvlc_exception_t * p_e )
152 {
153         (void)p_e;
154     libvlc_tree_t * p_tree = libvlc_tree_new(
155         (libvlc_retain_function)libvlc_media_list_retain,
156         (libvlc_release_function)libvlc_media_list_release,
157         p_mlist,
158         p_e );
159     
160         return p_tree;
161 }
162
163 /**************************************************************************
164  *       new_with_string (Public)
165  **************************************************************************/
166 libvlc_tree_t *
167 libvlc_tree_new_with_string_as_item( const char * psz,
168                                      libvlc_exception_t * p_e )
169 {
170         (void)p_e;
171     libvlc_tree_t * p_tree = libvlc_tree_new( NULL,
172                                     (libvlc_release_function)free,
173                                     psz ? strdup( psz ): NULL,
174                                     p_e );
175     
176         return p_tree;
177 }
178
179 /**************************************************************************
180  *       release (Public)
181  **************************************************************************/
182 void libvlc_tree_release( libvlc_tree_t * p_tree )
183 {
184     libvlc_tree_t * p_subtree;
185
186     p_tree->i_refcount--;
187
188     if( p_tree->i_refcount > 0 )
189         return;
190
191     if( p_tree->pf_item_release && p_tree->p_item )
192         p_tree->pf_item_release( p_tree->p_item );
193
194     FOREACH_ARRAY( p_subtree, p_tree->subtrees )
195         libvlc_tree_release( p_subtree );
196     FOREACH_END()
197
198         free( p_tree );
199 }
200
201 /**************************************************************************
202  *       retain (Public)
203  **************************************************************************/
204 void libvlc_tree_retain( libvlc_tree_t * p_tree )
205 {
206         p_tree->i_refcount++;
207 }
208
209 /**************************************************************************
210  *        item_as_string (Public)
211  **************************************************************************/
212 char *
213 libvlc_tree_item_as_string( libvlc_tree_t * p_tree,
214                             libvlc_exception_t * p_e )
215 {
216         (void)p_e;
217     return p_tree->p_item ? strdup( p_tree->p_item ) : NULL;
218 }
219
220 /**************************************************************************
221  *        item_as_media_list (Public)
222  **************************************************************************/
223 libvlc_media_list_t *
224 libvlc_tree_item_as_media_list( libvlc_tree_t * p_tree,
225                                 libvlc_exception_t * p_e )
226 {
227     /* Automatically retained */
228     return libvlc_tree_item( p_tree, p_e );
229 }
230
231 /**************************************************************************
232  *        count (Public)
233  **************************************************************************/
234 int
235 libvlc_tree_subtree_count( libvlc_tree_t * p_tree, libvlc_exception_t * p_e )
236 {
237         (void)p_e;
238     return p_tree->subtrees.i_size;
239 }
240
241 /**************************************************************************
242  *        subtree_at_index (Public)
243  *
244  * Note: The subtree won't be retained
245  **************************************************************************/
246 libvlc_tree_t *
247 libvlc_tree_subtree_at_index( libvlc_tree_t * p_tree,
248                               int index,
249                               libvlc_exception_t * p_e )
250 {
251         (void)p_e;
252     libvlc_tree_t * p_subtree;
253
254     p_subtree = ARRAY_VAL( p_tree->subtrees, index );
255     libvlc_tree_retain( p_subtree );
256
257     return p_subtree;
258 }
259
260 /**************************************************************************
261  *        insert_subtree_at_index (Public)
262  *
263  * Note: The subtree won't be retained
264  **************************************************************************/
265 void
266 libvlc_tree_insert_subtree_at_index( libvlc_tree_t * p_tree,
267                                      libvlc_tree_t * p_subtree,
268                                      int index,
269                                      libvlc_exception_t * p_e )
270 {
271     (void)p_e;
272     libvlc_tree_retain( p_tree );
273
274     ARRAY_INSERT( p_tree->subtrees, p_subtree, index);
275     notify_subtree_addition( p_tree, p_subtree, index );
276 }
277
278 /**************************************************************************
279  *        remove_subtree_at_index (Public)
280  **************************************************************************/
281 void
282 libvlc_tree_remove_subtree_at_index( libvlc_tree_t * p_tree,
283                                      int index,
284                                      libvlc_exception_t * p_e )
285 {
286         (void)p_e;
287     libvlc_tree_t * p_subtree;
288
289     p_subtree = ARRAY_VAL( p_tree->subtrees, index );
290
291     ARRAY_REMOVE( p_tree->subtrees, index );
292     notify_subtree_deletion( p_tree, p_subtree, index );
293
294     libvlc_tree_release( p_subtree );
295 }