]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/playlist.m
* Support for saving xspf playlist files
[vlc] / modules / gui / macosx / playlist.m
index e650989125261849ee179be9e47f843afc621347..4cada240cc6e10ef36e5cb305120e979b397b07e 100644 (file)
@@ -20,7 +20,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /* TODO
@@ -47,6 +47,7 @@
 #include "intf.h"
 #import "wizard.h"
 #import "bookmarks.h"
+#import "playlistinfo.h"
 #include "playlist.h"
 #include "controls.h"
 #include "vlc_osd.h"
         o_outline_dict = [[NSMutableDictionary alloc] init];
     }
     return self;
-}        
+}
 - (void)awakeFromNib
 {
     playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
@@ -463,27 +464,6 @@ 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 playlistUpdated];
 }
 
@@ -501,8 +481,8 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     [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("Properties")];
-    [o_mi_preparse setTitle: _NS("Preparse")];
+    [o_mi_info setTitle: _NS("Information")];
+    [o_mi_preparse setTitle: _NS("Get Stream Information")];
     [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")];
@@ -517,13 +497,18 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     [[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")];
+    [o_mi_addNode setTitle: _NS("Add Folder to Playlist")];
+
+    [o_save_accessory_text setStringValue: _NS("File Format:")];
+    [[o_save_accessory_popup itemAtIndex:0] setTitle: _NS("Extended M3U")];
+    [[o_save_accessory_popup itemAtIndex:1] setTitle: _NS("XML Shareable Playlist Format (XSPF)")];
 }
 
 - (void)playlistUpdated
 {
     unsigned int i;
 
-    /* Clear indications of any existing column sorting*/
+    /* Clear indications of any existing column sorting */
     for( i = 0 ; i < [[o_outline_view tableColumns] count] ; i++ )
     {
         [o_outline_view setIndicatorImage:nil inTableColumn:
@@ -637,6 +622,9 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     [o_outline_view scrollRowToVisible: i_row];
 
     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
@@ -761,19 +749,58 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
                                                        FIND_ANYWHERE );
 
     NSSavePanel *o_save_panel = [NSSavePanel savePanel];
-    NSString * o_name = [NSString stringWithFormat: @"%@.m3u", _NS("Untitled")];
+    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 )
     {
-        playlist_Export( p_playlist, [[o_save_panel filename] fileSystemRepresentation], "export-m3u" );
+        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], "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], "export-m3u" );
+        }
     }
     vlc_object_release( p_playlist );
 }
 
-
 /* When called retrieves the selected outlineview row and plays that node or item */
 - (IBAction)playItem:(id)sender
 {
@@ -1494,6 +1521,27 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     vlc_object_release( p_playlist );
 }
 
+- (IBAction)addNode:(id)sender
+{
+    /* simply adds a new node to the end of the playlist */
+    playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
+                                          FIND_ANYWHERE );
+    if( !p_playlist )
+    {
+        return;
+    }
+
+    playlist_item_t * p_item = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, 
+        _("Empty Folder"), p_playlist->p_general );
+
+    if(! p_item )
+        msg_Warn( VLCIntf, "node creation failed" );
+    
+    playlist_ViewUpdate( p_playlist, VIEW_CATEGORY );
+    
+    vlc_object_release( p_playlist );
+}
+
 @end
 
 @implementation VLCPlaylist (NSOutlineViewDataSource)
@@ -1657,10 +1705,8 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         /* If the item is to be dropped as root item of the outline, make it a
            child of the General node.
            Else, choose the proposed parent as parent. */
-        if( item == nil )
-        p_new_parent = p_playlist->p_general;
-        else
-        p_new_parent = [item pointerValue];
+        if( item == nil ) p_new_parent = p_playlist->p_general;
+        else p_new_parent = [item pointerValue];
 
         /* Make sure the proposed parent is a node.
            (This should never be true) */
@@ -1709,8 +1755,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
                 else
                 {
                     if ((p_new_parent == p_old_parent &&
-                                   i_old_index < index + (int)i)
-                                   || p_new_parent == p_playlist->p_general )
+                                   i_old_index < index + (int)i) )
                     {
                         i_removed_from_node++;
                     }