]> git.sesse.net Git - vlc/blob - modules/gui/macosx/playlistinfo.m
* OSX lowlevel work
[vlc] / modules / gui / macosx / playlistinfo.m
1 /*****************************************************************************
2  r playlistinfo.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2002-2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Benjamin Pracht <bigben at videolan dot 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27
28 #include "intf.h"
29 #include "playlistinfo.h"
30 #include "playlist.h"
31
32 /*****************************************************************************
33  * VLCPlaylistInfo Implementation
34  *****************************************************************************/
35
36 @implementation VLCInfo
37
38 - (id)init
39 {
40     self = [super init];
41
42     if( self != nil )
43     {
44         i_item = -1;
45         o_selected = NULL;
46     }
47     return( self );
48 }
49
50 - (void)dealloc
51 {
52     [o_selected release];
53     [super dealloc];
54 }
55
56 - (void)awakeFromNib
57 {
58     [o_info_window setExcludedFromWindowsMenu: TRUE];
59
60     [o_info_window setTitle: _NS("Properties")];
61     [o_uri_lbl setStringValue: _NS("URI")];
62     [o_title_lbl setStringValue: _NS("Title")];
63     [o_author_lbl setStringValue: _NS("Author")];
64     [o_btn_ok setTitle: _NS("OK")];
65     [o_btn_cancel setTitle: _NS("Cancel")];
66     [o_btn_delete_group setTitle: _NS("Delete Group")];
67     [o_btn_add_group setTitle: _NS("Add Group")];
68     [o_group_lbl setStringValue: _NS("Group")];
69 }
70
71 - (IBAction)togglePlaylistInfoPanel:(id)sender
72 {
73     if( [o_info_window isVisible] )
74     {
75         [o_info_window orderOut: sender];
76     }
77     else
78     {
79         i_item = [[[VLCMain sharedInstance] getPlaylist] selectedPlaylistItem];
80         o_selected = [[[VLCMain sharedInstance] getPlaylist] selectedPlaylistItemsList];
81         [o_selected retain];
82         [self initPanel:sender];
83     }
84 }
85
86 - (IBAction)toggleInfoPanel:(id)sender
87 {
88     if( [o_info_window isVisible] )
89     {
90         [o_info_window orderOut: sender];
91     }
92     else
93     {
94         intf_thread_t * p_intf = VLCIntf;
95         playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
96                                           FIND_ANYWHERE );
97
98         if (p_playlist)
99         {
100             i_item = p_playlist->i_index;
101             o_selected = [NSMutableArray arrayWithObject:
102                             [NSNumber numberWithInt:i_item]];
103             [o_selected retain];
104             vlc_object_release(p_playlist);
105         }
106         [self initPanel:sender];
107     }
108 }
109
110 - (void)initPanel:(id)sender
111 {
112     intf_thread_t * p_intf = VLCIntf;
113     playlist_t * p_playlist;
114
115     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
116                                           FIND_ANYWHERE );
117
118
119     if( p_playlist )
120     {
121         char *psz_temp;
122
123         /*fill uri / title / author info */
124         [o_uri_txt setStringValue:
125             ([NSString stringWithUTF8String:p_playlist->
126                pp_items[i_item]->input.psz_uri] == nil ) ?
127             [NSString stringWithCString:p_playlist->
128                 pp_items[i_item]->input.psz_uri] :
129             [NSString stringWithUTF8String:p_playlist->
130                 pp_items[i_item]->input.psz_uri]];
131
132         [o_title_txt setStringValue:
133             ([NSString stringWithUTF8String:p_playlist->
134                 pp_items[i_item]->input.psz_name] == nil ) ?
135             [NSString stringWithCString:p_playlist->
136                 pp_items[i_item]->input.psz_name] :
137             [NSString stringWithUTF8String:p_playlist->
138                 pp_items[i_item]->input.psz_name]];
139
140         psz_temp = playlist_GetInfo( p_playlist, i_item ,_("General"),_("Author") );
141         [o_author_txt setStringValue: [NSString stringWithUTF8String: psz_temp]];
142         free( psz_temp );
143
144         [[VLCInfoTreeItem rootItem] refresh];
145         [o_outline_view reloadData];
146
147         [self createComboBox];
148         [self handleGroup:self];
149
150         vlc_object_release( p_playlist );
151     }
152     [o_info_window makeKeyAndOrderFront: sender];
153 }
154
155 - (IBAction)infoCancel:(id)sender
156 {
157     [o_info_window orderOut: self];
158 }
159
160
161 - (IBAction)infoOk:(id)sender
162 {
163     int i,i_row,c;
164     intf_thread_t * p_intf = VLCIntf;
165     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
166                                           FIND_ANYWHERE );
167     vlc_value_t val;
168     NSNumber * o_number;
169
170
171     if (p_playlist)
172     {
173         vlc_mutex_lock(&p_playlist->pp_items[i_item]->input.lock);
174
175         p_playlist->pp_items[i_item]->input.psz_uri =
176             strdup([[o_uri_txt stringValue] cString]);
177         p_playlist->pp_items[i_item]->input.psz_name =
178             strdup([[o_title_txt stringValue] cString]);
179         playlist_ItemAddInfo(p_playlist->pp_items[i_item],_("General"),_("Author"), [[o_author_txt stringValue] cString]);
180
181         c = (int)[o_selected count];
182
183         if ([[o_group_cbx stringValue] isEqual:
184                     [o_group_cbx objectValueOfSelectedItem]])
185         {
186             for (i = 0 ; i < c ; i++)
187             {
188                 o_number = [o_selected lastObject];
189                 i_row = [o_number intValue];
190                 p_playlist->pp_items[i_row]->i_group = p_playlist->
191                     pp_groups[[o_group_cbx indexOfSelectedItem]]->i_id;
192                 [o_selected removeObject: o_number];
193             }
194         }
195         else
196         {
197             playlist_group_t * p_group = playlist_CreateGroup( p_playlist,
198                 strdup([[o_group_cbx stringValue] cString]));
199             if (p_group)
200             {
201                 for (i = 0 ; i < c ; i++)
202                 {
203                     o_number = [o_selected lastObject];
204                     i_row = [o_number intValue];
205                     p_playlist->pp_items[i_row]->i_group = p_group->i_id;
206                     [o_selected removeObject: o_number];
207                 }
208             }
209         }
210
211
212         vlc_mutex_unlock(&p_playlist->pp_items[i_item]->input.lock);
213         val.b_bool = VLC_TRUE;
214         var_Set( p_playlist,"intf-change",val );
215         vlc_object_release ( p_playlist );
216     }
217     [o_info_window orderOut: self];
218 }
219
220 - (IBAction)handleGroup:(id)sender
221 {
222     intf_thread_t * p_intf = VLCIntf;
223     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
224                                           FIND_ANYWHERE );
225
226     if (p_playlist)
227     {
228         if ([[o_group_cbx stringValue] isEqual:
229                     [o_group_cbx objectValueOfSelectedItem]])
230         {
231             [o_group_color setBackgroundColor:[[[VLCMain sharedInstance] getPlaylist]
232                 getColor: p_playlist->pp_groups[
233                 [o_group_cbx indexOfSelectedItem]]->i_id]];
234         }
235         else
236         {
237             [o_group_color setBackgroundColor:[[[VLCMain sharedInstance] getPlaylist]
238                 getColor:p_playlist->pp_groups[
239                 [o_group_cbx numberOfItems] - 1]->i_id + 1]];
240         }
241     vlc_object_release(p_playlist);
242     }
243 }
244
245 - (IBAction)deleteOutlineGroup:(id)sender
246 {
247     intf_thread_t * p_intf = VLCIntf;
248     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
249                                           FIND_ANYWHERE );
250
251     if(p_playlist)
252     {
253         if ([[o_group_cbx stringValue] isEqual:
254                     [o_group_cbx objectValueOfSelectedItem]])
255         {
256             [[[VLCMain sharedInstance] getPlaylist] deleteGroup:p_playlist->pp_groups[
257                     [o_group_cbx indexOfSelectedItem]]->i_id];
258             [self createComboBox];
259             [self handleGroup:self];
260             [o_group_cbx reloadData];
261         }
262         else
263         {
264             msg_Warn(p_playlist,"Group doesn't exist, cannot delete");
265         }
266     vlc_object_release(p_playlist);
267     }
268 }
269
270 - (IBAction)createOutlineGroup:(id)sender;
271 {
272     intf_thread_t * p_intf = VLCIntf;
273     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
274                                           FIND_ANYWHERE );
275     if(p_playlist)
276     {
277         playlist_CreateGroup( p_playlist,
278                     strdup([[o_group_cbx stringValue] cString]));
279         [self createComboBox];
280         [o_group_cbx reloadData];
281         [[[VLCMain sharedInstance] getPlaylist] playlistUpdated];
282         vlc_object_release(p_playlist);
283     }
284 }
285
286 -(void)createComboBox
287 {
288     intf_thread_t * p_intf = VLCIntf;
289     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
290                                           FIND_ANYWHERE );
291     int i;
292
293     [o_group_cbx removeAllItems];
294
295     if (p_playlist)
296     {
297         for (i = 0; i < p_playlist->i_groups ; i++)
298         {
299             [o_group_cbx addItemWithObjectValue:
300                 [NSString stringWithUTF8String:
301                 p_playlist->pp_groups[i]->psz_name]];
302             if (p_playlist->pp_items[i_item]->i_group == p_playlist
303                 ->pp_groups[i]->i_id)
304             {
305                 [o_group_cbx selectItemAtIndex:i];
306             }
307         }
308     vlc_object_release(p_playlist);
309     }
310 }
311
312 - (int)getItem
313 {
314     return i_item;
315 }
316
317 @end
318
319 @implementation VLCInfo (NSMenuValidation)
320
321 - (BOOL)validateMenuItem:(NSMenuItem *)o_mi
322 {
323     BOOL bEnabled = TRUE;
324
325     intf_thread_t * p_intf = VLCIntf;
326     input_thread_t * p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
327                                                        FIND_ANYWHERE );
328
329     if( [[o_mi title] isEqualToString: _NS("Info")] )
330     {
331         if( p_input == NULL )
332         {
333             bEnabled = FALSE;
334         }
335     }
336     if( p_input ) vlc_object_release( p_input );
337
338     return( bEnabled );
339 }
340
341 @end
342
343 @implementation VLCInfo (NSTableDataSource)
344
345 - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
346 {
347     return (item == nil) ? [[VLCInfoTreeItem rootItem] numberOfChildren] : [item numberOfChildren];
348 }
349
350 - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
351     return ([item numberOfChildren] > 0);
352 }
353
354 - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
355 {
356     return (item == nil) ? [[VLCInfoTreeItem rootItem] childAtIndex:index] : [item childAtIndex:index];
357 }
358
359 - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
360 {
361     if ([[tableColumn identifier] isEqualToString:@"0"])
362     {
363         return (item == nil) ? @"" : (id)[item getName];
364     }
365     else
366     {
367         return (item == nil) ? @"" : (id)[item getValue];
368     }
369 }
370
371
372 @end
373
374 @implementation VLCInfoTreeItem
375
376 static VLCInfoTreeItem *o_root_item = nil;
377
378 #define IsALeafNode ((id)-1)
379
380 - (id)initWithName: (NSString *)o_item_name value: (NSString *)o_item_value ID: (int)i_id parent:(VLCInfoTreeItem *)o_parent_item
381 {
382     self = [super init];
383
384     if( self != nil )
385     {
386         o_name = [o_item_name copy];
387         o_value = [o_item_value copy];
388         i_object_id = i_id;
389         o_parent = o_parent_item;
390         i_item = [[[VLCMain sharedInstance] getInfo] getItem];
391     }
392     return( self );
393 }
394
395 + (VLCInfoTreeItem *)rootItem {
396     if (o_root_item == nil) o_root_item = [[VLCInfoTreeItem alloc] initWithName:@"main" value: @"" ID: 0 parent:nil];
397     return o_root_item;
398 }
399
400 - (void)dealloc
401 {
402     if (o_children != IsALeafNode) [o_children release];
403     [o_name release];
404     [super dealloc];
405 }
406
407 /* Creates and returns the array of children
408  * Loads children incrementally */
409 - (NSArray *)children
410 {
411     if (o_children == NULL)
412     {
413         intf_thread_t * p_intf = VLCIntf;
414         playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
415                                           FIND_ANYWHERE );
416         int i;
417
418         if (p_playlist)
419         {
420             if (i_item > -1)
421             {
422                 if (self == o_root_item)
423                 {
424                     o_children = [[NSMutableArray alloc] initWithCapacity:p_playlist->pp_items[i_item]->input.i_categories];
425                     for (i = 0 ; i<p_playlist->pp_items[i_item]->input.i_categories ; i++)
426                     {
427                         [o_children addObject:[[VLCInfoTreeItem alloc]
428                             initWithName: [NSString stringWithUTF8String:
429                                 p_playlist->pp_items[i_item]->input.
430                                 pp_categories[i]->psz_name]
431                             value: @""
432                             ID: i
433                             parent: self]];
434                     }
435                 }
436                 else if (o_parent == o_root_item)
437                 {
438                     o_children = [[NSMutableArray alloc] initWithCapacity:
439                         p_playlist->pp_items[i_item]->input.
440                         pp_categories[i_object_id]->i_infos];
441                     for (i = 0 ; i<p_playlist->pp_items[i_item]->input.
442                            pp_categories[i_object_id]->i_infos ; i++)
443                     {
444                         [o_children addObject:[[VLCInfoTreeItem alloc]
445                         initWithName: [NSString stringWithUTF8String:
446                                 p_playlist->pp_items[i_item]->input.
447                                 pp_categories[i_object_id]->
448                                 pp_infos[i]->psz_name]
449                             value: [NSString stringWithUTF8String:
450                                 p_playlist->pp_items[i_item]->input.
451                                 pp_categories[i_object_id]->
452                                 pp_infos[i]->psz_value]
453                             ID: i
454                             parent: self]];
455                     }
456                 }
457                 else
458                 {
459                     o_children = IsALeafNode;
460                 }
461             }
462             vlc_object_release(p_playlist);
463         }
464     }
465     return o_children;
466 }
467
468 - (NSString *)getName
469 {
470     return o_name;
471 }
472
473 - (NSString *)getValue
474 {
475     return o_value;
476 }
477
478 - (VLCInfoTreeItem *)childAtIndex:(int)i_index {
479     return [[self children] objectAtIndex:i_index];
480 }
481
482 - (int)numberOfChildren {
483     id i_tmp = [self children];
484     return (i_tmp == IsALeafNode) ? (-1) : (int)[i_tmp count];
485 }
486
487 /*- (int)selectedPlaylistItem
488 {
489     return i_item;
490 }
491 */
492 - (void)refresh
493 {
494     i_item = [[[VLCMain sharedInstance] getInfo] getItem];
495     if (o_children != NULL)
496     {
497         [o_children release];
498         o_children = NULL;
499     }
500 }
501
502 @end
503