+ [[[[VLCMain sharedInstance] getWizard] getPlaylistWizard] reloadOutlineView];
+ [[[[VLCMain sharedInstance] getBookmarks] getDataTable] reloadData];
+
+ playlist_t *p_playlist = pl_Yield( VLCIntf );
+
+ if( playlist_CurrentSize( p_playlist ) >= 2 )
+ {
+ [o_status_field setStringValue: [NSString stringWithFormat:
+ _NS("%i items"),
+ playlist_CurrentSize( p_playlist )]];
+ }
+ else
+ {
+ if( playlist_IsEmpty( p_playlist ) )
+ [o_status_field setStringValue: _NS("No items in the playlist")];
+ else
+ [o_status_field setStringValue: _NS("1 item")];
+ }
+ vlc_object_release( p_playlist );
+}
+
+- (void)playModeUpdated
+{
+ playlist_t *p_playlist = pl_Yield( VLCIntf );
+
+ bool loop = var_GetBool( p_playlist, "loop" );
+ bool repeat = var_GetBool( p_playlist, "repeat" );
+ if( repeat )
+ [[[VLCMain sharedInstance] getControls] repeatOne];
+ else if( loop )
+ [[[VLCMain sharedInstance] getControls] repeatAll];
+ else
+ [[[VLCMain sharedInstance] getControls] repeatOff];
+
+ [[[VLCMain sharedInstance] getControls] shuffle];
+
+ vlc_object_release( p_playlist );
+}
+
+- (void)updateRowSelection
+{
+ int i_row;
+ unsigned int j;
+
+ playlist_t *p_playlist = pl_Yield( VLCIntf );
+ playlist_item_t *p_item, *p_temp_item;
+ NSMutableArray *o_array = [NSMutableArray array];
+
+ 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( 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 )
+ {
+ [o_outline_view expandItem: o_item];
+ }
+
+ }
+
+ 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 = pl_Yield( VLCIntf );
+ playlist_item_t *p_temp_item = p_item;
+
+ 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;
+ }
+
+ if ( p_temp_item )
+ {
+ int i;
+ PL_LOCK;
+
+ if( b_check )
+ {
+ /* Since outlineView: willDisplayCell:... may call this function with
+ p_items that don't exist anymore, first check if the item is still
+ in the playlist. Any cleaner solution welcomed. */
+ for( i = 0; i < p_playlist->all_items.i_size; i++ )
+ {
+ if( ARRAY_VAL( p_playlist->all_items, i) == p_item ) break;
+ else if ( i == p_playlist->all_items.i_size - 1 )
+ {
+ vlc_object_release( p_playlist );
+ PL_UNLOCK;
+ return NO;
+ }
+ }
+ }
+
+ while( p_temp_item )
+ {
+ p_temp_item = p_temp_item->p_parent;
+ if( p_temp_item == p_node )
+ {
+ PL_UNLOCK;
+ vlc_object_release( p_playlist );
+ return YES;
+ }
+ }
+ PL_UNLOCK;
+ }
+
+ vlc_object_release( p_playlist );
+ return NO;
+}
+
+/* This method is usefull for instance to remove the selected children of an
+ already selected node */
+- (void)removeItemsFrom:(id)o_items ifChildrenOf:(id)o_nodes
+{
+ unsigned int i, j;
+ for( i = 0 ; i < [o_items count] ; i++ )
+ {
+ for ( j = 0 ; j < [o_nodes count] ; j++ )
+ {
+ if( o_items == o_nodes)
+ {
+ if( j == i ) continue;
+ }
+ if( [self isItem: [[o_items objectAtIndex:i] pointerValue]
+ inNode: [[o_nodes objectAtIndex:j] pointerValue]
+ checkItemExistence: NO] )
+ {
+ [o_items removeObjectAtIndex:i];
+ /* We need to execute the next iteration with the same index
+ since the current item has been deleted */
+ i--;
+ break;
+ }
+ }
+ }
+
+}
+
+- (IBAction)savePlaylist:(id)sender
+{
+ playlist_t * p_playlist = pl_Yield( VLCIntf );
+
+ NSSavePanel *o_save_panel = [NSSavePanel savePanel];
+ NSString * o_name = [NSString stringWithFormat: @"%@", _NS("Untitled")];
+
+ //[o_save_panel setAllowedFileTypes: [NSArray arrayWithObjects: @"m3u", @"xpf", nil] ];
+ [o_save_panel setTitle: _NS("Save Playlist")];
+ [o_save_panel setPrompt: _NS("Save")];
+ [o_save_panel setAccessoryView: o_save_accessory_view];
+
+ if( [o_save_panel runModalForDirectory: nil
+ file: o_name] == NSOKButton )
+ {
+ NSString *o_filename = [o_save_panel filename];
+
+ if( [o_save_accessory_popup indexOfSelectedItem] == 1 )
+ {
+ NSString * o_real_filename;
+ NSRange range;
+ range.location = [o_filename length] - [@".xspf" length];
+ range.length = [@".xspf" length];
+
+ if( [o_filename compare:@".xspf" options: NSCaseInsensitiveSearch
+ range: range] != NSOrderedSame )
+ {
+ o_real_filename = [NSString stringWithFormat: @"%@.xspf", o_filename];
+ }
+ else
+ {
+ o_real_filename = o_filename;
+ }
+ playlist_Export( p_playlist,
+ [o_real_filename fileSystemRepresentation],
+ p_playlist->p_local_category, "export-xspf" );
+ }
+ else
+ {
+ NSString * o_real_filename;
+ NSRange range;
+ range.location = [o_filename length] - [@".m3u" length];
+ range.length = [@".m3u" length];
+
+ if( [o_filename compare:@".m3u" options: NSCaseInsensitiveSearch
+ range: range] != NSOrderedSame )
+ {
+ o_real_filename = [NSString stringWithFormat: @"%@.m3u", o_filename];
+ }
+ else
+ {
+ o_real_filename = o_filename;
+ }
+ playlist_Export( p_playlist,
+ [o_real_filename fileSystemRepresentation],
+ p_playlist->p_local_category, "export-m3u" );
+ }
+ }
+ vlc_object_release( p_playlist );