]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/playlist.m
* backport of [11511] [11512] and [11513]
[vlc] / modules / gui / macosx / playlist.m
index 28b5b395d1d6a48b7dbbcc7b4c5ef05328c8ddbf..700eeda8d48ee699356b21f3495f0c0fb6ded768 100644 (file)
             [[self delegate] deleteItem:self];
             break;
 
+        case NSEnterCharacter:
+        case NSCarriageReturnCharacter:
+            [(VLCPlaylist *)[[VLCMain sharedInstance] getPlaylist]
+                                                            playItem:self];
+            break;
+
         default:
             [super keyDown: o_event];
             break;
@@ -187,10 +193,36 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     vlc_list_release( p_list );
     vlc_object_release( p_playlist );
 
+    /* Change the simple textfield into a searchField if we can... */
+#if 0
+    if( MACOS_VERSION >= 10.3 )
+    {
+        NSView *o_parentview = [o_status_field superview];
+        NSSearchField *o_better_search_field = [[NSSearchField alloc]initWithFrame:[o_search_field frame]];
+        [o_better_search_field setRecentsAutosaveName:@"VLC media player search"];
+        [o_better_search_field setDelegate:self];
+        [[NSNotificationCenter defaultCenter] addObserver: self
+            selector: @selector(searchfieldChanged:)
+            name: NSControlTextDidChangeNotification
+            object: o_better_search_field];
+
+        [o_better_search_field setTarget:self];
+        [o_better_search_field setAction:@selector(searchItem:)];
+
+        [o_better_search_field setAutoresizingMask:NSViewMinXMargin];
+        [o_parentview addSubview:o_better_search_field];
+        [o_search_field setHidden:YES];
+    }
+#endif
     [self initStrings];
     //[self playlistUpdated];
 }
 
+- (void)searchfieldChanged:(NSNotification *)o_notification
+{
+    [o_search_field setStringValue:[[o_notification object] stringValue]];
+}
+
 - (void)initStrings
 {
     [o_mi_save_playlist setTitle: _NS("Save Playlist...")];
@@ -211,6 +243,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 #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")];
@@ -320,44 +353,45 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     vlc_object_release(p_playlist);
 }
 
+- (BOOL)isValueItem: (id)o_item inNode: (id)o_node
+{
+    int i;
+    int i_total = [[o_outline_view dataSource] outlineView:o_outline_view
+                                        numberOfChildrenOfItem: o_node];
+    for( i = 0 ; i < i_total ; i++ )
+    {
+        id o_temp_item = [[o_outline_view dataSource] outlineView:
+                                    o_outline_view child:i ofItem: o_node];
+        if( [[o_outline_view dataSource] outlineView:o_outline_view
+                                    numberOfChildrenOfItem: o_temp_item] > 0 )
+        {
+            if( [self isValueItem: o_item inNode: o_temp_item] == YES )
+            return YES;
+        }
+        else if( [o_temp_item isEqual: o_item] )
+        {
+            return YES;
+        }
+    }
+    return NO;
+}
 
-- (BOOL)isItem: (playlist_item_t *)p_item inNode: (playlist_item_t *)p_node
+- (IBAction)savePlaylist:(id)sender
 {
-    playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
-                                          FIND_ANYWHERE );
-    playlist_item_t *p_temp_item = p_item;
+    intf_thread_t * p_intf = VLCIntf;
+    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+                                                       FIND_ANYWHERE );
 
-    if( p_playlist == NULL )
-    {
-        return NO;
-    }
+    NSSavePanel *o_save_panel = [NSSavePanel savePanel];
+    NSString * o_name = [NSString stringWithFormat: @"%@.m3u", _NS("Untitled")];
+    [o_save_panel setTitle: _NS("Save Playlist")];
+    [o_save_panel setPrompt: _NS("Save")];
 
-    if ( p_temp_item )
+    if( [o_save_panel runModalForDirectory: nil
+            file: o_name] == NSOKButton )
     {
-        while( p_temp_item->i_parents > 0 )
-        {
-            int i;
-            for( i = 0; i < p_temp_item->i_parents ; i++ )
-            {
-                if( p_temp_item->pp_parents[i]->i_view == i_current_view )
-                {
-                    if( p_temp_item->pp_parents[i]->p_parent == p_node )
-                    {
-                        vlc_object_release( p_playlist );
-                        return YES;
-                    }
-                    else
-                    {
-                        p_temp_item = p_temp_item->pp_parents[i]->p_parent;
-                        break;
-                    }
-                }
-            }
-        }
+        playlist_Export( p_playlist, [[o_save_panel filename] fileSystemRepresentation], "export-m3u" );
     }
-
-    vlc_object_release( p_playlist );
-    return NO;
 }
 
 
@@ -453,24 +487,28 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 
     for( i = 0; i < i_count; i++ )
     {
-        playlist_item_t * p_item;
         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];
 
