]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/playlist.m
Removes trailing spaces. Removes tabs.
[vlc] / modules / gui / macosx / playlist.m
index a2c99976f0715bf57f0e23425ad4d9893a2ebbae..9f800961a19b265a5c4d33beefe86a49787ec010 100644 (file)
 #import "controls.h"
 #import "vlc_osd.h"
 #import "misc.h"
-#import <vlc_interaction.h>
+#import <vlc_interface.h>
 
 /*****************************************************************************
- * VLCPlaylistView implementation 
+ * VLCPlaylistView implementation
  *****************************************************************************/
 @implementation VLCPlaylistView
 
 
     if( i_return <= 0 )
         i_return = 0;
-NSLog( @"%d children for %s", i_return, p_item->p_input->psz_name ); 
+
     return i_return;
 }
 
@@ -190,17 +190,15 @@ NSLog( @"%d children for %s", i_return, p_item->p_input->psz_name );
     }
     else
     {
-        p_item = (playlist_item_t *)[item pointerValue];      
+        p_item = (playlist_item_t *)[item pointerValue];
     }
     if( p_item && index < p_item->i_children && index >= 0 )
         p_return = p_item->pp_children[index];
-    
     vlc_object_release( p_playlist );
 
     o_value = [o_outline_dict objectForKey:[NSString stringWithFormat: @"%p", p_return]];
-    #if 0
-    NSLog( @"%s", p_return->p_input->psz_name);
-    #endif
+
     if( o_value == nil )
     {
         o_value = [[NSValue valueWithPointer: p_return] retain];
@@ -231,59 +229,92 @@ NSLog( @"%d children for %s", i_return, p_item->p_input->psz_name );
     }
     vlc_object_release( p_playlist );
 
-NSLog( @"expandable" ); 
-    if( i_return <= 0 )
-        return NO;
-    else
-        return YES;
+    return (i_return > 0);
 }
 
 /* retrieve the string values for the cells */
 - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)o_tc byItem:(id)item
 {
     id o_value = nil;
-    intf_thread_t *p_intf = VLCIntf;
     playlist_item_t *p_item;
-    
-    if( item == nil || ![item isKindOfClass: [NSValue class]] ) return( @"error" );
-    
-    p_item = (playlist_item_t *)[item pointerValue];
-    if( p_item == NULL )
+
+    /* For error handling */
+    static BOOL attempted_reload = NO;
+
+    if( item == nil || ![item isKindOfClass: [NSValue class]] )
     {
-        return( @"error");
+        /* Attempt to fix the error by asking for a data redisplay
+         * This might cause infinite loop, so add a small check */
+        if( !attempted_reload )
+        {
+            attempted_reload = YES;
+            [outlineView reloadData];
+        }
+        return @"error" ;
     }
-//NSLog( @"values for %p", p_item ); 
-    
-    if( [[o_tc identifier] isEqualToString:@"1"] )
+    p_item = (playlist_item_t *)[item pointerValue];
+    if( !p_item || !p_item->p_input )
     {
-        o_value = [NSString stringWithUTF8String:
-            p_item->p_input->psz_name];
-        if( o_value == NULL )
-            o_value = [NSString stringWithCString:
-                p_item->p_input->psz_name];
+        /* Attempt to fix the error by asking for a data redisplay
+         * This might cause infinite loop, so add a small check */
+        if( !attempted_reload )
+        {
+            attempted_reload = YES;
+            [outlineView reloadData];
+        }
+        return @"error";
     }
-    else if( [[o_tc identifier] isEqualToString:@"2"] && p_item->p_input->p_meta &&
-        p_item->p_input->p_meta->psz_artist && *p_item->p_input->p_meta->psz_artist )
+    attempted_reload = NO;
+
+    if( [[o_tc identifier] isEqualToString:@"1"] )
     {
-        o_value = [NSString stringWithUTF8String:
-            p_item->p_input->p_meta->psz_artist];
-        if( o_value == NULL )
-            o_value = [NSString stringWithCString:
-                p_item->p_input->p_meta->psz_artist];
+        /* sanity check to prevent the NSString class from crashing */
+        char *psz_title =  input_item_GetTitle( p_item->p_input );
+        if( !EMPTY_STR( psz_title ) )
+        {
+            o_value = [NSString stringWithUTF8String: psz_title];
+            if( o_value == NULL )
+                o_value = [NSString stringWithCString: psz_title];
+        }
+        else
+        {
+            char *psz_name = input_item_GetName( p_item->p_input );
+            if( psz_name != NULL )
+            {
+                o_value = [NSString stringWithUTF8String: psz_name];
+                if( o_value == NULL )
+                    o_value = [NSString stringWithCString: psz_name];
+            }
+            free( psz_name );
+        }
+        free( psz_title );
     }
-    else if( [[o_tc identifier] isEqualToString:@"3"] )
+    else
     {
-        char psz_duration[MSTRTIME_MAX_SIZE];
-        mtime_t dur = p_item->p_input->i_duration;
-        if( dur != -1 )
+        char *psz_artist = input_item_GetArtist( p_item->p_input );
+        if( [[o_tc identifier] isEqualToString:@"2"] && !EMPTY_STR( psz_artist ) )
         {
-            secstotimestr( psz_duration, dur/1000000 );
-            o_value = [NSString stringWithUTF8String: psz_duration];
+            o_value = [NSString stringWithUTF8String: psz_artist];
+            if( o_value == NULL )
+                o_value = [NSString stringWithCString: psz_artist];
         }
-        else
+        else if( [[o_tc identifier] isEqualToString:@"3"] )
         {
-            o_value = @"-:--:--";
+            char psz_duration[MSTRTIME_MAX_SIZE];
+            mtime_t dur = input_item_GetDuration( p_item->p_input );
+            if( dur != -1 )
+            {
+                secstotimestr( psz_duration, dur/1000000 );
+                o_value = [NSString stringWithUTF8String: psz_duration];
+            }
+            else
+            {
+                o_value = @"-:--:--";
+            }
         }
+        free( psz_artist );
     }
 
     return( o_value );
@@ -354,7 +385,7 @@ NSLog( @"expandable" );
         @"VLCPlaylistItemPboardType", nil]];
     [o_outline_view setIntercellSpacing: NSMakeSize (0.0, 1.0)];
 
