+- (NSMutableArray *)subSearchItem:(playlist_item_t *)p_item
+{
+ playlist_t *p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ playlist_item_t *p_selected_item;
+ int i_current, i_selected_row;
+
+ if( !p_playlist )
+ return NULL;
+
+ i_selected_row = [o_outline_view selectedRow];
+ if (i_selected_row < 0)
+ i_selected_row = 0;
+
+ p_selected_item = (playlist_item_t *)[[o_outline_view itemAtRow:
+ i_selected_row] pointerValue];
+
+ for( i_current = 0; i_current < p_item->i_children ; i_current++ )
+ {
+ char *psz_temp;
+ NSString *o_current_name, *o_current_author;
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+ o_current_name = [NSString stringWithUTF8String:
+ p_item->pp_children[i_current]->input.psz_name];
+ psz_temp = vlc_input_item_GetInfo( &p_item->input ,
+ _("Meta-information"),_("Artist") );
+ o_current_author = [NSString stringWithUTF8String: psz_temp];
+ free( psz_temp);
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ if( p_selected_item == p_item->pp_children[i_current] &&
+ b_selected_item_met == NO )
+ {
+ b_selected_item_met = YES;
+ }
+ else if( p_selected_item == p_item->pp_children[i_current] &&
+ b_selected_item_met == YES )
+ {
+ vlc_object_release( p_playlist );
+ return NULL;
+ }
+ else if( b_selected_item_met == YES &&
+ ( [o_current_name rangeOfString:[o_search_field
+ stringValue] options:NSCaseInsensitiveSearch ].length ||
+ [o_current_author rangeOfString:[o_search_field
+ stringValue] options:NSCaseInsensitiveSearch ].length ) )
+ {
+ vlc_object_release( p_playlist );
+ /*Adds the parent items in the result array as well, so that we can
+ expand the tree*/
+ return [NSMutableArray arrayWithObject: [NSValue
+ valueWithPointer: p_item->pp_children[i_current]]];
+ }
+ if( p_item->pp_children[i_current]->i_children > 0 )
+ {
+ id o_result = [self subSearchItem:
+ p_item->pp_children[i_current]];
+ if( o_result != NULL )
+ {
+ vlc_object_release( p_playlist );
+ [o_result insertObject: [NSValue valueWithPointer:
+ p_item->pp_children[i_current]] atIndex:0];
+ return o_result;
+ }
+ }
+ }
+ vlc_object_release( p_playlist );
+ return NULL;
+}
+
+- (IBAction)searchItem:(id)sender
+{
+ playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ playlist_view_t * p_view;
+ id o_result;
+
+ unsigned int i;
+ int i_row = -1;
+
+ b_selected_item_met = NO;
+
+ if( p_playlist == NULL )
+ return;
+
+ p_view = playlist_ViewFind( p_playlist, i_current_view );
+
+ if( p_view )
+ {
+ /*First, only search after the selected item:*
+ *(b_selected_item_met = NO) */
+ o_result = [self subSearchItem:p_view->p_root];
+ if( o_result == NULL )
+ {
+ /* If the first search failed, search again from the beginning */
+ o_result = [self subSearchItem:p_view->p_root];
+ }
+ if( o_result != NULL )
+ {
+ for( i = 0 ; i < [o_result count] - 1 ; i++ )
+ {
+ [o_outline_view expandItem: [o_outline_dict objectForKey:
+ [NSString stringWithFormat: @"%p",
+ [[o_result objectAtIndex: i] pointerValue]]]];
+ }
+ i_row = [o_outline_view rowForItem: [o_outline_dict objectForKey:
+ [NSString stringWithFormat: @"%p",
+ [[o_result objectAtIndex: [o_result count] - 1 ]
+ pointerValue]]]];
+ }
+ if( i_row > -1 )
+ {
+ [o_outline_view selectRow:i_row byExtendingSelection: NO];
+ [o_outline_view scrollRowToVisible: i_row];
+ }
+ }
+ vlc_object_release( p_playlist );
+}
+
+- (NSMenu *)menuForEvent:(NSEvent *)o_event
+{
+ NSPoint pt;
+ vlc_bool_t b_rows;
+ vlc_bool_t b_item_sel;
+
+ pt = [o_outline_view convertPoint: [o_event locationInWindow]
+ fromView: nil];
+ b_item_sel = ( [o_outline_view rowAtPoint: pt] != -1 &&
+ [o_outline_view selectedRow] != -1 );
+ b_rows = [o_outline_view numberOfRows] != 0;
+
+ [o_mi_play setEnabled: b_item_sel];
+ [o_mi_delete setEnabled: b_item_sel];
+ [o_mi_selectall setEnabled: b_rows];
+ [o_mi_info setEnabled: b_item_sel];
+
+ return( o_ctx_menu );
+}
+
+- (playlist_item_t *)selectedPlaylistItem
+{
+ return [[o_outline_view itemAtRow: [o_outline_view selectedRow]]
+ pointerValue];
+}
+
+- (void)outlineView: (NSTableView*)o_tv
+ didClickTableColumn:(NSTableColumn *)o_tc
+{
+ int i_mode = 0, i_type;
+ intf_thread_t *p_intf = VLCIntf;
+ playlist_view_t *p_view;
+
+ playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ if( p_playlist == NULL )
+ {
+ return;
+ }
+
+ /* Check whether the selected table column header corresponds to a
+ sortable table column*/
+ if( !( o_tc == o_tc_name || o_tc == o_tc_author ) )
+ {
+ vlc_object_release( p_playlist );
+ return;
+ }
+
+ p_view = playlist_ViewFind( p_playlist, i_current_view );
+
+ if( o_tc_sortColumn == o_tc )
+ {
+ b_isSortDescending = !b_isSortDescending;
+ }
+ else
+ {
+ b_isSortDescending = VLC_FALSE;
+ }
+
+ if( o_tc == o_tc_name )
+ {
+ i_mode = SORT_TITLE;
+ }
+ else if( o_tc == o_tc_author )
+ {
+ i_mode = SORT_AUTHOR;
+ }
+
+ if( b_isSortDescending )
+ {
+ i_type = ORDER_REVERSE;
+ }
+ else
+ {
+ i_type = ORDER_NORMAL;
+ }
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+ playlist_RecursiveNodeSort( p_playlist, p_view->p_root, i_mode, i_type );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ vlc_object_release( p_playlist );
+ [self playlistUpdated];
+
+ o_tc_sortColumn = o_tc;
+ [o_outline_view setHighlightedTableColumn:o_tc];
+
+ if( b_isSortDescending )
+ {
+ [o_outline_view setIndicatorImage:o_descendingSortingImage
+ inTableColumn:o_tc];
+ }
+ else
+ {
+ [o_outline_view setIndicatorImage:o_ascendingSortingImage
+ inTableColumn:o_tc];
+ }
+}
+
+
+- (void)outlineView:(NSOutlineView *)outlineView
+ willDisplayCell:(id)cell
+ forTableColumn:(NSTableColumn *)tableColumn
+ item:(id)item
+{
+ playlist_t *p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ playlist_item_t *p_item = (playlist_item_t *)[item pointerValue];
+
+ if( !p_playlist ) return;
+
+ if( ( p_item == p_playlist->status.p_item ) ||
+ ( p_item->i_children != 0 &&
+ [self isItem: p_playlist->status.p_item inNode: p_item] ) )
+ {
+ [cell setFont: [NSFont boldSystemFontOfSize: 0]];
+ }
+ else
+ {
+ [cell setFont: [NSFont systemFontOfSize: 0]];
+ }
+ vlc_object_release( p_playlist );
+}
+