+ NSMenuItem * o_lmi;
+ module_t * p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+
+ if( !strcmp( p_parser->psz_capability, "services_discovery" ) )
+ {
+ /* create the menu entries used in the playlist menu */
+ o_lmi = [[o_mi_services submenu] addItemWithTitle:
+ [NSString stringWithUTF8String:
+ p_parser->psz_longname ? p_parser->psz_longname :
+ ( p_parser->psz_shortname ? p_parser->psz_shortname:
+ p_parser->psz_object_name)]
+ action: @selector(servicesChange:)
+ keyEquivalent: @""];
+ [o_lmi setTarget: self];
+ [o_lmi setRepresentedObject:
+ [NSString stringWithCString: p_parser->psz_object_name]];
+ if( playlist_IsServicesDiscoveryLoaded( p_playlist,
+ p_parser->psz_object_name ) )
+ [o_lmi setState: NSOnState];
+
+ /* create the menu entries for the main menu */
+ o_lmi = [[o_mm_mi_services submenu] addItemWithTitle:
+ [NSString stringWithUTF8String:
+ p_parser->psz_longname ? p_parser->psz_longname :
+ ( p_parser->psz_shortname ? p_parser->psz_shortname:
+ p_parser->psz_object_name)]
+ action: @selector(servicesChange:)
+ keyEquivalent: @""];
+ [o_lmi setTarget: self];
+ [o_lmi setRepresentedObject:
+ [NSString stringWithCString: p_parser->psz_object_name]];
+ if( playlist_IsServicesDiscoveryLoaded( p_playlist,
+ p_parser->psz_object_name ) )
+ [o_lmi setState: NSOnState];
+ }
+ }
+ vlc_list_release( p_list );
+ vlc_object_release( p_playlist );
+
+ //[self playlistUpdated];
+}
+
+- (void)searchfieldChanged:(NSNotification *)o_notification
+{
+ [o_search_field setStringValue:[[o_notification object] stringValue]];
+}
+
+- (void)initStrings
+{
+ [super initStrings];
+
+ [o_mi_save_playlist setTitle: _NS("Save Playlist...")];
+ [o_mi_play setTitle: _NS("Play")];
+ [o_mi_delete setTitle: _NS("Delete")];
+ [o_mi_recursive_expand setTitle: _NS("Expand Node")];
+ [o_mi_selectall setTitle: _NS("Select All")];
+ [o_mi_info setTitle: _NS("Information")];
+ [o_mi_preparse setTitle: _NS("Get Stream Information")];
+ [o_mi_sort_name setTitle: _NS("Sort Node by Name")];
+ [o_mi_sort_author setTitle: _NS("Sort Node by Author")];
+ [o_mi_services setTitle: _NS("Services discovery")];
+ [o_status_field setStringValue: [NSString stringWithFormat:
+ _NS("No items in the playlist")]];
+
+ [o_random_ckb setTitle: _NS("Random")];
+#if 0
+ [o_search_button setTitle: _NS("Search")];
+#endif
+ [o_search_field setToolTip: _NS("Search in Playlist")];
+ [[o_loop_popup itemAtIndex:0] setTitle: _NS("Standard Play")];
+ [[o_loop_popup itemAtIndex:1] setTitle: _NS("Repeat One")];
+ [[o_loop_popup itemAtIndex:2] setTitle: _NS("Repeat All")];
+ [o_mi_addNode setTitle: _NS("Add Folder to Playlist")];
+
+ [o_save_accessory_text setStringValue: _NS("File Format:")];
+ [[o_save_accessory_popup itemAtIndex:0] setTitle: _NS("Extended M3U")];
+ [[o_save_accessory_popup itemAtIndex:1] setTitle: _NS("XML Shareable Playlist Format (XSPF)")];
+}
+
+- (void)playlistUpdated
+{
+ unsigned int i;
+
+ /* Clear indications of any existing column sorting */
+ for( i = 0 ; i < [[o_outline_view tableColumns] count] ; i++ )
+ {
+ [o_outline_view setIndicatorImage:nil inTableColumn:
+ [[o_outline_view tableColumns] objectAtIndex:i]];
+ }
+
+ [o_outline_view setHighlightedTableColumn:nil];
+ o_tc_sortColumn = nil;
+ // TODO Find a way to keep the dict size to a minimum
+ //[o_outline_dict removeAllObjects];
+ [o_outline_view reloadData];
+ [[[[VLCMain sharedInstance] getWizard] getPlaylistWizard] reloadOutlineView];
+ [[[[VLCMain sharedInstance] getBookmarks] getDataTable] reloadData];
+
+ playlist_t *p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ if(! p_playlist )
+ return;
+
+ if( p_playlist->i_size >= 2 )
+ {
+ [o_status_field setStringValue: [NSString stringWithFormat:
+ _NS("%i items in the playlist"), p_playlist->i_size]];
+ }
+ else
+ {
+ if( p_playlist->i_size == 0 )
+ {
+ [o_status_field setStringValue: _NS("No items in the playlist")];
+ }
+ else
+ {
+ [o_status_field setStringValue: _NS("1 item in the playlist")];
+ }
+ }
+ vlc_object_release( p_playlist );
+}
+
+- (void)playModeUpdated
+{
+ playlist_t *p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ vlc_value_t val, val2;
+
+ if( p_playlist == NULL )
+ {
+ return;
+ }
+
+ var_Get( p_playlist, "loop", &val2 );
+ var_Get( p_playlist, "repeat", &val );
+ if( val.b_bool == VLC_TRUE )
+ {
+ [o_loop_popup selectItemAtIndex: 1];
+ }
+ else if( val2.b_bool == VLC_TRUE )
+ {
+ [o_loop_popup selectItemAtIndex: 2];
+ }
+ else
+ {
+ [o_loop_popup selectItemAtIndex: 0];
+ }
+
+ var_Get( p_playlist, "random", &val );
+ [o_random_ckb setState: val.b_bool];
+
+ vlc_object_release( p_playlist );
+}
+
+- (void)updateRowSelection
+{
+ int i_row;
+ unsigned int j;
+
+ playlist_t *p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ playlist_item_t *p_item, *p_temp_item;
+ NSMutableArray *o_array = [NSMutableArray array];
+
+ if( p_playlist == NULL )
+ return;
+
+ p_item = p_playlist->status.p_item;
+ if( p_item == NULL )
+ {
+ vlc_object_release(p_playlist);
+ return;
+ }
+
+ p_temp_item = p_item;
+ while( p_temp_item->p_parent )
+ {
+ [o_array insertObject: [NSValue valueWithPointer: p_temp_item] atIndex: 0];
+ p_temp_item = p_temp_item->p_parent;
+ /*for (i = 0 ; i < p_temp_item->i_parents ; i++)
+ {
+ if( p_temp_item->pp_parents[i]->i_view == i_current_view )
+ {
+ p_temp_item = p_temp_item->pp_parents[i]->p_parent;
+ break;
+ }
+ }*/
+ }
+
+ for( j = 0; j < [o_array count] - 1; j++ )
+ {
+ id o_item;
+ if( ( o_item = [o_outline_dict objectForKey:
+ [NSString stringWithFormat: @"%p",
+ [[o_array objectAtIndex:j] pointerValue]]] ) != nil )
+ {
+ msg_Err( p_playlist, "o_item: %p", o_item );
+ [o_outline_view expandItem: o_item];
+ }
+
+ }
+
+ i_row = [o_outline_view rowForItem:[o_outline_dict
+ objectForKey:[NSString stringWithFormat: @"%p", p_item]]];
+
+ [o_outline_view selectRow: i_row byExtendingSelection: NO];
+ [o_outline_view scrollRowToVisible: i_row];
+
+ vlc_object_release(p_playlist);
+
+ /* update our info-panel to reflect the new item */
+ [[[VLCMain sharedInstance] getInfo] updatePanel];
+}
+
+/* Check if p_item is a child of p_node recursively. We need to check the item
+ existence first since OSX sometimes tries to redraw items that have been
+ deleted. We don't do it when not required since this verification takes
+ quite a long time on big playlists (yes, pretty hacky). */
+- (BOOL)isItem: (playlist_item_t *)p_item
+ inNode: (playlist_item_t *)p_node
+ checkItemExistence:(BOOL)b_check
+
+{
+ playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ playlist_item_t *p_temp_item = p_item;
+
+ if( p_playlist == NULL )
+ {
+ return NO;
+ }
+
+ if( p_node == p_item )
+ {
+ vlc_object_release(p_playlist);
+ return YES;
+ }
+
+ if( p_node->i_children < 1)
+ {
+ vlc_object_release(p_playlist);
+ return NO;
+ }