-        p_item = (playlist_item_t *)[[o_outline_view itemAtRow: i_row] pointerValue];
-
-        if( p_item->i_children > -1 ) //is a node and not an item
+        if( [[o_outline_view dataSource] outlineView:o_outline_view
+                                        numberOfChildrenOfItem: o_item]  > 0 )
+        //is a node and not an item
         {
+            id o_playing_item = [o_outline_dict objectForKey:
+                [NSString stringWithFormat: @"%p", p_playlist->status.p_item]];
             if( p_playlist->status.i_status != PLAYLIST_STOPPED &&
-                [self isItem: p_playlist->status.p_item inNode: p_item] == YES )
+                [self isValueItem: o_playing_item inNode: o_item] == 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
         {
@@ -479,7 +517,9 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
             {
                 playlist_Stop( p_playlist );
             }
-            playlist_LockDelete( p_playlist, p_item->input.i_id );
+            vlc_mutex_lock( &p_playlist->object_lock );
+            playlist_Delete( p_playlist, p_item->input.i_id );
+            vlc_mutex_unlock( &p_playlist->object_lock );
         }
     }
     [self playlistUpdated];
@@ -779,7 +819,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         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") );
+                   _("Meta-information"),_("Artist") );
         o_current_author = [NSString stringWithUTF8String: psz_temp];
         free( psz_temp);
         vlc_mutex_unlock( &p_playlist->object_lock );
@@ -838,7 +878,6 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 
     if( p_playlist == NULL )
         return;
-
     p_view = playlist_ViewFind( p_playlist, i_current_view );
 
     if( p_view )
@@ -853,7 +892,14 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         }
         if( o_result != NULL )
         {
-            for( i = 0 ; i < [o_result count] - 1 ; i++ )
+            int i_start;
+            if( [[o_result objectAtIndex: 0] pointerValue] ==
+                                                    p_playlist->p_general )
+            i_start = 1;
+            else
+            i_start = 0;
+
+            for( i = i_start ; i < [o_result count] - 1 ; i++ )
             {
                 [o_outline_view expandItem: [o_outline_dict objectForKey:
                             [NSString stringWithFormat: @"%p",
@@ -912,7 +958,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     {
         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 ) )
@@ -980,13 +1026,16 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 {
     playlist_t *p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
                                           FIND_ANYWHERE );
-    playlist_item_t *p_item = (playlist_item_t *)[item pointerValue];
+
+    id o_playing_item;
 
     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] ) )
+    o_playing_item = [o_outline_dict objectForKey:
+                [NSString stringWithFormat:@"%p",  p_playlist->status.p_item]];
+
+    if( [self isValueItem: o_playing_item inNode: item] ||
+                                                [o_playing_item isEqual: item] )
     {
         [cell setFont: [NSFont boldSystemFontOfSize: 0]];
     }
@@ -1016,7 +1065,14 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         playlist_view_t *p_view;
         p_view = playlist_ViewFind( p_playlist, i_current_view );
         if( p_view && p_view->p_root )
+        {
             i_return = p_view->p_root->i_children;
+            if( i_current_view == VIEW_CATEGORY )
+            {
+                i_return--; /* remove the GENERAL item from the list */
+                i_return += p_playlist->p_general->i_children; /* add the items of the general node */
+            }
+        }
     }
     else
     {
@@ -1048,8 +1104,20 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         /* root object */
         playlist_view_t *p_view;
         p_view = playlist_ViewFind( p_playlist, i_current_view );
-        if( p_view && index < p_view->p_root->i_children && index >= 0 )
-            p_return = p_view->p_root->pp_children[index];
+        if( p_view && p_view->p_root ) p_return = p_view->p_root->pp_children[index];
+        
+        if( i_current_view == VIEW_CATEGORY )
+        {
+            if( p_playlist->p_general->i_children && index >= 0 && index < p_playlist->p_general->i_children )
+            {
+                p_return = p_playlist->p_general->pp_children[index];
+            }
+            else if( p_view && p_view->p_root && index >= 0 && index - p_playlist->p_general->i_children < p_view->p_root->i_children )
+            {
+                p_return = p_view->p_root->pp_children[index - p_playlist->p_general->i_children + 1];
+                
+            }
+        }
     }
     else
     {
@@ -1099,8 +1167,13 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         /* root object */
         playlist_view_t *p_view;
         p_view = playlist_ViewFind( p_playlist, i_current_view );
-        if( p_view && p_view->p_root )
-            i_return = p_view->p_root->i_children;
+        if( p_view && p_view->p_root ) i_return = p_view->p_root->i_children;
+        
+        if( i_current_view == VIEW_CATEGORY )
+        {
+            i_return--;
+            i_return += p_playlist->p_general->i_children;
+        }
     }
     else
     {