-    /* this uses private Apple API which works fine until 10.4, 
+    /* this uses private Apple API which works fine until 10.4,
      * but keep checking in the future!
      * These methods are being added artificially to NSOutlineView's interface above */
     o_ascendingSortingImage = [[NSOutlineView class] _defaultTableHeaderSortImage];
@@ -364,40 +395,44 @@ NSLog( @"expandable" );
 
     for( i_index = 0; i_index < p_list->i_count; i_index++ )
     {
-        NSMenuItem * o_lmi;
-        module_t * p_parser = (module_t *)p_list->p_values[i_index].p_object ;
+        vlc_bool_t  b_enabled;
+        char        *objectname;
+        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 */
+            /* Check for submodules */
+            int i = -1;
+            while( p_parser->pp_shortcuts[++i] != NULL ); i--;
+
+            /* Check whether to enable these menuitems */
+            objectname = i>=0 ? (char *)p_parser->pp_shortcuts[i] : (char *)p_parser->psz_object_name;
+            b_enabled = playlist_IsServicesDiscoveryLoaded( p_playlist, objectname );
+            /* 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)]
+                     objectname)]
                                              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 setRepresentedObject: [NSString stringWithCString: objectname]];
+            if( b_enabled ) [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)]
+                     objectname)]
                                              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];
+            [o_lmi setRepresentedObject: [NSString stringWithCString:objectname]];
+            if( b_enabled ) [o_lmi setState: NSOnState];
         }
     }
     vlc_list_release( p_list );
@@ -460,21 +495,18 @@ NSLog( @"expandable" );
 
     playlist_t *p_playlist = pl_Yield( VLCIntf );
 
-    if( p_playlist->i_size >= 2 )
+    if( playlist_CurrentSize( p_playlist ) >= 2 )
     {
         [o_status_field setStringValue: [NSString stringWithFormat:
-                    _NS("%i items in the playlist"), p_playlist->i_size]];
+                    _NS("%i items in the playlist"),
+                playlist_CurrentSize( p_playlist )]];
     }
     else
     {
-        if( p_playlist->i_size == 0 )
-        {
+        if( playlist_IsEmpty( p_playlist ) )
             [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 );
 }
@@ -593,10 +625,10 @@ NSLog( @"expandable" );
         /* 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->i_all_size; i++ )
+            for( i = 0; i < p_playlist->all_items.i_size; i++ )
             {
-                if( p_playlist->pp_all_items[i] == p_item ) break;
-                else if ( i == p_playlist->i_all_size - 1 )
+                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 );
                     vlc_mutex_unlock( &p_playlist->object_lock );
@@ -684,8 +716,8 @@ NSLog( @"expandable" );
             {
                 o_real_filename = o_filename;
             }
-            playlist_Export( p_playlist, 
-                [o_real_filename fileSystemRepresentation], 
+            playlist_Export( p_playlist,
+                [o_real_filename fileSystemRepresentation],
                 p_playlist->p_local_category, "export-xspf" );
         }
         else
@@ -704,7 +736,7 @@ NSLog( @"expandable" );
             {
                 o_real_filename = o_filename;
             }
-            playlist_Export( p_playlist, 
+            playlist_Export( p_playlist,
                 [o_real_filename fileSystemRepresentation],
                 p_playlist->p_local_category, "export-m3u" );
         }
@@ -742,7 +774,7 @@ NSLog( @"expandable" );
                 p_item = NULL;
             }
         }
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, p_node, p_item );
+        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_node, p_item );
     }
     vlc_object_release( p_playlist );
 }
@@ -754,7 +786,7 @@ NSLog( @"expandable" );
     NSMutableArray *o_to_preparse;
     intf_thread_t * p_intf = VLCIntf;
     playlist_t * p_playlist = pl_Yield( p_intf );
-                                                       
     o_to_preparse = [NSMutableArray arrayWithArray:[[o_outline_view selectedRowEnumerator] allObjects]];
     i_count = [o_to_preparse count];
 
@@ -791,13 +823,13 @@ NSLog( @"expandable" );
     NSMenuItem *o_mi = (NSMenuItem *)sender;
     NSString *o_string = [o_mi representedObject];
     playlist_t * p_playlist = pl_Yield( VLCIntf );
-    if( !playlist_IsServicesDiscoveryLoaded( p_playlist, [o_string cString] ) )
-        playlist_ServicesDiscoveryAdd( p_playlist, [o_string cString] );
+    if( !playlist_IsServicesDiscoveryLoaded( p_playlist, [o_string UTF8String] ) )
+        playlist_ServicesDiscoveryAdd( p_playlist, [o_string UTF8String] );
     else
-        playlist_ServicesDiscoveryRemove( p_playlist, [o_string cString] );
+        playlist_ServicesDiscoveryRemove( p_playlist, [o_string UTF8String] );
 
     [o_mi setState: playlist_IsServicesDiscoveryLoaded( p_playlist,
-                                          [o_string cString] ) ? YES : NO];
+                                          [o_string UTF8String] ) ? YES : NO];
 
     vlc_object_release( p_playlist );
     [self playlistUpdated];
@@ -850,7 +882,7 @@ NSLog( @"expandable" );
         }
         else
         {
-            playlist_LockDelete( p_playlist, p_item->i_id );
+            playlist_DeleteFromInput( p_playlist, p_item->p_input->i_id, VLC_FALSE );
         }
     }
     [self playlistUpdated];
@@ -971,7 +1003,7 @@ NSLog( @"expandable" );
     {
         for( i = 0; i < (int)[o_options count]; i++ )
         {
-            vlc_input_item_AddOption( p_input, strdup( [[o_options objectAtIndex:i] UTF8String] ) );
+            input_ItemAddOption( p_input, strdup( [[o_options objectAtIndex:i] UTF8String] ) );
         }
     }
 
@@ -1006,20 +1038,21 @@ NSLog( @"expandable" );
         }
 
         /* Add the item */
-        playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_INSERT,
-                        i_position == -1 ? PLAYLIST_END : i_position + i_item );
+        playlist_AddInput( p_playlist, p_input, PLAYLIST_INSERT,
+             i_position == -1 ? PLAYLIST_END : i_position + i_item, VLC_TRUE,
+         VLC_FALSE );
 
         if( i_item == 0 && !b_enqueue )
         {
             playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input );
