]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/playlist.m
macosx: Use pl_Locked for better readability.
[vlc] / modules / gui / macosx / playlist.m
index 09c3c13bfa5b6f060f2f998dd5322f733cf7ecc4..57bd2b95c13b931fe9f33792d061c0ecf9143750 100644 (file)
@@ -92,7 +92,6 @@
 
 @end
 
-
 /*****************************************************************************
  * VLCPlaylistCommon implementation
  *
     [o_outline_view setTarget: self];
     [o_outline_view setDelegate: self];
     [o_outline_view setDataSource: self];
+    [o_outline_view setAllowsEmptySelection: NO];
 
     vlc_object_release( p_playlist );
     [self initStrings];
     int i_return = 0;
     playlist_item_t *p_item = NULL;
     playlist_t * p_playlist = pl_Yield( VLCIntf );
-    if( outlineView != o_outline_view )
-    {
-        vlc_object_release( p_playlist );
-        return 0;
-    }
+    assert( outlineView == o_outline_view );
 
-    if( item == nil )
-    {
-        /* root object */
+    if( !item )
         p_item = p_playlist->p_root_category;
-    }
     else
-    {
         p_item = (playlist_item_t *)[item pointerValue];
-    }
+
     if( p_item )
         i_return = p_item->i_children;
-    vlc_object_release( p_playlist );
+
+    pl_Release( VLCIntf );
 
     return i_return > 0 ? i_return : 0;
 }
         else
         {
             char *psz_name = input_item_GetName( p_item->p_input );
-            if( psz_name != NULL )
+            if( !EMPTY_STR( psz_name ) )
             {
                 o_value = [NSString stringWithUTF8String: psz_name];
             }
             }
             else
             {
-                o_value = @"-:--:--";
+                o_value = @"--:--";
             }
         }
         free( psz_artist );
     }
