]> git.sesse.net Git - vlc/blob - modules/gui/macosx/playlistinfo.m
* Use the playlist info panel instead of the old one everywhere
[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_info_ok setTitle: _NS("OK")];
65     [o_btn_info_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 = [[[NSApp delegate] getPlaylist] selectedPlaylistItem];
80         o_selected = [[[NSApp delegate] 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 = [NSApp getIntf];
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 = [NSApp getIntf];
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         /*fill uri / title / author info */
122         [o_uri_txt setStringValue:
123             ([NSString stringWithUTF8String:p_playlist->
124                pp_items[i_item]->input.psz_uri] == nil ) ?
125             [NSString stringWithCString:p_playlist->
126                 pp_items[i_item]->input.psz_uri] :
127             [NSString stringWithUTF8String:p_playlist->
128                 pp_items[i_item]->input.psz_uri]];
129
130         [o_title_txt setStringValue:
131             ([NSString stringWithUTF8String:p_playlist->
132                 pp_items[i_item]->input.psz_name] == nil ) ?
133             [NSString stringWithCString:p_playlist->
134                 pp_items[i_item]->input.psz_name] :
135             [NSString stringWithUTF8String:p_playlist->
136                 pp_items[i_item]->input.psz_name]];
137
138         [o_author_txt setStringValue:
139             [NSString stringWithUTF8String:playlist_GetInfo
140             (p_playlist, i_item ,_("General"),_("Author") )]];
141
142         [[VLCInfoTreeItem rootItem] refresh];
143         [o_outline_view reloadData];
144
145         [self createComboBox];
146         [self handleGroup:self];
147
148         vlc_object_release( p_playlist );
149     }
150     [o_info_window makeKeyAndOrderFront: sender];
151 }
152
153 - (IBAction)infoCancel:(id)sender
154 {
155     [o_info_window orderOut: self];
156 }
157
158
159 - (IBAction)infoOk:(id)sender
160 {
161     int i,i_row,c;
162     intf_thread_t * p_intf = [NSApp getIntf];
163     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
164                                           FIND_ANYWHERE );
165     vlc_value_t val;
166     NSNumber * o_number;
167
168
169     if (p_playlist)
170     {
171         vlc_mutex_lock(&p_playlist->pp_items[i_item]->input.lock);
172
173         p_playlist->pp_items[i_item]->input.psz_uri =
174             strdup([[o_uri_txt stringValue] cString]);
175         p_playlist->pp_items[i_item]->input.psz_name =
176             strdup([[o_title_txt stringValue] cString]);
177         playlist_ItemAddInfo(p_playlist->pp_items[i_item],_("General"),_("Author"), [[o_author_txt stringValue] cString]);
178
179         c = (int)[o_selected count];
180
181         if ([[o_group_cbx stringValue] isEqual:
182                     [o_group_cbx objectValueOfSelectedItem]])
183         {
184             for (i = 0 ; i < c ; i++)
185             {
186                 o_number = [o_selected lastObject];
187                 i_row = [o_number intValue];
188                 p_playlist->pp_items[i_row]->i_group = p_playlist->
189                     pp_groups[[o_group_cbx indexOfSelectedItem]]->i_id;
190                 [o_selected removeObject: o_number];
191             }
192         }
193         else
194         {
195             playlist_group_t * p_group = playlist_CreateGroup( p_playlist,
196                 strdup([[o_group_cbx stringValue] cString]));
197             if (p_group)
198             {
199                 for (i = 0 ; i < c ; i++)
200                 {
201                     o_number = [o_selected lastObject];
202                     i_row = [o_number intValue];
203                     p_playlist->pp_items[i_row]->i_group = p_group->i_id;
204                     [o_selected removeObject: o_number];
205                 }
206             }
207         }
208
209
210         vlc_mutex_unlock(&p_playlist->pp_items[i_item]->input.lock);
211         val.b_bool = VLC_TRUE;
212         var_Set( p_playlist,"intf-change",val );
213         vlc_object_release ( p_playlist );
214     }
215     [o_info_window orderOut: self];
216 }
217
218 - (IBAction)handleGroup:(id)sender
219 {
220     intf_thread_t * p_intf = [NSApp getIntf];
221     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
222                                           FIND_ANYWHERE );
223
224     if (p_playlist)
225     {
226         if ([[o_group_cbx stringValue] isEqual:
227                     [o_group_cbx objectValueOfSelectedItem]])
228         {
229             [o_group_color setBackgroundColor:[[[NSApp delegate] getPlaylist]
230                 getColor: p_playlist->pp_groups[
231                 [o_group_cbx indexOfSelectedItem]]->i_id]];
232         }
233         else
234         {
235             [o_group_color setBackgroundColor:[[[NSApp delegate] getPlaylist]
236                 getColor:p_playlist->pp_groups[
237                 [o_group_cbx numberOfItems] - 1]->i_id + 1]];
238         }
239     vlc_object_release(p_playlist);
240     }
241 }
242
243 - (IBAction)deleteOutlineGroup:(id)sender
244 {
245     intf_thread_t * p_intf = [NSApp getIntf];
246     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
247                                           FIND_ANYWHERE );
248
249     if(p_playlist)
250     {
251         if ([[o_group_cbx stringValue] isEqual:
252                     [o_group_cbx objectValueOfSelectedItem]])
253         {
254             [[[NSApp delegate] getPlaylist] deleteGroup:p_playlist->pp_groups[
255                     [o_group_cbx indexOfSelectedItem]]->i_id];
256             [self createComboBox];
257             [self handleGroup:self];
258             [o_group_cbx reloadData];
259         }
260         else
261         {
262             msg_Warn(p_playlist,"Group doesn't exist, cannot delete");
263         }
264     vlc_object_release(p_playlist);
265     }
266 }
267
268 - (IBAction)createOutlineGroup:(id)sender;
269 {
270     intf_thread_t * p_intf = [NSApp getIntf];
271     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
272                                           FIND_ANYWHERE );
273     if(p_playlist)
274     {
275         playlist_CreateGroup( p_playlist,
276                     strdup([[o_group_cbx stringValue] cString]));
277         [self createComboBox];
278         [o_group_cbx reloadData];
279         [[[NSApp delegate] getPlaylist] playlistUpdated];
280         vlc_object_release(p_playlist);
281     }
282 }
283
284 -(void)createComboBox
285 {
286     intf_thread_t * p_intf = [NSApp getIntf];
287     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
288                                           FIND_ANYWHERE );
289     int i;
290
291     [o_group_cbx removeAllItems];
292
293     if (p_playlist)
294     {
295         for (i = 0; i < p_playlist->i_groups ; i++)
296         {
297             [o_group_cbx addItemWithObjectValue:
298                 [NSString stringWithUTF8String:
299                 p_playlist->pp_groups[i]->psz_name]];
300             if (p_playlist->pp_items[i_item]->i_group == p_playlist
301                 ->pp_groups[i]->i_id)
302             {
303                 [o_group_cbx selectItemAtIndex:i];
304             }
305         }
306     vlc_object_release(p_playlist);
307     }
308 }
309
310 - (int)getItem
311 {
312     return i_item;
313 }
314
315 @end
316
317 @implementation VLCInfo (NSMenuValidation)
318
319 - (BOOL)validateMenuItem:(NSMenuItem *)o_mi
320 {
321     BOOL bEnabled = TRUE;
322
323     intf_thread_t * p_intf = [NSApp getIntf];
324     input_thread_t * p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
325                                                        FIND_ANYWHERE );
326
327     if( [[o_mi title] isEqualToString: _NS("Info")] )
328     {
329         if( p_input == NULL )
330         {
331             bEnabled = FALSE;
332         }
333     }
334     if( p_input ) vlc_object_release( p_input );
335
336     return( bEnabled );
337 }
338
339 @end
340
341 @implementation VLCInfo (NSTableDataSource)
342
343 - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
344 {
345     return (item == nil) ? [[VLCInfoTreeItem rootItem] numberOfChildren] : [item numberOfChildren];
346 }
347
348 - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
349     return ([item numberOfChildren] > 0);
350 }
351
352 - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
353 {
354     return (item == nil) ? [[VLCInfoTreeItem rootItem] childAtIndex:index] : [item childAtIndex:index];
355 }
356
357 - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
358 {
359     if ([[tableColumn identifier] isEqualToString:@"0"])
360     {
361         return (item == nil) ? @"" : (id)[item getName];
362     }
363     else
364     {
365         return (item == nil) ? @"" : (id)[item getValue];
366     }
367 }
368
369
370 @end
371
372 @implementation VLCInfoTreeItem
373
374 static VLCInfoTreeItem *o_root_item = nil;
375
376 #define IsALeafNode ((id)-1)
377
378 - (id)initWithName: (NSString *)o_item_name value: (NSString *)o_item_value ID: (int)i_id parent:(VLCInfoTreeItem *)o_parent_item
379 {
380     self = [super init];
381
382     if( self != nil )
383     {
384         o_name = [o_item_name copy];
385         o_value = [o_item_value copy];
386         i_object_id = i_id;
387         o_parent = o_parent_item;
388         i_item = [[[NSApp delegate] getInfo] getItem];
389     }
390     return( self );
391 }
392
393 + (VLCInfoTreeItem *)rootItem {
394     if (o_root_item == nil) o_root_item = [[VLCInfoTreeItem alloc] initWithName:@"main" value: @"" ID: 0 parent:nil];
395     return o_root_item;
396 }
397
398 - (void)dealloc
399 {
400     if (o_children != IsALeafNode) [o_children release];
401     [o_name release];
402     [super dealloc];
403 }
404
405 /* Creates and returns the array of children
406  * Loads children incrementally */
407 - (NSArray *)children
408 {
409     if (o_children == NULL)
410     {
411         intf_thread_t * p_intf = [NSApp getIntf];
412         playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
413                                           FIND_ANYWHERE );
414         int i;
415
416         if (p_playlist)
417         {
418             if (i_item > -1)
419             {
420                 if (self == o_root_item)
421                 {
422                     o_children = [[NSMutableArray alloc] initWithCapacity:p_playlist->pp_items[i_item]->input.i_categories];
423                     for (i = 0 ; i<p_playlist->pp_items[i_item]->input.i_categories ; i++)
424                     {
425                         [o_children addObject:[[VLCInfoTreeItem alloc]
426                             initWithName: [NSString stringWithUTF8String:
427                                 p_playlist->pp_items[i_item]->input.
428                                 pp_categories[i]->psz_name]
429                             value: @""
430                             ID: i
431                             parent: self]];
432                     }
433                 }
434                 else if (o_parent == o_root_item)
435                 {
436                     o_children = [[NSMutableArray alloc] initWithCapacity:
437                         p_playlist->pp_items[i_item]->input.
438                         pp_categories[i_object_id]->i_infos];
439                     for (i = 0 ; i<p_playlist->pp_items[i_item]->input.
440                            pp_categories[i_object_id]->i_infos ; i++)
441                     {
442                         [o_children addObject:[[VLCInfoTreeItem alloc]
443                         initWithName: [NSString stringWithUTF8String:
444                                 p_playlist->pp_items[i_item]->input.
445                                 pp_categories[i_object_id]->
446                                 pp_infos[i]->psz_name]
447                             value: [NSString stringWithUTF8String:
448                                 p_playlist->pp_items[i_item]->input.
449                                 pp_categories[i_object_id]->
450                                 pp_infos[i]->psz_value]
451                             ID: i
452                             parent: self]];
453                     }
454                 }
455                 else
456                 {
457                     o_children = IsALeafNode;
458                 }
459             }
460             vlc_object_release(p_playlist);
461         }
462     }
463     return o_children;
464 }
465
466 - (NSString *)getName
467 {
468     return o_name;
469 }
470
471 - (NSString *)getValue
472 {
473     return o_value;
474 }
475
476 - (VLCInfoTreeItem *)childAtIndex:(int)i_index {
477     return [[self children] objectAtIndex:i_index];
478 }
479
480 - (int)numberOfChildren {
481     id i_tmp = [self children];
482     return (i_tmp == IsALeafNode) ? (-1) : (int)[i_tmp count];
483 }
484
485 /*- (int)selectedPlaylistItem
486 {
487     return i_item;
488 }
489 */
490 - (void)refresh
491 {
492     i_item = [[[NSApp delegate] getInfo] getItem];
493     if (o_children != NULL)
494     {
495         [o_children release];
496         o_children = NULL;
497     }
498 }
499
500 @end
501