-            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, NULL, p_item );
+            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
+            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_item );
         }
         else
         {
             playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input );
-            playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item );
+            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
+            playlist_Control( p_playlist, PLAYLIST_SKIP, VLC_TRUE, p_item );
         }
     }
     [self playlistUpdated];
@@ -1048,68 +1081,26 @@ NSLog( @"expandable" );
        playlist_NodeAddInput( p_playlist, p_input, p_node,
                                       PLAYLIST_INSERT,
                                       i_position == -1 ?
-                                      PLAYLIST_END : i_position + i_item );
+                                      PLAYLIST_END : i_position + i_item, VLC_FALSE );
 
 
         if( i_item == 0 && !b_enqueue )
         {
             playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input );
-            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, NULL, p_item );
+            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
+            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_item );
         }
         else
         {
             playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input );
-            playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item );
+            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
+            playlist_Control( p_playlist, PLAYLIST_SKIP, VLC_TRUE, p_item );
         }
     }
     [self playlistUpdated];
     vlc_object_release( p_playlist );
 }
-/* FIXME!!
-- (IBAction)handlePopUp:(id)sender
-
-{
-    intf_thread_t * p_intf = VLCIntf;
-    vlc_value_t val1,val2;
-    playlist_t * p_playlist = pl_Yield( p_intf );
-
-    switch( [o_loop_popup indexOfSelectedItem] )
-    {
-        case 1:
 
-             val1.b_bool = 0;
-             var_Set( p_playlist, "loop", val1 );
-             val1.b_bool = 1;
-             var_Set( p_playlist, "repeat", val1 );
-             vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat One" ) );
-        break;
-
-        case 2:
-             val1.b_bool = 0;
-             var_Set( p_playlist, "repeat", val1 );
-             val1.b_bool = 1;
-             var_Set( p_playlist, "loop", val1 );
-             vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat All" ) );
-        break;
-
-        default:
-             var_Get( p_playlist, "repeat", &val1 );
-             var_Get( p_playlist, "loop", &val2 );
-             if( val1.b_bool || val2.b_bool )
-             {
-                  val1.b_bool = 0;
-                  var_Set( p_playlist, "repeat", val1 );
-                  var_Set( p_playlist, "loop", val1 );
-                  vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat Off" ) );
-             }
-         break;
-     }
-     vlc_object_release( p_playlist );
-     [self playlistUpdated];
-}
-*/
 - (NSMutableArray *)subSearchItem:(playlist_item_t *)p_item
 {
     playlist_t *p_playlist = pl_Yield( VLCIntf );
@@ -1131,7 +1122,7 @@ NSLog( @"expandable" );
         vlc_mutex_lock( &p_playlist->object_lock );
         o_current_name = [NSString stringWithUTF8String:
             p_item->pp_children[i_current]->p_input->psz_name];
-        psz_temp = vlc_input_item_GetInfo( p_item->p_input ,
+        psz_temp = input_ItemGetInfo( p_item->p_input ,
                    _("Meta-information"),_("Artist") );
         o_current_author = [NSString stringWithUTF8String: psz_temp];
         free( psz_temp);
@@ -1361,7 +1352,7 @@ NSLog( @"expandable" );
     /* we have to create a new thread here because otherwise we would block the
      * interface since the interaction-stuff and this code would run in the same
      * thread */
-    [NSThread detachNewThreadSelector: @selector(addNodeThreadedly) 
+    [NSThread detachNewThreadSelector: @selector(addNodeThreadedly)
         toTarget: self withObject:nil];
     [self playlistUpdated];
 }
@@ -1377,17 +1368,21 @@ NSLog( @"expandable" );
     int ret_v;
     char *psz_name = NULL;
     playlist_item_t * p_item;
-    ret_v = intf_UserStringInput( p_playlist, _("New Node"), 
+    ret_v = intf_UserStringInput( p_playlist, _("New Node"),
         _("Please enter a name for the new node."), &psz_name );
+
     if( psz_name != NULL && psz_name != "" )
-        p_item = playlist_NodeCreate( p_playlist, psz_name, 
-                                            p_playlist->p_local_category );
-    else
-        p_item = playlist_NodeCreate( p_playlist, _("Empty Folder"), 
-                                            p_playlist->p_local_category );
+        p_item = playlist_NodeCreate( p_playlist, psz_name,
+                                            p_playlist->p_local_category, 0 );
+    else if(! config_GetInt( p_playlist, "interact" ) )
+    {
+        /* in case that the interaction is disabled, just give it a bogus name */
+        p_item = playlist_NodeCreate( p_playlist, _("Empty Folder"),
+                                            p_playlist->p_local_category, 0 );
+    }
 
     if(! p_item )
-        msg_Warn( VLCIntf, "node creation failed" );
+        msg_Warn( VLCIntf, "node creation failed or cancelled by user" );
 
     vlc_object_release( p_playlist );
     [ourPool release];
@@ -1402,17 +1397,15 @@ NSLog( @"expandable" );
     id o_value = [super outlineView: outlineView child: index ofItem: item];
     playlist_t *p_playlist = pl_Yield( VLCIntf );
 
-    /* FIXME: playlist->i_size doesn't provide the correct number of items anymore
-     * check the playlist API for the fixed function, once zorglub implemented it -- fpk, 9/17/06 */
-
-    if( p_playlist->i_size >= 2 )
+    if( playlist_CurrentSize( p_playlist )  >= 2 )
     {
         [o_status_field setStringValue: [NSString stringWithFormat:
-                    _NS("%i items in the playlist"), p_playlist->i_size]];
+                    _NS("%i items in the playlist"),
+             playlist_CurrentSize( p_playlist )]];
     }
     else
     {
-        if( p_playlist->i_size == 0 )
+        if( playlist_IsEmpty( p_playlist ) )
         {
             [o_status_field setStringValue: _NS("No items in the playlist")];
         }
@@ -1494,6 +1487,13 @@ NSLog( @"expandable" );
         }
     }
 
+    /* Don't allow on drop on playlist root element's child */
+    if( !item && index != NSOutlineViewDropOnItemIndex)
+    {
+        vlc_object_release( p_playlist );
+        return NSDragOperationNone;
+    }
+
     /* We refuse to drop an item in anything else than a child of the General
        Node. We still accept items that would be root nodes of the outlineview
        however, to allow drop in an empty playlist. */