-
-    return( o_value );
+    return o_value;
 }
 
 @end
         @"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.5.
      * We need to keep checking in the future!
      * These methods are being added artificially to NSOutlineView's interface above */
     o_ascendingSortingImage = [[NSOutlineView class] _defaultTableHeaderSortImage];
     
     for( i = 0; ppsz_services[i]; i++ )
     {
-        vlc_bool_t  b_enabled;
-        char        *objectname;
+        bool  b_enabled;
         NSMenuItem  *o_lmi;
 
         char * name = ppsz_name[i] ? ppsz_name[i] : ppsz_services[i];
         /* Check whether to enable these menuitems */
-        b_enabled = playlist_IsServicesDiscoveryLoaded( p_playlist, objectname );
+        b_enabled = playlist_IsServicesDiscoveryLoaded( p_playlist, ppsz_services[i] );
 
         /* Create the menu entries used in the playlist menu */
         o_lmi = [[o_mi_services submenu] addItemWithTitle:
     [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_info setTitle: _NS("Information...")];
+    [o_mi_preparse setTitle: _NS("Fetch Meta Data")];
     [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")];
 
 - (void)playlistUpdated
 {
-    unsigned int i;
-
     /* Clear indications of any existing column sorting */
-    for( i = 0 ; i < [[o_outline_view tableColumns] count] ; i++ )
+    for( unsigned int i = 0 ; i < [[o_outline_view tableColumns] count] ; i++ )
     {
         [o_outline_view setIndicatorImage:nil inTableColumn:
                             [[o_outline_view tableColumns] objectAtIndex:i]];
     if( playlist_CurrentSize( p_playlist ) >= 2 )
     {
         [o_status_field setStringValue: [NSString stringWithFormat:
-                    _NS("%i items in the playlist"),
+                    _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 in the playlist")];
+            [o_status_field setStringValue: _NS("1 item")];
     }
     vlc_object_release( p_playlist );
 }
 - (void)playModeUpdated
 {
     playlist_t *p_playlist = pl_Yield( VLCIntf );
-    vlc_value_t val, val2;
 
-    var_Get( p_playlist, "loop", &val2 );
-    var_Get( p_playlist, "repeat", &val );
-    if( val.b_bool == VLC_TRUE )
-    {
+    bool loop = var_GetBool( p_playlist, "loop" );
+    bool repeat = var_GetBool( p_playlist, "repeat" );
+    if( repeat )
         [[[VLCMain sharedInstance] getControls] repeatOne];
-   }
-    else if( val2.b_bool == VLC_TRUE )
-    {
+    else if( loop )
         [[[VLCMain sharedInstance] getControls] repeatAll];
-    }
     else
-    {
         [[[VLCMain sharedInstance] getControls] repeatOff];
-    }
 
     [[[VLCMain sharedInstance] getControls] shuffle];
 
     vlc_object_release( p_playlist );
 }
 
+- (void)outlineViewSelectionDidChange:(NSNotification *)notification
+{
+    // FIXME: unsafe
+    playlist_item_t * p_item = [[o_outline_view itemAtRow:[o_outline_view selectedRow]] pointerValue];
+
+    if( p_item )
+    {
+        /* update our info-panel to reflect the new item */
+        [[[VLCMain sharedInstance] getInfo] updatePanelWithItem:p_item->p_input];
+    }
+}
+
+- (BOOL)isSelectionEmpty
+{
+    return [o_outline_view selectedRow] == -1;
+}
+
 - (void)updateRowSelection
 {
     int i_row;
     unsigned int j;
 
+    // FIXME: unsafe
     playlist_t *p_playlist = pl_Yield( VLCIntf );
     playlist_item_t *p_item, *p_temp_item;
     NSMutableArray *o_array = [NSMutableArray array];
 
     }
 
+    /* update our info-panel to reflect the new item */
+    [[[VLCMain sharedInstance] getInfo] updatePanelWithItem:p_item->p_input];
+
     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
+                    locked:(BOOL)b_locked
 
 {
     playlist_t * p_playlist = pl_Yield( VLCIntf );
     if ( p_temp_item )
     {
         int i;
-        vlc_mutex_lock( &p_playlist->object_lock );
+        if(!b_locked) PL_LOCK;
 
         if( b_check )
         {
                 if( ARRAY_VAL( p_playlist->all_items, i) == p_item ) break;
                 else if ( i == p_playlist->all_items.i_size - 1 )
                 {
+                    if(!b_locked) PL_UNLOCK;
                     vlc_object_release( p_playlist );
-                    vlc_mutex_unlock( &p_playlist->object_lock );
                     return NO;
                 }
             }
             p_temp_item = p_temp_item->p_parent;
             if( p_temp_item == p_node )
             {
-                 vlc_mutex_unlock( &p_playlist->object_lock );
-                 vlc_object_release( p_playlist );
-                 return YES;
+                if(!b_locked) PL_UNLOCK;
+                vlc_object_release( p_playlist );
+                return YES;
             }
         }
-        vlc_mutex_unlock( &p_playlist->object_lock );
+        if(!b_locked) PL_UNLOCK;
     }
 
     vlc_object_release( p_playlist );
     return NO;
 }
 
+- (BOOL)isItem: (playlist_item_t *)p_item
+                    inNode: (playlist_item_t *)p_node
+                    checkItemExistence:(BOOL)b_check
+{
+    [self isItem:p_item inNode:p_node checkItemExistence:b_check locked: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
             }
             if( [self isItem: [[o_items objectAtIndex:i] pointerValue]
                     inNode: [[o_nodes objectAtIndex:j] pointerValue]
-                    checkItemExistence: NO] )
+                    checkItemExistence: NO locked:NO] )
             {
                 [o_items removeObjectAtIndex:i];
                 /* We need to execute the next iteration with the same index
                 p_item = NULL;
             }
         }
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, p_node, p_item );
+        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Unlocked, p_node, p_item );
     }
     vlc_object_release( p_playlist );
 }
             if( p_playlist->status.i_status != PLAYLIST_STOPPED &&
                 [self isItem: p_playlist->status.p_item inNode:
                         ((playlist_item_t *)[o_item pointerValue])
-                        checkItemExistence: NO] == YES )
+                        checkItemExistence: NO locked:YES] == YES )
                 // if current item is in selected node and is playing then stop playlist
                 playlist_Stop( p_playlist );
     
-            playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
+            playlist_NodeDelete( p_playlist, p_item, true, false );
         }
         else
-            playlist_DeleteFromInput( p_playlist, p_item->p_input->i_id, VLC_TRUE );
+            playlist_DeleteFromInput( p_playlist, p_item->p_input->i_id, pl_Locked );
     }
     PL_UNLOCK;
 
 
     if( p_item->i_children > -1 ) // the item is a node
     {
-        vlc_mutex_lock( &p_playlist->object_lock );
+        PL_LOCK;
         playlist_RecursiveNodeSort( p_playlist, p_item, i_mode, ORDER_NORMAL );
-        vlc_mutex_unlock( &p_playlist->object_lock );
+        PL_UNLOCK;
     }
     else
     {
-        vlc_mutex_lock( &p_playlist->object_lock );
+        PL_LOCK;
         playlist_RecursiveNodeSort( p_playlist,
                 p_item->p_parent, i_mode, ORDER_NORMAL );
-        vlc_mutex_unlock( &p_playlist->object_lock );
+        PL_UNLOCK;
     }
     vlc_object_release( p_playlist );
     [self playlistUpdated];
     int i_item;
     playlist_t * p_playlist = pl_Yield( VLCIntf );
 
+    PL_LOCK;
     for( i_item = 0; i_item < (int)[o_array count]; i_item++ )
     {
         input_item_t *p_input;
 
         /* Add the item */
         /* FIXME: playlist_AddInput() can fail */
+        
         playlist_AddInput( p_playlist, p_input, PLAYLIST_INSERT,
-             i_position == -1 ? PLAYLIST_END : i_position + i_item, VLC_TRUE,
-         VLC_FALSE );
+             i_position == -1 ? PLAYLIST_END : i_position + i_item, true,
+         pl_Locked );
 
         if( i_item == 0 && !b_enqueue )
         {
             playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
-            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, NULL, p_item );
-        }
-        else
-        {
-            playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
-            playlist_Control( p_playlist, PLAYLIST_SKIP, VLC_TRUE, p_item );
+            p_item = playlist_ItemGetByInput( p_playlist, p_input, pl_Locked );
+            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, NULL, p_item );
         }
         vlc_gc_decref( p_input );
     }
+    PL_UNLOCK;
+
     [self playlistUpdated];
     vlc_object_release( p_playlist );
 }
         /* Get the item */
         o_one_item = [o_array objectAtIndex: i_item];
         p_input = [self createItem: o_one_item];
