+- (IBAction)servicesChange:(id)sender
+{
+ NSMenuItem *o_mi = (NSMenuItem *)sender;
+ NSString *o_string = [o_mi representedObject];
+ playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ if( !playlist_IsServicesDiscoveryLoaded( p_playlist, [o_string cString] ) )
+ playlist_ServicesDiscoveryAdd( p_playlist, [o_string cString] );
+ else
+ playlist_ServicesDiscoveryRemove( p_playlist, [o_string cString] );
+
+ [o_mi setState: playlist_IsServicesDiscoveryLoaded( p_playlist,
+ [o_string cString] ) ? YES : NO];
+
+ vlc_object_release( p_playlist );
+ [self playlistUpdated];
+ return;
+}
+
+- (IBAction)selectAll:(id)sender
+{
+ [o_outline_view selectAll: nil];
+}
+
+- (IBAction)deleteItem:(id)sender
+{
+ int i, i_count, i_row;
+ NSMutableArray *o_to_delete;
+ NSNumber *o_number;
+
+ playlist_t * p_playlist;
+ intf_thread_t * p_intf = VLCIntf;
+
+ p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+
+ if ( p_playlist == NULL )
+ {
+ return;
+ }
+ o_to_delete = [NSMutableArray arrayWithArray:[[o_outline_view selectedRowEnumerator] allObjects]];
+ i_count = [o_to_delete count];
+
+ for( i = 0; i < i_count; i++ )
+ {
+ o_number = [o_to_delete lastObject];
+ i_row = [o_number intValue];
+ id o_item = [o_outline_view itemAtRow: i_row];
+ playlist_item_t *p_item = [o_item pointerValue];
+ [o_to_delete removeObject: o_number];
+ [o_outline_view deselectRow: i_row];
+
+ if( [[o_outline_view dataSource] outlineView:o_outline_view
+ numberOfChildrenOfItem: o_item] > 0 )
+ //is a node and not an item
+ {
+ if( p_playlist->status.i_status != PLAYLIST_STOPPED &&
+ [self isItem: p_playlist->status.p_item inNode:
+ ((playlist_item_t *)[o_item pointerValue])
+ checkItemExistence: NO] == YES )
+ {
+ // if current item is in selected node and is playing then stop playlist
+ playlist_Stop( p_playlist );
+ }
+ vlc_mutex_lock( &p_playlist->object_lock );
+ playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ }
+ else
+ {
+ playlist_LockDelete( p_playlist, p_item->i_id );
+ }
+ }
+ [self playlistUpdated];
+ vlc_object_release( p_playlist );
+}
+
+- (IBAction)sortNodeByName:(id)sender
+{
+ [self sortNode: SORT_TITLE];
+}
+
+- (IBAction)sortNodeByAuthor:(id)sender
+{
+ [self sortNode: SORT_AUTHOR];
+}
+
+- (void)sortNode:(int)i_mode
+{
+ playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ playlist_item_t * p_item;
+
+ if (p_playlist == NULL)
+ {
+ return;
+ }
+
+ if( [o_outline_view selectedRow] > -1 )
+ {
+ p_item = [[o_outline_view itemAtRow: [o_outline_view selectedRow]]
+ pointerValue];
+ }
+ else
+ /*If no item is selected, sort the whole playlist*/
+ {
+ p_item = p_playlist->p_root_category;
+ }
+
+ if( p_item->i_children > -1 ) // the item is a node
+ {
+ vlc_mutex_lock( &p_playlist->object_lock );
+ playlist_RecursiveNodeSort( p_playlist, p_item, i_mode, ORDER_NORMAL );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ }
+ else
+ {
+ vlc_mutex_lock( &p_playlist->object_lock );
+ playlist_RecursiveNodeSort( p_playlist,
+ p_item->p_parent, i_mode, ORDER_NORMAL );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ }
+ vlc_object_release( p_playlist );
+ [self playlistUpdated];
+}
+
+- (input_item_t *)createItem:(NSDictionary *)o_one_item