-        if( !p_input )
-        {
-            continue;
-        }
+
+        if( !p_input ) continue;
 
         /* Add the item */
-        /* FIXME: playlist_NodeAddInput() can fail */
-       playlist_NodeAddInput( p_playlist, p_input, p_node,
+        /* FIXME: playlist_BothAddInput() can fail */
+        PL_LOCK;
+        playlist_BothAddInput( p_playlist, p_input, p_node,
                                       PLAYLIST_INSERT,
                                       i_position == -1 ?
-                                      PLAYLIST_END : i_position + i_item, VLC_FALSE );
+                                      PLAYLIST_END : i_position + i_item,
+                                      NULL, NULL, pl_Locked );
 
 
         if( i_item == 0 && !b_enqueue )
         {
             playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
-            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, NULL, p_item );
-        }
-        else
-        {
-            playlist_item_t *p_item;
-            p_item = playlist_ItemGetByInput( p_playlist, p_input, VLC_TRUE );
-            playlist_Control( p_playlist, PLAYLIST_SKIP, VLC_TRUE, p_item );
+            p_item = playlist_ItemGetByInput( p_playlist, p_input, pl_Locked );
+            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, NULL, p_item );
         }
+        PL_UNLOCK;
         vlc_gc_decref( p_input );
     }
     [self playlistUpdated];
         char *psz_temp;
         NSString *o_current_name, *o_current_author;
 
-        vlc_mutex_lock( &p_playlist->object_lock );
+        PL_LOCK;
         o_current_name = [NSString stringWithUTF8String:
             p_item->pp_children[i_current]->p_input->psz_name];
         psz_temp = input_ItemGetInfo( p_item->p_input ,
                    _("Meta-information"),_("Artist") );
         o_current_author = [NSString stringWithUTF8String: psz_temp];
         free( psz_temp);
-        vlc_mutex_unlock( &p_playlist->object_lock );
+        PL_UNLOCK;
 
         if( p_selected_item == p_item->pp_children[i_current] &&
                     b_selected_item_met == NO )
         }
         else if( b_selected_item_met == YES &&
                     ( [o_current_name rangeOfString:[o_search_field
-                        stringValue] options:NSCaseInsensitiveSearch ].length ||
+                        stringValue] options:NSCaseInsensitiveSearch].length ||
                       [o_current_author rangeOfString:[o_search_field
-                        stringValue] options:NSCaseInsensitiveSearch ].length ) )
+                        stringValue] options:NSCaseInsensitiveSearch].length ) )
         {
             vlc_object_release( p_playlist );
             /*Adds the parent items in the result array as well, so that we can
 - (NSMenu *)menuForEvent:(NSEvent *)o_event
 {
     NSPoint pt;
-    vlc_bool_t b_rows;
-    vlc_bool_t b_item_sel;
+    bool b_rows;
+    bool 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 );
+    NSInteger row = [o_outline_view rowAtPoint:pt];
+    if( row != -1 )
+        [o_outline_view selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
+
+    b_item_sel = ( row != -1 && [o_outline_view selectedRow] != -1 );
     b_rows = [o_outline_view numberOfRows] != 0;
 
     [o_mi_play setEnabled: b_item_sel];
     }
     else
     {
-        b_isSortDescending = VLC_FALSE;
+        b_isSortDescending = false;
     }
 
     if( o_tc == o_tc_name )
         i_type = ORDER_NORMAL;
     }
 
-    vlc_mutex_lock( &p_playlist->object_lock );
+    vlc_object_lock( p_playlist );
     playlist_RecursiveNodeSort( p_playlist, p_playlist->p_root_category, i_mode, i_type );
-    vlc_mutex_unlock( &p_playlist->object_lock );
+    vlc_object_unlock( p_playlist );
 
     vlc_object_release( p_playlist );
     [self playlistUpdated];
                         [item pointerValue] checkItemExistence: YES]
                         || [o_playing_item isEqual: item] )
     {
-        [cell setFont: [NSFont boldSystemFontOfSize: 0]];
+        [cell setFont: [[NSFontManager sharedFontManager] convertFont:[cell font] toHaveTrait:NSBoldFontMask]];
     }
     else
     {
-        [cell setFont: [NSFont systemFontOfSize: 0]];
+        [cell setFont: [[NSFontManager sharedFontManager] convertFont:[cell font] toNotHaveTrait:NSBoldFontMask]];
     }
     vlc_object_release( p_playlist );
 }
     ret_v = intf_UserStringInput( p_playlist, _("New Node"),
         _("Please enter a name for the new node."), &psz_name );
 
-    if( psz_name != NULL && psz_name != "" )
+    if( ret_v != DIALOG_CANCELLED && psz_name && *psz_name )
         p_item = playlist_NodeCreate( p_playlist, psz_name,
                                       p_playlist->p_local_category, 0, NULL );
     else if(! config_GetInt( p_playlist, "interact" ) )
     if( playlist_CurrentSize( p_playlist )  >= 2 )
     {
         [o_status_field setStringValue: [NSString stringWithFormat:
-                    _NS("%i items in the playlist"),
+                    _NS("%i items"),
              playlist_CurrentSize( p_playlist )]];
     }
     else
         }
         else
         {
-            [o_status_field setStringValue: _NS("1 item in the playlist")];
+            [o_status_field setStringValue: _NS("1 item")];
         }
     }
     vlc_object_release( p_playlist );
 
     [o_outline_dict setObject:o_value forKey:[NSString stringWithFormat:@"%p",
                                                     [o_value pointerValue]]];
-#ifndef NDEBUG
-    msg_Dbg( VLCIntf, "adding item %p", [o_value pointerValue] );
-#endif
     return o_value;
 
 }
                 }
             }
 
-            vlc_mutex_lock( &p_playlist->object_lock );
-            // Acually detach the item from the old position
+            PL_LOCK;
+            // Actually detach the item from the old position
             if( playlist_NodeRemoveItem( p_playlist, p_item, p_old_parent ) ==
                 VLC_SUCCESS )
             {
                 // Reattach the item to the new position
                 playlist_NodeInsert( p_playlist, p_item, p_new_parent, i_new_index );
             }
-            vlc_mutex_unlock( &p_playlist->object_lock );
+            PL_UNLOCK;
         }
         [self playlistUpdated];
         i_row = [o_outline_view rowForItem:[o_outline_dict
 
         if ( item == nil )
         {
-            [self appendArray: o_array atPos: index enqueue: YES];
-        }
-        /* This should never occur */
-        else if( p_node->i_children == -1 )
-        {
-            vlc_object_release( p_playlist );
-            return NO;
+            [self appendArray:o_array atPos:index enqueue: YES];
         }
         else
         {
-            [self appendNodeArray: o_array inNode: p_node
-                atPos: index enqueue: YES];
+            assert( p_node->i_children != -1 );
+            [self appendNodeArray:o_array inNode: p_node
+                atPos:index enqueue:YES];
         }
         vlc_object_release( p_playlist );
         return YES;