macosx: Rename the Playlist related class files to match the class name
authorMarvin Scholz <epirat07@gmail.com>
Fri, 9 Oct 2015 16:02:58 +0000 (18:02 +0200)
committerFelix Paul Kühne <fkuehne@videolan.org>
Mon, 12 Oct 2015 14:46:00 +0000 (16:46 +0200)
This renames the playlist related class files to match the class name,
which makes it easier to find the which belongs to a certain class and
follows common Cocoa/Obj C file naming conventions.

Signed-off-by: Felix Paul Kühne <fkuehne@videolan.org>
26 files changed:
extras/package/macosx/vlc.xcodeproj/project.pbxproj
modules/gui/macosx/ControlsBar.m
modules/gui/macosx/ConvertAndSave.m
modules/gui/macosx/CoreInteraction.m
modules/gui/macosx/InputManager.m
modules/gui/macosx/MainMenu.m
modules/gui/macosx/MainWindow.m
modules/gui/macosx/Makefile.am
modules/gui/macosx/PLModel.m
modules/gui/macosx/VLCPlaylist.h [new file with mode: 0644]
modules/gui/macosx/VLCPlaylist.m [new file with mode: 0644]
modules/gui/macosx/VLCPlaylistInfo.h [new file with mode: 0644]
modules/gui/macosx/VLCPlaylistInfo.m [new file with mode: 0644]
modules/gui/macosx/VLCPlaylistView.h [new file with mode: 0644]
modules/gui/macosx/VLCPlaylistView.m [new file with mode: 0644]
modules/gui/macosx/VLCVoutWindowController.m
modules/gui/macosx/applescript.m
modules/gui/macosx/intf.m
modules/gui/macosx/open.m
modules/gui/macosx/playlist.h [deleted file]
modules/gui/macosx/playlist.m [deleted file]
modules/gui/macosx/playlistinfo.h [deleted file]
modules/gui/macosx/playlistinfo.m [deleted file]
modules/gui/macosx/playlistview.h [deleted file]
modules/gui/macosx/playlistview.m [deleted file]
po/POTFILES.in

index 850bfee..fa0ed11 100644 (file)
                1CCB5F7A1A62A724004C3E90 /* open.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED6C28203E2EB1C0059A3A7 /* open.m */; };
                1CCB5F7B1A62A724004C3E90 /* output.h in Sources */ = {isa = PBXBuildFile; fileRef = 8E55FB7F0459B0FD00FB3317 /* output.h */; };
                1CCB5F7C1A62A724004C3E90 /* output.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E55FB800459B0FD00FB3317 /* output.m */; };
-               1CCB5F7D1A62A724004C3E90 /* playlist.h in Sources */ = {isa = PBXBuildFile; fileRef = 8ED6C28303E2EB1C0059A3A7 /* playlist.h */; };
-               1CCB5F7E1A62A724004C3E90 /* playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED6C28403E2EB1C0059A3A7 /* playlist.m */; };
-               1CCB5F7F1A62A724004C3E90 /* playlistinfo.h in Sources */ = {isa = PBXBuildFile; fileRef = 8E49720006417F6800370C9F /* playlistinfo.h */; };
-               1CCB5F801A62A724004C3E90 /* playlistinfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E49720106417F6800370C9F /* playlistinfo.m */; };
+               1CCB5F7D1A62A724004C3E90 /* VLCPlaylist.h in Sources */ = {isa = PBXBuildFile; fileRef = 8ED6C28303E2EB1C0059A3A7 /* VLCPlaylist.h */; };
+               1CCB5F7E1A62A724004C3E90 /* VLCPlaylist.m in Sources */ = {isa = PBXBuildFile; fileRef = 8ED6C28403E2EB1C0059A3A7 /* VLCPlaylist.m */; };
+               1CCB5F7F1A62A724004C3E90 /* VLCPlaylistInfo.h in Sources */ = {isa = PBXBuildFile; fileRef = 8E49720006417F6800370C9F /* VLCPlaylistInfo.h */; };
+               1CCB5F801A62A724004C3E90 /* VLCPlaylistInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E49720106417F6800370C9F /* VLCPlaylistInfo.m */; };
                1CCB5F811A62A724004C3E90 /* prefs_widgets.h in Sources */ = {isa = PBXBuildFile; fileRef = 8E9CA1A306D7DEE800B7186C /* prefs_widgets.h */; };
                1CCB5F821A62A724004C3E90 /* prefs_widgets.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9CA1A406D7DEE800B7186C /* prefs_widgets.m */; };
                1CCB5F831A62A724004C3E90 /* prefs.h in Sources */ = {isa = PBXBuildFile; fileRef = 8ED6C28503E2EB1C0059A3A7 /* prefs.h */; };
                7D8BB0B61830311300FAE9B7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/DebugMessageVisualizer.xib; sourceTree = "<group>"; };
                7D8BB0B91830367200FAE9B7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/PlaylistMenu.xib; sourceTree = "<group>"; };
                7D8BB0BF1830393300FAE9B7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/MainWindow.xib; sourceTree = "<group>"; };
-               7DA481221B5FC13700917FD7 /* playlistview.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = playlistview.h; path = ../../../modules/gui/macosx/playlistview.h; sourceTree = "<group>"; };
-               7DA481231B5FC13700917FD7 /* playlistview.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = playlistview.m; path = ../../../modules/gui/macosx/playlistview.m; sourceTree = "<group>"; };
+               7DA481221B5FC13700917FD7 /* VLCPlaylistView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VLCPlaylistView.h; path = ../../../modules/gui/macosx/VLCPlaylistView.h; sourceTree = "<group>"; };
+               7DA481231B5FC13700917FD7 /* VLCPlaylistView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = VLCPlaylistView.m; path = ../../../modules/gui/macosx/VLCPlaylistView.m; sourceTree = "<group>"; };
                7DB65D5218ABD6380053B874 /* AddonsWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AddonsWindowController.h; path = ../../../modules/gui/macosx/AddonsWindowController.h; sourceTree = SOURCE_ROOT; };
                7DB65D5318ABD6380053B874 /* AddonsWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AddonsWindowController.m; path = ../../../modules/gui/macosx/AddonsWindowController.m; sourceTree = SOURCE_ROOT; };
                7DB65D5518ABD6490053B874 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/AddonManager.xib; sourceTree = "<group>"; };
                7DF812F41B5599E40052293C /* PLModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = PLModel.m; path = ../../../modules/gui/macosx/PLModel.m; sourceTree = "<group>"; };
                7DFFA16A16124F38001AF89F /* effects-one-button-pressed-dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "effects-one-button-pressed-dark.png"; path = "Resources/mainwindow_dark/effects-one-button-pressed-dark.png"; sourceTree = "<group>"; };
                7DFFA16B16124F38001AF89F /* effects-one-button-pressed-dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "effects-one-button-pressed-dark@2x.png"; path = "Resources/mainwindow_dark/effects-one-button-pressed-dark@2x.png"; sourceTree = "<group>"; };
-               8E49720006417F6800370C9F /* playlistinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = playlistinfo.h; path = ../../../modules/gui/macosx/playlistinfo.h; sourceTree = SOURCE_ROOT; };
-               8E49720106417F6800370C9F /* playlistinfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = playlistinfo.m; path = ../../../modules/gui/macosx/playlistinfo.m; sourceTree = SOURCE_ROOT; };
+               8E49720006417F6800370C9F /* VLCPlaylistInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCPlaylistInfo.h; path = ../../../modules/gui/macosx/VLCPlaylistInfo.h; sourceTree = SOURCE_ROOT; };
+               8E49720106417F6800370C9F /* VLCPlaylistInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCPlaylistInfo.m; path = ../../../modules/gui/macosx/VLCPlaylistInfo.m; sourceTree = SOURCE_ROOT; };
                8E55FB7F0459B0FD00FB3317 /* output.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = output.h; path = ../../../modules/gui/macosx/output.h; sourceTree = SOURCE_ROOT; };
                8E55FB800459B0FD00FB3317 /* output.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = output.m; path = ../../../modules/gui/macosx/output.m; sourceTree = SOURCE_ROOT; };
                8E6BC6F6041643860059A3A7 /* applescript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = applescript.h; path = ../../../modules/gui/macosx/applescript.h; sourceTree = SOURCE_ROOT; };
                8ED6C28003E2EB1C0059A3A7 /* misc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = misc.m; path = ../../../modules/gui/macosx/misc.m; sourceTree = SOURCE_ROOT; };
                8ED6C28103E2EB1C0059A3A7 /* open.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = open.h; path = ../../../modules/gui/macosx/open.h; sourceTree = SOURCE_ROOT; };
                8ED6C28203E2EB1C0059A3A7 /* open.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = open.m; path = ../../../modules/gui/macosx/open.m; sourceTree = SOURCE_ROOT; };
-               8ED6C28303E2EB1C0059A3A7 /* playlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = playlist.h; path = ../../../modules/gui/macosx/playlist.h; sourceTree = SOURCE_ROOT; };
-               8ED6C28403E2EB1C0059A3A7 /* playlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = playlist.m; path = ../../../modules/gui/macosx/playlist.m; sourceTree = SOURCE_ROOT; };
+               8ED6C28303E2EB1C0059A3A7 /* VLCPlaylist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCPlaylist.h; path = ../../../modules/gui/macosx/VLCPlaylist.h; sourceTree = SOURCE_ROOT; };
+               8ED6C28403E2EB1C0059A3A7 /* VLCPlaylist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCPlaylist.m; path = ../../../modules/gui/macosx/VLCPlaylist.m; sourceTree = SOURCE_ROOT; };
                8ED6C28503E2EB1C0059A3A7 /* prefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prefs.h; path = ../../../modules/gui/macosx/prefs.h; sourceTree = SOURCE_ROOT; };
                8ED6C28603E2EB1C0059A3A7 /* prefs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = prefs.m; path = ../../../modules/gui/macosx/prefs.m; sourceTree = SOURCE_ROOT; };
                8EDAC3430440F72D0059A3A7 /* README.MacOSX.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = README.MacOSX.rtf; sourceTree = SOURCE_ROOT; };
                                8ED6C28203E2EB1C0059A3A7 /* open.m */,
                                8E55FB7F0459B0FD00FB3317 /* output.h */,
                                8E55FB800459B0FD00FB3317 /* output.m */,
-                               8ED6C28303E2EB1C0059A3A7 /* playlist.h */,
-                               8ED6C28403E2EB1C0059A3A7 /* playlist.m */,
-                               7DA481221B5FC13700917FD7 /* playlistview.h */,
-                               7DA481231B5FC13700917FD7 /* playlistview.m */,
-                               8E49720006417F6800370C9F /* playlistinfo.h */,
-                               8E49720106417F6800370C9F /* playlistinfo.m */,
+                               8ED6C28303E2EB1C0059A3A7 /* VLCPlaylist.h */,
+                               8ED6C28403E2EB1C0059A3A7 /* VLCPlaylist.m */,
+                               7DA481221B5FC13700917FD7 /* VLCPlaylistView.h */,
+                               7DA481231B5FC13700917FD7 /* VLCPlaylistView.m */,
+                               8E49720006417F6800370C9F /* VLCPlaylistInfo.h */,
+                               8E49720106417F6800370C9F /* VLCPlaylistInfo.m */,
                                7DF812F11B5599E40052293C /* PLItem.h */,
                                7DF812F21B5599E40052293C /* PLItem.m */,
                                7DF812F31B5599E40052293C /* PLModel.h */,
                                1CCB5F7B1A62A724004C3E90 /* output.h in Sources */,
                                1CC25CA81B2C585D0003F994 /* darwinvlc.m in Sources */,
                                1CCB5F7C1A62A724004C3E90 /* output.m in Sources */,
-                               1CCB5F7D1A62A724004C3E90 /* playlist.h in Sources */,
-                               1CCB5F7E1A62A724004C3E90 /* playlist.m in Sources */,
-                               1CCB5F7F1A62A724004C3E90 /* playlistinfo.h in Sources */,
-                               1CCB5F801A62A724004C3E90 /* playlistinfo.m in Sources */,
+                               1CCB5F7D1A62A724004C3E90 /* VLCPlaylist.h in Sources */,
+                               1CCB5F7E1A62A724004C3E90 /* VLCPlaylist.m in Sources */,
+                               1CCB5F7F1A62A724004C3E90 /* VLCPlaylistInfo.h in Sources */,
+                               1CCB5F801A62A724004C3E90 /* VLCPlaylistInfo.m in Sources */,
                                1CCB5F811A62A724004C3E90 /* prefs_widgets.h in Sources */,
                                1CCB5F821A62A724004C3E90 /* prefs_widgets.m in Sources */,
                                1CCB5F831A62A724004C3E90 /* prefs.h in Sources */,
index 0259e6f..3d2623d 100644 (file)
@@ -27,7 +27,7 @@
 #import "CoreInteraction.h"
 #import "MainMenu.h"
 #import "fspanel.h"
-#import "playlist.h"
+#import "VLCPlaylist.h"
 #import "CompatibilityFixes.h"
 
 /*****************************************************************************
index 08f543b..053644a 100644 (file)
@@ -23,7 +23,7 @@
 
 #import "ConvertAndSave.h"
 #import "intf.h"
-#import "playlist.h"
+#import "VLCPlaylist.h"
 #import "misc.h"
 #import "SharedDialogs.h"
 
index face01d..400636b 100644 (file)
@@ -24,7 +24,7 @@
 #import "CoreInteraction.h"
 #import "intf.h"
 #import "open.h"
-#import "playlist.h"
+#import "VLCPlaylist.h"
 #import <math.h>
 #import <vlc_playlist.h>
 #import <vlc_input.h>
index 368f127..d39c6a8 100644 (file)
@@ -27,8 +27,8 @@
 #import "intf.h"
 #import "MainMenu.h"
 #import "MainWindow.h"
-#import "playlist.h"
-#import "playlistinfo.h"
+#import "VLCPlaylist.h"
+#import "VLCPlaylistInfo.h"
 #import "TrackSynchronization.h"
 #import "VideoView.h"
 
index 83ae929..38bf052 100644 (file)
@@ -36,8 +36,8 @@
 #import "bookmarks.h"
 #import "simple_prefs.h"
 #import "coredialogs.h"
-#import "playlist.h"
-#import "playlistinfo.h"
+#import "VLCPlaylist.h"
+#import "VLCPlaylistInfo.h"
 #import "VideoView.h"
 #import "CoreInteraction.h"
 #import "MainWindow.h"
index c7631b9..4ea2687 100644 (file)
@@ -32,7 +32,7 @@
 #import "AudioEffects.h"
 #import "MainMenu.h"
 #import "open.h"
-#import "playlist.h"
+#import "VLCPlaylist.h"
 #import "SideBarItem.h"
 #import <math.h>
 #import <vlc_playlist.h>
index 06784bc..691cf12 100644 (file)
@@ -51,9 +51,9 @@ libmacosx_plugin_la_SOURCES = \
        misc.h misc.m \
        open.h open.m \
        output.h output.m \
-       playlistview.h playlistview.m \
-       playlist.h playlist.m \
-       playlistinfo.h playlistinfo.m \
+       VLCPlaylistView.h VLCPlaylistView.m \
+       VLCPlaylist.h VLCPlaylist.m \
+       VLCPlaylistInfo.h VLCPlaylistInfo.m \
        PLItem.h PLItem.m \
        PLModel.h PLModel.m \
        prefs.h prefs.m \
index 7478fc3..4ccb16e 100644 (file)
 
 #import "misc.h"    /* VLCByteCountFormatter */
 
-#import "playlist.h"
+#import "VLCPlaylist.h"
 #import "StringUtility.h"
 #import "intf.h"
 #import "ControlsBar.h"
 #import "MainMenu.h"
-#import "playlistinfo.h"
+#import "VLCPlaylistInfo.h"
 #import "MainWindow.h"
 
 #ifdef HAVE_CONFIG_H
diff --git a/modules/gui/macosx/VLCPlaylist.h b/modules/gui/macosx/VLCPlaylist.h
new file mode 100644 (file)
index 0000000..937abb9
--- /dev/null
@@ -0,0 +1,95 @@
+/*****************************************************************************
+ * VLCPlaylist.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2002-2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Benjamin Pracht <bigben at videolab dot org>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "PXSourceList.h"
+#import "PLModel.h"
+#import "VLCPlaylistView.h"
+
+@interface VLCPlaylist : NSObject<NSOutlineViewDelegate>
+
+@property (readwrite, weak) IBOutlet NSMenu *playlistMenu;
+@property (readwrite, weak) IBOutlet NSMenuItem *playPlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *deletePlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *infoPlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *preparsePlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *revealInFinderPlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *downloadCoverArtPlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *selectAllPlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *sortNamePlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *sortAuthorPlaylistMenuItem;
+@property (readwrite, weak) IBOutlet NSMenuItem *recursiveExpandPlaylistMenuItem;
+
+@property (nonatomic, readwrite, weak) VLCPlaylistView *outlineView;
+@property (nonatomic, readwrite, weak) NSTableHeaderView *playlistHeaderView;
+
+- (PLModel *)model;
+
+- (void)reloadStyles;
+
+- (NSMenu *)menuForEvent:(NSEvent *)o_event;
+
+- (void)playlistUpdated;
+- (void)playbackModeUpdated;
+- (void)updateTogglePlaylistState;
+- (void)outlineViewSelectionDidChange:(NSNotification *)notification;
+- (void)sortNode:(int)i_mode;
+
+- (void)currentlyPlayingItemChanged;
+
+- (BOOL)isSelectionEmpty;
+
+- (IBAction)playItem:(id)sender;
+- (IBAction)revealItemInFinder:(id)sender;
+- (IBAction)preparseItem:(id)sender;
+- (IBAction)downloadCoverArt:(id)sender;
+- (IBAction)deleteItem:(id)sender;
+- (IBAction)selectAll:(id)sender;
+- (IBAction)sortNodeByName:(id)sender;
+- (IBAction)sortNodeByAuthor:(id)sender;
+- (IBAction)recursiveExpandNode:(id)sender;
+- (IBAction)showInfoPanel:(id)sender;
+
+- (NSArray *)draggedItems;
+
+/**
+ * Simplified version to add new items at the end of the current playlist
+ */
+- (void)addPlaylistItems:(NSArray*)o_array;
+
+/**
+ * Adds new items to the playlist, at specified parent node and index.
+ * @param o_array array of items. Each item is a Dictionary with meta info.
+ * @param i_plItemId parent playlist node id, -1 for default playlist
+ * @param i_position index for new items, -1 for appending at end
+ * @param b_start starts playback of first item if true
+ */
+- (void)addPlaylistItems:(NSArray*)o_array withParentItemId:(int)i_plItemId atPos:(int)i_position startPlayback:(BOOL)b_start;
+
+
+- (void)setColumn: (NSString *)o_column state: (NSInteger)i_state translationDict:(NSDictionary *)o_dict;
+- (void)continuePlaybackWhereYouLeftOff:(input_thread_t *)p_input_thread;
+- (void)storePlaybackPositionForItem:(input_thread_t *)p_input_thread;
+
+@end
diff --git a/modules/gui/macosx/VLCPlaylist.m b/modules/gui/macosx/VLCPlaylist.m
new file mode 100644 (file)
index 0000000..8bcde00
--- /dev/null
@@ -0,0 +1,866 @@
+/*****************************************************************************
+ * VLCPlaylist.m: MacOS X interface module
+ *****************************************************************************
+* Copyright (C) 2002-2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Derk-Jan Hartman <hartman at videola/n dot org>
+ *          Benjamin Pracht <bigben at videolan dot org>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/* TODO
+ * add 'icons' for different types of nodes? (http://www.cocoadev.com/index.pl?IconAndTextInTableCell)
+ * reimplement enable/disable item
+ */
+
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <sys/param.h>                                    /* for MAXPATHLEN */
+#include <string.h>
+#include <math.h>
+#include <sys/mount.h>
+
+#import "CompatibilityFixes.h"
+
+#import "intf.h"
+#import "VLCPlaylist.h"
+#import "MainMenu.h"
+#import "VLCPlaylistInfo.h"
+#import "ResumeDialogController.h"
+
+#include <vlc_keys.h>
+#import <vlc_interface.h>
+#include <vlc_url.h>
+
+/*****************************************************************************
+ * An extension to NSOutlineView's interface to fix compilation warnings
+ * and let us access these 2 functions properly.
+ * This uses a private API, but works fine on all current OSX releases.
+ * Radar ID 11739459 request a public API for this. However, it is probably
+ * easier and faster to recreate similar looking bitmaps ourselves.
+ *****************************************************************************/
+
+@interface NSOutlineView (UndocumentedSortImages)
++ (NSImage *)_defaultTableHeaderSortImage;
++ (NSImage *)_defaultTableHeaderReverseSortImage;
+@end
+
+@interface VLCPlaylist ()
+{
+    NSImage *_descendingSortingImage;
+    NSImage *_ascendingSortingImage;
+
+    BOOL b_selected_item_met;
+    BOOL b_isSortDescending;
+    NSTableColumn *_sortTableColumn;
+
+    BOOL b_playlistmenu_nib_loaded;
+    BOOL b_view_setup;
+
+    PLModel *_model;
+}
+
+- (void)saveTableColumns;
+@end
+
+@implementation VLCPlaylist
+
++ (void)initialize
+{
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSMutableArray *columnArray = [[NSMutableArray alloc] init];
+    [columnArray addObject: [NSArray arrayWithObjects:TITLE_COLUMN, [NSNumber numberWithFloat:190.], nil]];
+    [columnArray addObject: [NSArray arrayWithObjects:ARTIST_COLUMN, [NSNumber numberWithFloat:95.], nil]];
+    [columnArray addObject: [NSArray arrayWithObjects:DURATION_COLUMN, [NSNumber numberWithFloat:95.], nil]];
+
+    NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
+                                 [NSArray arrayWithArray:columnArray], @"PlaylistColumnSelection",
+                                 [NSArray array], @"recentlyPlayedMediaList",
+                                 [NSDictionary dictionary], @"recentlyPlayedMedia", nil];
+
+    [defaults registerDefaults:appDefaults];
+}
+
+- (PLModel *)model
+{
+    return _model;
+}
+
+- (void)reloadStyles
+{
+    NSFont *fontToUse;
+    CGFloat rowHeight;
+    if (var_InheritBool(VLCIntf, "macosx-large-text")) {
+        fontToUse = [NSFont systemFontOfSize:13.];
+        rowHeight = 21.;
+    } else {
+        fontToUse = [NSFont systemFontOfSize:11.];
+        rowHeight = 16.;
+    }
+
+    NSArray *columns = [_outlineView tableColumns];
+    NSUInteger count = columns.count;
+    for (NSUInteger x = 0; x < count; x++)
+        [[columns[x] dataCell] setFont:fontToUse];
+    [_outlineView setRowHeight:rowHeight];
+}
+
+- (void)awakeFromNib
+{
+    if (b_view_setup)
+        return;
+
+    [self reloadStyles];
+    [self initStrings];
+
+    /* This uses a private API, but works fine on all current OSX releases.
+     * Radar ID 11739459 request a public API for this. However, it is probably
+     * easier and faster to recreate similar looking bitmaps ourselves. */
+    _ascendingSortingImage = [[NSOutlineView class] _defaultTableHeaderSortImage];
+    _descendingSortingImage = [[NSOutlineView class] _defaultTableHeaderReverseSortImage];
+
+    _sortTableColumn = nil;
+
+    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationWillTerminate:) name: NSApplicationWillTerminateNotification object: nil];
+
+    b_view_setup = YES;
+}
+
+- (void)setOutlineView:(VLCPlaylistView * __nullable)outlineView
+{
+    _outlineView = outlineView;
+    [_outlineView setDelegate:self];
+
+    playlist_t * p_playlist = pl_Get(VLCIntf);
+
+    _model = [[PLModel alloc] initWithOutlineView:_outlineView playlist:p_playlist rootItem:p_playlist->p_playing playlistObject:self];
+    [_outlineView setDataSource:_model];
+    [_outlineView reloadData];
+
+    [_outlineView setTarget: self];
+    [_outlineView setDoubleAction: @selector(playItem:)];
+
+    [_outlineView setAllowsEmptySelection: NO];
+    [_outlineView registerForDraggedTypes: [NSArray arrayWithObjects:NSFilenamesPboardType, @"VLCPlaylistItemPboardType", nil]];
+    [_outlineView setIntercellSpacing: NSMakeSize (0.0, 1.0)];
+}
+
+- (void)setPlaylistHeaderView:(NSTableHeaderView * __nullable)playlistHeaderView
+{
+    VLCMainMenu *mainMenu = [[VLCMain sharedInstance] mainMenu];
+    _playlistHeaderView = playlistHeaderView;
+    NSMenu *contextMenu = [mainMenu setupPlaylistTableColumnsMenu];
+    [_playlistHeaderView setMenu: contextMenu];
+
+    NSArray * columnArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"PlaylistColumnSelection"];
+    NSUInteger columnCount = [columnArray count];
+    NSString * column;
+
+    for (NSUInteger i = 0; i < columnCount; i++) {
+        column = [columnArray[i] firstObject];
+        if ([column isEqualToString:@"status"])
+            continue;
+
+        if(![mainMenu setPlaylistColumnTableState: NSOnState forColumn:column])
+            continue;
+
+        [[_outlineView tableColumnWithIdentifier: column] setWidth: [columnArray[i][1] floatValue]];
+    }
+}
+
+- (void)applicationWillTerminate:(NSNotification *)notification
+{
+    /* let's make sure we save the correct widths and positions, since this likely changed since the last time the user played with the column selection */
+    [self saveTableColumns];
+}
+
+- (void)initStrings
+{
+    [_playPlaylistMenuItem setTitle: _NS("Play")];
+    [_deletePlaylistMenuItem setTitle: _NS("Delete")];
+    [_recursiveExpandPlaylistMenuItem setTitle: _NS("Expand Node")];
+    [_selectAllPlaylistMenuItem setTitle: _NS("Select All")];
+    [_infoPlaylistMenuItem setTitle: _NS("Media Information...")];
+    [_downloadCoverArtPlaylistMenuItem setTitle: _NS("Download Cover Art")];
+    [_preparsePlaylistMenuItem setTitle: _NS("Fetch Meta Data")];
+    [_revealInFinderPlaylistMenuItem setTitle: _NS("Reveal in Finder")];
+    [_sortNamePlaylistMenuItem setTitle: _NS("Sort Node by Name")];
+    [_sortAuthorPlaylistMenuItem setTitle: _NS("Sort Node by Author")];
+}
+
+- (void)playlistUpdated
+{
+    [_outlineView reloadData];
+}
+
+- (void)playbackModeUpdated
+{
+    [_model playbackModeUpdated];
+}
+
+- (void)updateTogglePlaylistState
+{
+    [self outlineViewSelectionDidChange: NULL];
+}
+
+- (void)outlineViewSelectionDidChange:(NSNotification *)notification
+{
+//    // FIXME: unsafe
+//    playlist_item_t * p_item = [[_outlineView itemAtRow:[_outlineView selectedRow]] pointerValue];
+//
+//    if (p_item) {
+//        /* update the state of our Reveal-in-Finder menu items */
+//        NSMutableString *o_mrl;
+//        char *psz_uri = input_item_GetURI(p_item->p_input);
+//
+//        [o_mi_revealInFinder setEnabled: NO];
+//        [o_mm_mi_revealInFinder setEnabled: NO];
+//        if (psz_uri) {
+//            o_mrl = [NSMutableString stringWithUTF8String: psz_uri];
+//
+//            /* perform some checks whether it is a file and if it is local at all... */
+//            NSRange prefix_range = [o_mrl rangeOfString: @"file:"];
+//            if (prefix_range.location != NSNotFound)
+//                [o_mrl deleteCharactersInRange: prefix_range];
+//
+//            if ([o_mrl characterAtIndex:0] == '/') {
+//                [o_mi_revealInFinder setEnabled: YES];
+//                [o_mm_mi_revealInFinder setEnabled: YES];
+//            }
+//            free(psz_uri);
+//        }
+//
+//        /* update our info-panel to reflect the new item */
+//        [[VLCInfo sharedInstance] updatePanelWithItem:p_item->p_input];
+//    }
+}
+
+- (BOOL)isSelectionEmpty
+{
+    return [_outlineView selectedRow] == -1;
+}
+
+- (void)currentlyPlayingItemChanged
+{
+    PLItem *item = [[self model] currentlyPlayingItem];
+    if (!item)
+        return;
+
+    // select item
+    NSInteger itemIndex = [_outlineView rowForItem:item];
+    if (itemIndex < 0) {
+        // expand if needed
+        while (item != nil) {
+            PLItem *parent = [item parent];
+
+            if (![_outlineView isExpandable: parent])
+                break;
+            if (![_outlineView isItemExpanded: parent])
+                [_outlineView expandItem: parent];
+            item = parent;
+        }
+
+        // search for row again
+        itemIndex = [_outlineView rowForItem:item];
+        if (itemIndex < 0) {
+            return;
+        }
+    }
+
+    [_outlineView selectRowIndexes: [NSIndexSet indexSetWithIndex: itemIndex] byExtendingSelection: NO];
+}
+
+/* When called retrieves the selected outlineview row and plays that node or item */
+- (IBAction)playItem:(id)sender
+{
+    playlist_t *p_playlist = pl_Get(VLCIntf);
+
+    // ignore clicks on column header when handling double action
+    if (sender == _outlineView && [_outlineView clickedRow] == -1)
+        return;
+
+    PLItem *o_item = [_outlineView itemAtRow:[_outlineView selectedRow]];
+    if (!o_item)
+        return;
+
+    PL_LOCK;
+    playlist_item_t *p_item = playlist_ItemGetById(p_playlist, [o_item plItemId]);
+    playlist_item_t *p_node = playlist_ItemGetById(p_playlist, [[[self model] rootItem] plItemId]);
+
+    if (p_item && p_node) {
+        playlist_Control(p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, p_node, p_item);
+    }
+    PL_UNLOCK;
+}
+
+- (IBAction)revealItemInFinder:(id)sender
+{
+    NSIndexSet *selectedRows = [_outlineView selectedRowIndexes];
+    [selectedRows enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
+
+        PLItem *o_item = [_outlineView itemAtRow:idx];
+
+        /* perform some checks whether it is a file and if it is local at all... */
+        char *psz_url = input_item_GetURI([o_item input]);
+        NSURL *url = [NSURL URLWithString:toNSStr(psz_url)];
+        free(psz_url);
+        if (![url isFileURL])
+            return;
+        if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]])
+            return;
+
+        msg_Dbg(VLCIntf, "Reveal url %s in finder", [[url path] UTF8String]);
+        [[NSWorkspace sharedWorkspace] selectFile: [url path] inFileViewerRootedAtPath: [url path]];
+    }];
+
+}
+
+/* When called retrieves the selected outlineview row and plays that node or item */
+- (IBAction)preparseItem:(id)sender
+{
+    int i_count;
+    NSIndexSet *o_selected_indexes;
+    intf_thread_t * p_intf = VLCIntf;
+    playlist_t * p_playlist = pl_Get(p_intf);
+    playlist_item_t *p_item = NULL;
+
+    o_selected_indexes = [_outlineView selectedRowIndexes];
+    i_count = [o_selected_indexes count];
+
+    NSUInteger indexes[i_count];
+    [o_selected_indexes getIndexes:indexes maxCount:i_count inIndexRange:nil];
+    for (int i = 0; i < i_count; i++) {
+        PLItem *o_item = [_outlineView itemAtRow:indexes[i]];
+        [_outlineView deselectRow: indexes[i]];
+
+        if (![o_item isLeaf]) {
+            msg_Dbg(p_intf, "preparsing nodes not implemented");
+            continue;
+        }
+
+        libvlc_MetaRequest(p_intf->p_libvlc, [o_item input], META_REQUEST_OPTION_NONE);
+
+    }
+    [self playlistUpdated];
+}
+
+- (IBAction)downloadCoverArt:(id)sender
+{
+    int i_count;
+    NSIndexSet *o_selected_indexes;
+    intf_thread_t * p_intf = VLCIntf;
+    playlist_t * p_playlist = pl_Get(p_intf);
+    playlist_item_t *p_item = NULL;
+
+    o_selected_indexes = [_outlineView selectedRowIndexes];
+    i_count = [o_selected_indexes count];
+
+    NSUInteger indexes[i_count];
+    [o_selected_indexes getIndexes:indexes maxCount:i_count inIndexRange:nil];
+    for (int i = 0; i < i_count; i++) {
+        PLItem *o_item = [_outlineView itemAtRow: indexes[i]];
+
+        if (![o_item isLeaf])
+            continue;
+
+        libvlc_ArtRequest(p_intf->p_libvlc, [o_item input], META_REQUEST_OPTION_NONE);
+    }
+    [self playlistUpdated];
+}
+
+- (IBAction)selectAll:(id)sender
+{
+    [_outlineView selectAll: nil];
+}
+
+- (IBAction)showInfoPanel:(id)sender
+{
+    [[VLCInfo sharedInstance] initPanel];
+}
+
+- (IBAction)deleteItem:(id)sender
+{
+    [_model deleteSelectedItem];
+}
+
+- (IBAction)sortNodeByName:(id)sender
+{
+    [self sortNode: SORT_TITLE];
+}
+
+- (IBAction)sortNodeByAuthor:(id)sender
+{
+    [self sortNode: SORT_ARTIST];
+}
+
+- (void)sortNode:(int)i_mode
+{
+    playlist_t * p_playlist = pl_Get(VLCIntf);
+    playlist_item_t * p_item;
+
+    // TODO why do we need this kind of sort? It looks crap and confusing...
+
+//    if ([_outlineView selectedRow] > -1) {
+//        p_item = [[_outlineView itemAtRow: [_outlineView selectedRow]] pointerValue];
+//        if (!p_item)
+//            return;
+//    } else
+//        p_item = [self currentPlaylistRoot]; // If no item is selected, sort the whole playlist
+//
+//    PL_LOCK;
+//    if (p_item->i_children > -1) // the item is a node
+//        playlist_RecursiveNodeSort(p_playlist, p_item, i_mode, ORDER_NORMAL);
+//    else
+//        playlist_RecursiveNodeSort(p_playlist, p_item->p_parent, i_mode, ORDER_NORMAL);
+//
+//    PL_UNLOCK;
+//    [self playlistUpdated];
+}
+
+- (input_item_t *)createItem:(NSDictionary *)itemToCreateDict
+{
+    intf_thread_t *p_intf = VLCIntf;
+    playlist_t *p_playlist = pl_Get(p_intf);
+
+    input_item_t *p_input;
+    BOOL b_rem = FALSE, b_dir = FALSE, b_writable = FALSE;
+    NSString *uri, *name, *path;
+    NSURL * url;
+    NSArray *optionsArray;
+
+    /* Get the item */
+    uri = (NSString *)[itemToCreateDict objectForKey: @"ITEM_URL"];
+    url = [NSURL URLWithString: uri];
+    path = [url path];
+    name = (NSString *)[itemToCreateDict objectForKey: @"ITEM_NAME"];
+    optionsArray = (NSArray *)[itemToCreateDict objectForKey: @"ITEM_OPTIONS"];
+
+    if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&b_dir] && b_dir &&
+        [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:path isRemovable: &b_rem
+                                                     isWritable:&b_writable isUnmountable:NULL description:NULL type:NULL] && b_rem && !b_writable && [url isFileURL]) {
+
+        NSString *diskType = [[VLCStringUtility sharedInstance] getVolumeTypeFromMountPath: path];
+        msg_Dbg(p_intf, "detected optical media of type %s in the file input", [diskType UTF8String]);
+
+        if ([diskType isEqualToString: kVLCMediaDVD])
+            uri = [NSString stringWithFormat: @"dvdnav://%@", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
+        else if ([diskType isEqualToString: kVLCMediaVideoTSFolder])
+            uri = [NSString stringWithFormat: @"dvdnav://%@", path];
+        else if ([diskType isEqualToString: kVLCMediaAudioCD])
+            uri = [NSString stringWithFormat: @"cdda://%@", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
+        else if ([diskType isEqualToString: kVLCMediaVCD])
+            uri = [NSString stringWithFormat: @"vcd://%@#0:0", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
+        else if ([diskType isEqualToString: kVLCMediaSVCD])
+            uri = [NSString stringWithFormat: @"vcd://%@@0:0", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
+        else if ([diskType isEqualToString: kVLCMediaBD] || [diskType isEqualToString: kVLCMediaBDMVFolder])
+            uri = [NSString stringWithFormat: @"bluray://%@", path];
+        else
+            msg_Warn(VLCIntf, "unknown disk type, treating %s as regular input", [path UTF8String]);
+
+        p_input = input_item_New([uri UTF8String], [[[NSFileManager defaultManager] displayNameAtPath:path] UTF8String]);
+    }
+    else
+        p_input = input_item_New([uri fileSystemRepresentation], name ? [name UTF8String] : NULL);
+
+    if (!p_input)
+        return NULL;
+
+    if (optionsArray) {
+        NSUInteger count = [optionsArray count];
+        for (NSUInteger i = 0; i < count; i++)
+            input_item_AddOption(p_input, [optionsArray[i] UTF8String], VLC_INPUT_OPTION_TRUSTED);
+    }
+
+    /* Recent documents menu */
+    if (url != nil && (BOOL)config_GetInt(p_playlist, "macosx-recentitems") == YES)
+        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:url];
+
+    return p_input;
+}
+
+- (void)addPlaylistItems:(NSArray*)array
+{
+
+    int i_plItemId = -1;
+
+    // add items directly to media library if this is the current root
+    if ([[self model] currentRootType] == ROOT_TYPE_MEDIALIBRARY)
+        i_plItemId = [[[self model] rootItem] plItemId];
+
+    BOOL b_autoplay = var_InheritBool(VLCIntf, "macosx-autoplay");
+
+    [self addPlaylistItems:array withParentItemId:i_plItemId atPos:-1 startPlayback:b_autoplay];
+}
+
+- (void)addPlaylistItems:(NSArray*)array withParentItemId:(int)i_plItemId atPos:(int)i_position startPlayback:(BOOL)b_start
+{
+    playlist_t * p_playlist = pl_Get(VLCIntf);
+    PL_LOCK;
+
+    playlist_item_t *p_parent = NULL;
+    if (i_plItemId >= 0)
+        p_parent = playlist_ItemGetById(p_playlist, i_plItemId);
+    else
+        p_parent = p_playlist->p_playing;
+
+    if (!p_parent) {
+        PL_UNLOCK;
+        return;
+    }
+
+    NSUInteger count = [array count];
+    int i_current_offset = 0;
+    for (NSUInteger i = 0; i < count; ++i) {
+
+        NSDictionary *o_current_item = array[i];
+        input_item_t *p_input = [self createItem: o_current_item];
+        if (!p_input)
+            continue;
+
+        int i_pos = (i_position == -1) ? PLAYLIST_END : i_position + i_current_offset++;
+        playlist_item_t *p_item = playlist_NodeAddInput(p_playlist, p_input, p_parent,
+                                                        PLAYLIST_INSERT, i_pos, pl_Locked);
+        if (!p_item)
+            continue;
+
+        if (i == 0 && b_start) {
+            playlist_Control(p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, p_parent, p_item);
+        }
+        input_item_Release(p_input);
+    }
+    PL_UNLOCK;
+}
+
+- (IBAction)recursiveExpandNode:(id)sender
+{
+    NSIndexSet * selectedRows = [_outlineView selectedRowIndexes];
+    NSUInteger count = [selectedRows count];
+    NSUInteger indexes[count];
+    [selectedRows getIndexes:indexes maxCount:count inIndexRange:nil];
+
+    id item;
+    playlist_item_t *p_item;
+    for (NSUInteger i = 0; i < count; i++) {
+        item = [_outlineView itemAtRow: indexes[i]];
+
+        /* We need to collapse the node first, since OSX refuses to recursively
+         expand an already expanded node, even if children nodes are collapsed. */
+        if ([_outlineView isExpandable:item]) {
+            [_outlineView collapseItem: item collapseChildren: YES];
+            [_outlineView expandItem: item expandChildren: YES];
+        }
+
+        selectedRows = [_outlineView selectedRowIndexes];
+        [selectedRows getIndexes:indexes maxCount:count inIndexRange:nil];
+    }
+}
+
+- (NSMenu *)menuForEvent:(NSEvent *)o_event
+{
+    if (!b_playlistmenu_nib_loaded)
+        b_playlistmenu_nib_loaded = [NSBundle loadNibNamed:@"PlaylistMenu" owner:self];
+
+    NSPoint pt;
+    bool b_rows;
+    bool b_item_sel;
+
+    pt = [_outlineView convertPoint: [o_event locationInWindow] fromView: nil];
+    int row = [_outlineView rowAtPoint:pt];
+    if (row != -1 && ![[_outlineView selectedRowIndexes] containsIndex: row])
+        [_outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
+
+    b_item_sel = (row != -1 && [_outlineView selectedRow] != -1);
+    b_rows = [_outlineView numberOfRows] != 0;
+
+    playlist_t *p_playlist = pl_Get(VLCIntf);
+    bool b_del_allowed = [[self model] editAllowed];
+
+    [_playPlaylistMenuItem setEnabled: b_item_sel];
+    [_deletePlaylistMenuItem setEnabled: b_item_sel && b_del_allowed];
+    [_selectAllPlaylistMenuItem setEnabled: b_rows];
+    [_infoPlaylistMenuItem setEnabled: b_item_sel];
+    [_preparsePlaylistMenuItem setEnabled: b_item_sel];
+    [_recursiveExpandPlaylistMenuItem setEnabled: b_item_sel];
+    [_sortNamePlaylistMenuItem setEnabled: b_item_sel];
+    [_sortAuthorPlaylistMenuItem setEnabled: b_item_sel];
+    [_downloadCoverArtPlaylistMenuItem setEnabled: b_item_sel];
+
+    return _playlistMenu;
+}
+
+- (void)outlineView:(NSOutlineView *)outlineView didClickTableColumn:(NSTableColumn *)aTableColumn
+{
+    int type = 0;
+    intf_thread_t *p_intf = VLCIntf;
+    NSString * identifier = [aTableColumn identifier];
+
+    playlist_t *p_playlist = pl_Get(p_intf);
+
+    if (_sortTableColumn == aTableColumn)
+        b_isSortDescending = !b_isSortDescending;
+    else
+        b_isSortDescending = false;
+
+    if (b_isSortDescending)
+        type = ORDER_REVERSE;
+    else
+        type = ORDER_NORMAL;
+
+    [[self model] sortForColumn:identifier withMode:type];
+
+    // TODO rework, why do we need a full call here?
+//    [self playlistUpdated];
+
+    /* Clear indications of any existing column sorting */
+    NSUInteger count = [[_outlineView tableColumns] count];
+    for (NSUInteger i = 0 ; i < count ; i++)
+        [_outlineView setIndicatorImage:nil inTableColumn: [_outlineView tableColumns][i]];
+
+    [_outlineView setHighlightedTableColumn:nil];
+    _sortTableColumn = aTableColumn;
+    [_outlineView setHighlightedTableColumn:aTableColumn];
+
+    if (b_isSortDescending)
+        [_outlineView setIndicatorImage:_descendingSortingImage inTableColumn:aTableColumn];
+    else
+        [_outlineView setIndicatorImage:_ascendingSortingImage inTableColumn:aTableColumn];
+}
+
+
+- (void)outlineView:(NSOutlineView *)outlineView
+    willDisplayCell:(id)cell
+     forTableColumn:(NSTableColumn *)tableColumn
+               item:(id)item
+{
+    /* this method can be called when VLC is already dead, hence the extra checks */
+    intf_thread_t * p_intf = VLCIntf;
+    if (!p_intf)
+        return;
+    playlist_t *p_playlist = pl_Get(p_intf);
+
+    NSFont *fontToUse;
+    if (var_InheritBool(VLCIntf, "macosx-large-text"))
+        fontToUse = [NSFont systemFontOfSize:13.];
+    else
+        fontToUse = [NSFont systemFontOfSize:11.];
+
+    BOOL b_is_playing = NO;
+    PL_LOCK;
+    playlist_item_t *p_current_item = playlist_CurrentPlayingItem(p_playlist);
+    if (p_current_item) {
+        b_is_playing = p_current_item->i_id == [item plItemId];
+    }
+    PL_UNLOCK;
+
+    /*
+     TODO: repaint all items bold:
+     [self isItem: [o_playing_item pointerValue] inNode: [item pointerValue] checkItemExistence:YES locked:NO]
+     || [o_playing_item isEqual: item]
+     */
+
+    if (b_is_playing)
+        [cell setFont: [[NSFontManager sharedFontManager] convertFont:fontToUse toHaveTrait:NSBoldFontMask]];
+    else
+        [cell setFont: [[NSFontManager sharedFontManager] convertFont:fontToUse toNotHaveTrait:NSBoldFontMask]];
+}
+
+// TODO remove method
+- (NSArray *)draggedItems
+{
+    return [[self model] draggedItems];
+}
+
+- (void)setColumn:(NSString *)columnIdentifier state:(NSInteger)i_state translationDict:(NSDictionary *)translationDict
+{
+    if (i_state == NSOnState) {
+        NSString *title = [translationDict objectForKey:columnIdentifier];
+        if (!title)
+            return;
+
+        NSTableColumn *tableColumn = [[NSTableColumn alloc] initWithIdentifier:columnIdentifier];
+        [tableColumn setEditable:NO];
+        [[tableColumn dataCell] setFont:[NSFont controlContentFontOfSize:11.]];
+
+        [[tableColumn headerCell] setStringValue:[translationDict objectForKey:columnIdentifier]];
+
+        if ([columnIdentifier isEqualToString: TRACKNUM_COLUMN]) {
+            [tableColumn setWidth:20.];
+            [tableColumn setResizingMask:NSTableColumnNoResizing];
+            [[tableColumn headerCell] setStringValue:@"#"];
+        }
+
+        [_outlineView addTableColumn:tableColumn];
+        [_outlineView reloadData];
+        [_outlineView setNeedsDisplay: YES];
+    }
+    else
+        [_outlineView removeTableColumn: [_outlineView tableColumnWithIdentifier:columnIdentifier]];
+
+    [_outlineView setOutlineTableColumn: [_outlineView tableColumnWithIdentifier:TITLE_COLUMN]];
+}
+
+- (void)saveTableColumns
+{
+    NSMutableArray *arrayToSave = [[NSMutableArray alloc] init];
+    NSArray *columns = [[NSArray alloc] initWithArray:[_outlineView tableColumns]];
+    NSUInteger columnCount = [columns count];
+    NSTableColumn *currentColumn;
+    for (NSUInteger i = 0; i < columnCount; i++) {
+        currentColumn = columns[i];
+        [arrayToSave addObject:[NSArray arrayWithObjects:[currentColumn identifier], [NSNumber numberWithFloat:[currentColumn width]], nil]];
+    }
+    [[NSUserDefaults standardUserDefaults] setObject:arrayToSave forKey:@"PlaylistColumnSelection"];
+    [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+- (BOOL)isValidResumeItem:(input_item_t *)p_item
+{
+    char *psz_url = input_item_GetURI(p_item);
+    NSString *urlString = toNSStr(psz_url);
+    free(psz_url);
+
+    if ([urlString isEqualToString:@""])
+        return NO;
+
+    NSURL *url = [NSURL URLWithString:urlString];
+
+    if (![url isFileURL])
+        return NO;
+
+    BOOL isDir = false;
+    if (![[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDir])
+        return NO;
+
+    if (isDir)
+        return NO;
+
+    return YES;
+}
+
+- (void)continuePlaybackWhereYouLeftOff:(input_thread_t *)p_input_thread
+{
+    NSDictionary *recentlyPlayedFiles = [[NSUserDefaults standardUserDefaults] objectForKey:@"recentlyPlayedMedia"];
+    if (!recentlyPlayedFiles)
+        return;
+
+    input_item_t *p_item = input_GetItem(p_input_thread);
+    if (!p_item)
+        return;
+
+    /* allow the user to over-write the start/stop/run-time */
+    if (var_GetFloat(p_input_thread, "run-time") > 0 ||
+        var_GetFloat(p_input_thread, "start-time") > 0 ||
+        var_GetFloat(p_input_thread, "stop-time") != 0) {
+        return;
+    }
+
+    /* check for file existance before resuming */
+    if (![self isValidResumeItem:p_item])
+        return;
+
+    char *psz_url = decode_URI(input_item_GetURI(p_item));
+    if (!psz_url)
+        return;
+    NSString *url = toNSStr(psz_url);
+    free(psz_url);
+
+    NSNumber *lastPosition = [recentlyPlayedFiles objectForKey:url];
+    if (!lastPosition || lastPosition.intValue <= 0)
+        return;
+
+    int settingValue = config_GetInt(VLCIntf, "macosx-continue-playback");
+    if (settingValue == 2) // never resume
+        return;
+
+    CompletionBlock completionBlock = ^(enum ResumeResult result) {
+
+        if (result == RESUME_RESTART)
+            return;
+
+        mtime_t lastPos = (mtime_t)lastPosition.intValue * 1000000;
+        msg_Dbg(VLCIntf, "continuing playback at %lld", lastPos);
+        var_SetInteger(p_input_thread, "time", lastPos);
+
+        if (result == RESUME_ALWAYS)
+            config_PutInt(VLCIntf, "macosx-continue-playback", 1);
+    };
+
+    if (settingValue == 1) { // always
+        completionBlock(RESUME_NOW);
+        return;
+    }
+
+    [[[VLCMain sharedInstance] resumeDialog] showWindowWithItem:p_item
+                                               withLastPosition:lastPosition.intValue
+                                                completionBlock:completionBlock];
+
+}
+
+- (void)storePlaybackPositionForItem:(input_thread_t *)p_input_thread
+{
+    if (!var_InheritBool(VLCIntf, "macosx-recentitems"))
+        return;
+
+    input_item_t *p_item = input_GetItem(p_input_thread);
+    if (!p_item)
+        return;
+
+    if (![self isValidResumeItem:p_item])
+        return;
+
+    char *psz_url = decode_URI(input_item_GetURI(p_item));
+    if (!psz_url)
+        return;
+    NSString *url = toNSStr(psz_url);
+    free(psz_url);
+
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSMutableDictionary *mutDict = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:@"recentlyPlayedMedia"]];
+
+    float relativePos = var_GetFloat(p_input_thread, "position");
+    mtime_t pos = var_GetInteger(p_input_thread, "time") / CLOCK_FREQ;
+    mtime_t dur = input_item_GetDuration(p_item) / 1000000;
+
+    NSMutableArray *mediaList = [[defaults objectForKey:@"recentlyPlayedMediaList"] mutableCopy];
+
+    if (relativePos > .05 && relativePos < .95 && dur > 180) {
+        [mutDict setObject:[NSNumber numberWithInt:pos] forKey:url];
+
+        [mediaList removeObject:url];
+        [mediaList addObject:url];
+        NSUInteger mediaListCount = mediaList.count;
+        if (mediaListCount > 30) {
+            for (NSUInteger x = 0; x < mediaListCount - 30; x++) {
+                [mutDict removeObjectForKey:[mediaList firstObject]];
+                [mediaList removeObjectAtIndex:0];
+            }
+        }
+    } else {
+        [mutDict removeObjectForKey:url];
+        [mediaList removeObject:url];
+    }
+    [defaults setObject:mutDict forKey:@"recentlyPlayedMedia"];
+    [defaults setObject:mediaList forKey:@"recentlyPlayedMediaList"];
+    [defaults synchronize];
+}
+
+@end
diff --git a/modules/gui/macosx/VLCPlaylistInfo.h b/modules/gui/macosx/VLCPlaylistInfo.h
new file mode 100644 (file)
index 0000000..2893a94
--- /dev/null
@@ -0,0 +1,123 @@
+/*****************************************************************************
+ * VLCPlaylistInfo.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2002-2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Benjamin Pracht <bigben at videolan dot org>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * VLCPlaylistInfo interface
+ *****************************************************************************/
+
+@class VLCInfoTreeItem;
+
+@interface VLCInfo : NSObject
+
+@property (readonly) input_item_t *item;
+
+@property (readwrite, weak) IBOutlet NSPanel *infoPanel;
+@property (readwrite, weak) IBOutlet NSOutlineView *outlineView;
+@property (readwrite, weak) IBOutlet NSTabView *tabView;
+
+@property (readwrite, weak) IBOutlet NSTextField *uriLabel;
+@property (readwrite, weak) IBOutlet NSTextField *titleLabel;
+@property (readwrite, weak) IBOutlet NSTextField *authorLabel;
+@property (readwrite, weak) IBOutlet NSTextField *uriTextField;
+@property (readwrite, weak) IBOutlet NSTextField *titleTextField;
+@property (readwrite, weak) IBOutlet NSTextField *authorTextField;
+@property (readwrite, weak) IBOutlet NSTextField *collectionLabel;
+@property (readwrite, weak) IBOutlet NSTextField *collectionTextField;
+@property (readwrite, weak) IBOutlet NSTextField *copyrightLabel;
+@property (readwrite, weak) IBOutlet NSTextField *copyrightTextField;
+@property (readwrite, weak) IBOutlet NSTextField *dateLabel;
+@property (readwrite, weak) IBOutlet NSTextField *dateTextField;
+@property (readwrite, weak) IBOutlet NSTextField *descriptionLabel;
+@property (readwrite, weak) IBOutlet NSTextField *descriptionTextField;
+@property (readwrite, weak) IBOutlet NSTextField *encodedbyLabel;
+@property (readwrite, weak) IBOutlet NSTextField *encodedbyTextField;
+@property (readwrite, weak) IBOutlet NSTextField *genreLabel;
+@property (readwrite, weak) IBOutlet NSTextField *genreTextField;
+@property (readwrite, weak) IBOutlet NSTextField *languageLabel;
+@property (readwrite, weak) IBOutlet NSTextField *languageTextField;
+@property (readwrite, weak) IBOutlet NSTextField *nowPlayingLabel;
+@property (readwrite, weak) IBOutlet NSTextField *nowPlayingTextField;
+@property (readwrite, weak) IBOutlet NSTextField *publisherLabel;
+@property (readwrite, weak) IBOutlet NSTextField *publisherTextField;
+@property (readwrite, weak) IBOutlet NSTextField *seqNumLabel;
+@property (readwrite, weak) IBOutlet NSTextField *seqNumTextField;
+@property (readwrite, weak) IBOutlet NSImageView *imageWell;
+@property (readwrite, weak) IBOutlet NSButton *saveMetaDataButton;
+
+@property (readwrite, weak) IBOutlet NSTextField *audioLabel;
+@property (readwrite, weak) IBOutlet NSTextField *audioDecodedLabel;
+@property (readwrite, weak) IBOutlet NSTextField *audioDecodedTextField;
+@property (readwrite, weak) IBOutlet NSTextField *demuxBitrateLabel;
+@property (readwrite, weak) IBOutlet NSTextField *demuxBitrateTextField;
+@property (readwrite, weak) IBOutlet NSTextField *demuxBytesLabel;
+@property (readwrite, weak) IBOutlet NSTextField *demuxBytesTextField;
+@property (readwrite, weak) IBOutlet NSTextField *displayedLabel;
+@property (readwrite, weak) IBOutlet NSTextField *displayedTextField;
+@property (readwrite, weak) IBOutlet NSTextField *inputBitrateLabel;
+@property (readwrite, weak) IBOutlet NSTextField *inputBitrateTextField;
+@property (readwrite, weak) IBOutlet NSTextField *inputLabel;
+@property (readwrite, weak) IBOutlet NSTextField *lostAudioBuffersLabel;
+@property (readwrite, weak) IBOutlet NSTextField *lostAudioBuffersTextField;
+@property (readwrite, weak) IBOutlet NSTextField *lostFramesLabel;
+@property (readwrite, weak) IBOutlet NSTextField *lostFramesTextField;
+@property (readwrite, weak) IBOutlet NSTextField *playedAudioBuffersLabel;
+@property (readwrite, weak) IBOutlet NSTextField *playedAudioBuffersTextField;
+@property (readwrite, weak) IBOutlet NSTextField *readBytesLabel;
+@property (readwrite, weak) IBOutlet NSTextField *readBytesTextField;
+@property (readwrite, weak) IBOutlet NSTextField *sentBitrateLabel;
+@property (readwrite, weak) IBOutlet NSTextField *sentBitrateTextField;
+@property (readwrite, weak) IBOutlet NSTextField *sentBytesLabel;
+@property (readwrite, weak) IBOutlet NSTextField *sentBytesTextField;
+@property (readwrite, weak) IBOutlet NSTextField *sentPacketsLabel;
+@property (readwrite, weak) IBOutlet NSTextField *sentPacketsTextField;
+@property (readwrite, weak) IBOutlet NSTextField *soutLabel;
+@property (readwrite, weak) IBOutlet NSTextField *videoLabel;
+@property (readwrite, weak) IBOutlet NSTextField *videoDecodedLabel;
+@property (readwrite, weak) IBOutlet NSTextField *videoDecodedTextField;
+
+- (void)updateCocoaWindowLevel:(NSInteger)i_level;
+- (void)initPanel;
+
+- (IBAction)metaFieldChanged:(id)sender;
+- (IBAction)saveMetaData:(id)sender;
+- (IBAction)downloadCoverArt:(id)sender;
+- (void)initMediaPanelStats;
+- (void)updatePanelWithItem:(input_item_t *)_p_item;
+- (void)setMeta:(char *)meta forLabel:(id)theItem;
+- (void)updateMetadata;
+- (void)updateStatistics;
+
++ (VLCInfo *)sharedInstance;
+@end
+
+@interface VLCInfoTreeItem : NSObject
+
+@property (readonly) int numberOfChildren;
+@property (readonly) NSString *name;
+@property (readonly) NSString *value;
+
+- (VLCInfoTreeItem *)childAtIndex:(NSUInteger)i_index;
+- (void)refresh;
+
+@end
diff --git a/modules/gui/macosx/VLCPlaylistInfo.m b/modules/gui/macosx/VLCPlaylistInfo.m
new file mode 100644 (file)
index 0000000..d0755e7
--- /dev/null
@@ -0,0 +1,531 @@
+/*****************************************************************************
+ * VLCPlaylistInfo.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2002-2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Benjamin Pracht <bigben at videolan dot org>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ ******************************************************************************/
+
+#import "CompatibilityFixes.h"
+#import "intf.h"
+#import "VLCPlaylistInfo.h"
+#import "VLCPlaylist.h"
+#import <vlc_url.h>
+
+@interface VLCInfo () <NSOutlineViewDataSource, NSOutlineViewDelegate>
+{
+    VLCInfoTreeItem *rootItem;
+
+    input_item_t *p_item;
+
+    BOOL b_nibLoaded;
+    BOOL b_awakeFromNib;
+    BOOL b_stats;
+}
+@end
+
+@implementation VLCInfo
+
++ (VLCInfo *)sharedInstance
+{
+    static VLCInfo *sharedInstance = nil;
+    static dispatch_once_t pred;
+
+    dispatch_once(&pred, ^{
+        sharedInstance = [VLCInfo new];
+    });
+
+    return sharedInstance;
+}
+
+- (void)awakeFromNib
+{
+    [_infoPanel setExcludedFromWindowsMenu: YES];
+    [_infoPanel setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
+
+    [_infoPanel setTitle: _NS("Media Information")];
+
+    _outlineView.dataSource = self;
+    _outlineView.delegate = self;
+
+    [_uriLabel setStringValue: _NS("Location")];
+    [_titleLabel setStringValue: _NS("Title")];
+    [_authorLabel setStringValue: _NS("Artist")];
+    [_saveMetaDataButton setStringValue: _NS("Save Metadata")];
+
+    [[_tabView tabViewItemAtIndex: 0] setLabel: _NS("General")];
+    [[_tabView tabViewItemAtIndex: 1] setLabel: _NS("Codec Details")];
+    [[_tabView tabViewItemAtIndex: 2] setLabel: _NS("Statistics")];
+    [_tabView selectTabViewItemAtIndex: 0];
+
+    /* constants defined in vlc_meta.h */
+    [_genreLabel setStringValue: _NS(VLC_META_GENRE)];
+    [_copyrightLabel setStringValue: _NS(VLC_META_COPYRIGHT)];
+    [_collectionLabel setStringValue: _NS(VLC_META_ALBUM)];
+    [_seqNumLabel setStringValue: _NS(VLC_META_TRACK_NUMBER)];
+    [_descriptionLabel setStringValue: _NS(VLC_META_DESCRIPTION)];
+    [_dateLabel setStringValue: _NS(VLC_META_DATE)];
+    [_languageLabel setStringValue: _NS(VLC_META_LANGUAGE)];
+    [_nowPlayingLabel setStringValue: _NS(VLC_META_NOW_PLAYING)];
+    [_publisherLabel setStringValue: _NS(VLC_META_PUBLISHER)];
+    [_encodedbyLabel setStringValue: _NS(VLC_META_ENCODED_BY)];
+
+    /* statistics */
+    [_inputLabel setStringValue: _NS("Input")];
+    [_readBytesLabel setStringValue: _NS("Read at media")];
+    [_inputBitrateLabel setStringValue: _NS("Input bitrate")];
+    [_demuxBytesLabel setStringValue: _NS("Demuxed")];
+    [_demuxBitrateLabel setStringValue: _NS("Stream bitrate")];
+
+    [_videoLabel setStringValue: _NS("Video")];
+    [_videoDecodedLabel setStringValue: _NS("Decoded blocks")];
+    [_displayedLabel setStringValue: _NS("Displayed frames")];
+    [_lostFramesLabel setStringValue: _NS("Lost frames")];
+
+    [_soutLabel setStringValue: _NS("Streaming")];
+    [_sentPacketsLabel setStringValue: _NS("Sent packets")];
+    [_sentBytesLabel setStringValue: _NS("Sent bytes")];
+    [_sentBitrateLabel setStringValue: _NS("Send rate")];
+
+    [_audioLabel setStringValue: _NS("Audio")];
+    [_audioDecodedLabel setStringValue: _NS("Decoded blocks")];
+    [_playedAudioBuffersLabel setStringValue: _NS("Played buffers")];
+    [_lostAudioBuffersLabel setStringValue: _NS("Lost buffers")];
+
+    [_infoPanel setInitialFirstResponder: _uriLabel];
+
+    b_awakeFromNib = YES;
+
+    /* We may be awoken from nib way after initialisation
+     *Update ourselves */
+    [self updatePanelWithItem:p_item];
+}
+
+
+- (void)dealloc
+{
+    if (p_item)
+        vlc_gc_decref(p_item);
+}
+
+- (void)updateCocoaWindowLevel:(NSInteger)i_level
+{
+    if (_infoPanel && [_infoPanel isVisible] && [_infoPanel level] != i_level)
+        [_infoPanel setLevel: i_level];
+}
+
+- (void)initPanel
+{
+    if (!b_nibLoaded)
+        b_nibLoaded = [NSBundle loadNibNamed:@"MediaInfo" owner: self];
+
+    b_stats = var_InheritBool(VLCIntf, "stats");
+    if (!b_stats) {
+        if ([_tabView numberOfTabViewItems] > 2)
+            [_tabView removeTabViewItem: [_tabView tabViewItemAtIndex: 2]];
+    }
+    else
+        [self initMediaPanelStats];
+
+    NSInteger i_level = [[[VLCMain sharedInstance] voutController] currentStatusWindowLevel];
+    [_infoPanel setLevel: i_level];
+    [_infoPanel makeKeyAndOrderFront:nil];
+}
+
+- (void)initMediaPanelStats
+{
+    //Initializing Input Variables
+    [_readBytesTextField setStringValue: [NSString stringWithFormat:_NS("%.1f KiB"), (float)0]];
+    [_inputBitrateTextField setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]];
+    [_demuxBytesTextField setStringValue: [NSString stringWithFormat:_NS("%.1f KiB"), (float)0]];
+    [_demuxBitrateTextField setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]];
+
+    //Initializing Video Variables
+    [_videoDecodedTextField setIntValue:0];
+    [_displayedTextField setIntValue:0];
+    [_lostFramesTextField setIntValue:0];
+
+    //Initializing Output Variables
+    [_sentPacketsTextField setIntValue: 0];
+    [_sentBytesTextField setStringValue: [NSString stringWithFormat:_NS("%.1f KiB"), (float)0]];
+    [_sentBitrateTextField setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]];
+
+    //Initializing Audio Variables
+    [_audioDecodedTextField setIntValue:0];
+    [_playedAudioBuffersTextField setIntValue: 0];
+    [_lostAudioBuffersTextField setIntValue: 0];
+}
+
+- (void)updateMetadata
+{
+    if (!p_item)
+        return;
+
+    [self updatePanelWithItem:p_item];
+}
+
+- (void)updatePanelWithItem:(input_item_t *)_p_item;
+{
+    @autoreleasepool {
+        rootItem = [[VLCInfoTreeItem alloc] init];
+
+        if (_p_item != p_item) {
+            if (p_item)
+                vlc_gc_decref(p_item);
+            [_saveMetaDataButton setEnabled: NO];
+            if (_p_item)
+                vlc_gc_incref(_p_item);
+            p_item = _p_item;
+        }
+
+        if (!p_item) {
+            /* Erase */
+        #define SET( foo ) \
+            [self setMeta: "" forLabel: _##foo##TextField];
+            SET( uri );
+            SET( title );
+            SET( author );
+            SET( collection );
+            SET( seqNum );
+            SET( genre );
+            SET( copyright );
+            SET( publisher );
+            SET( nowPlaying );
+            SET( language );
+            SET( date );
+            SET( description );
+            SET( encodedby );
+        #undef SET
+            [_imageWell setImage: [NSImage imageNamed: @"noart.png"]];
+        } else {
+            if (!input_item_IsPreparsed(p_item))
+                libvlc_MetaRequest(VLCIntf->p_libvlc, p_item, META_REQUEST_OPTION_NONE);
+
+            /* fill uri info */
+            char *psz_url = decode_URI(input_item_GetURI(p_item));
+            [_uriTextField setStringValue:toNSStr(psz_url)];
+            free(psz_url);
+
+            /* fill title info */
+            char *psz_title = input_item_GetTitle(p_item);
+            if (!psz_title)
+                psz_title = input_item_GetName(p_item);
+            [_titleTextField setStringValue:toNSStr(psz_title)];
+            free(psz_title);
+
+        #define SET( foo, bar ) \
+            char *psz_##foo = input_item_Get##bar ( p_item ); \
+            [self setMeta: psz_##foo forLabel: _##foo##TextField]; \
+            FREENULL( psz_##foo );
+
+            /* fill the other fields */
+            SET( author, Artist );
+            SET( collection, Album );
+            SET( seqNum, TrackNum );
+            SET( genre, Genre );
+            SET( copyright, Copyright );
+            SET( publisher, Publisher );
+            SET( nowPlaying, NowPlaying );
+            SET( language, Language );
+            SET( date, Date );
+            SET( description, Description );
+            SET( encodedby, EncodedBy );
+
+        #undef SET
+
+            char *psz_meta;
+            NSImage *image;
+            psz_meta = input_item_GetArtURL(p_item);
+
+            /* FIXME Can also be attachment:// */
+            if (psz_meta && strncmp(psz_meta, "attachment://", 13))
+                image = [[NSImage alloc] initWithContentsOfURL: [NSURL URLWithString:toNSStr(psz_meta)]];
+            else
+                image = [NSImage imageNamed: @"noart.png"];
+            [_imageWell setImage: image];
+            FREENULL(psz_meta);
+        }
+
+        /* reload the advanced table */
+        [rootItem refresh];
+        [_outlineView reloadData];
+        [_outlineView expandItem:nil expandChildren:YES];
+
+        /* update the stats once to display p_item change faster */
+        [self updateStatistics];
+    }
+}
+
+- (void)setMeta: (char *)psz_meta forLabel: (id)theItem
+{
+    if (psz_meta != NULL && *psz_meta)
+        [theItem setStringValue: toNSStr(psz_meta)];
+    else
+        [theItem setStringValue: @""];
+}
+
+- (void)updateStatistics
+{
+    if (!b_awakeFromNib || !b_stats)
+        return;
+
+    if ([_infoPanel isVisible]) {
+        if (!p_item || !p_item->p_stats) {
+            [self initMediaPanelStats];
+            return;
+        }
+
+        vlc_mutex_lock(&p_item->p_stats->lock);
+
+        /* input */
+        [_readBytesTextField setStringValue: [NSString stringWithFormat:
+            @"%8.0f KiB", (float)(p_item->p_stats->i_read_bytes)/1024]];
+        [_inputBitrateTextField setStringValue: [NSString stringWithFormat:
+            @"%6.0f kb/s", (float)(p_item->p_stats->f_input_bitrate)*8000]];
+        [_demuxBytesTextField setStringValue: [NSString stringWithFormat:
+            @"%8.0f KiB", (float)(p_item->p_stats->i_demux_read_bytes)/1024]];
+        [_demuxBitrateTextField setStringValue: [NSString stringWithFormat:
+            @"%6.0f kb/s", (float)(p_item->p_stats->f_demux_bitrate)*8000]];
+
+        /* Video */
+        [_videoDecodedTextField setIntValue: p_item->p_stats->i_decoded_video];
+        [_displayedTextField setIntValue: p_item->p_stats->i_displayed_pictures];
+        [_lostFramesTextField setIntValue: p_item->p_stats->i_lost_pictures];
+
+        /* Sout */
+        [_sentPacketsTextField setIntValue: p_item->p_stats->i_sent_packets];
+        [_sentBytesTextField setStringValue: [NSString stringWithFormat: @"%8.0f KiB",
+            (float)(p_item->p_stats->i_sent_bytes)/1024]];
+        [_sentBitrateTextField setStringValue: [NSString stringWithFormat:
+            @"%6.0f kb/s", (float)(p_item->p_stats->f_send_bitrate*8)*1000]];
+
+        /* Audio */
+        [_audioDecodedTextField setIntValue: p_item->p_stats->i_decoded_audio];
+        [_playedAudioBuffersTextField setIntValue: p_item->p_stats->i_played_abuffers];
+        [_lostAudioBuffersTextField setIntValue: p_item->p_stats->i_lost_abuffers];
+
+        vlc_mutex_unlock(&p_item->p_stats->lock);
+    }
+}
+
+- (IBAction)metaFieldChanged:(id)sender
+{
+    [_saveMetaDataButton setEnabled: YES];
+}
+
+- (IBAction)saveMetaData:(id)sender
+{
+    if (!p_item)
+        goto error;
+
+    #define utf8( _blub ) \
+        [[_blub stringValue] UTF8String]
+
+    input_item_SetName( p_item, utf8( _titleTextField ) );
+    input_item_SetTitle( p_item, utf8( _titleTextField ) );
+    input_item_SetArtist( p_item, utf8( _authorTextField ) );
+    input_item_SetAlbum( p_item, utf8( _collectionTextField ) );
+    input_item_SetGenre( p_item, utf8( _genreTextField ) );
+    input_item_SetTrackNum( p_item, utf8( _seqNumTextField ) );
+    input_item_SetDate( p_item, utf8( _dateTextField ) );
+    input_item_SetCopyright( p_item, utf8( _copyrightTextField ) );
+    input_item_SetPublisher( p_item, utf8( _publisherTextField ) );
+    input_item_SetDescription( p_item, utf8( _descriptionTextField ) );
+    input_item_SetLanguage( p_item, utf8( _languageTextField ) );
+
+    playlist_t *p_playlist = pl_Get(VLCIntf);
+    input_item_WriteMeta(VLC_OBJECT(p_playlist), p_item);
+
+    var_SetBool(p_playlist, "intf-change", true);
+    [self updatePanelWithItem: p_item];
+
+    [_saveMetaDataButton setEnabled: NO];
+    return;
+
+error:
+    NSRunAlertPanel(_NS("Error while saving meta"),
+        @"%@",_NS("VLC was unable to save the meta data."),
+        _NS("OK"), nil, nil);
+}
+
+- (IBAction)downloadCoverArt:(id)sender
+{
+    playlist_t *p_playlist = pl_Get(VLCIntf);
+    if (p_item) libvlc_ArtRequest(VLCIntf->p_libvlc, p_item, META_REQUEST_OPTION_NONE);
+}
+
+- (input_item_t *)item
+{
+    if (p_item) vlc_gc_incref(p_item);
+    return p_item;
+}
+
+@end
+
+@implementation VLCInfo (NSMenuValidation)
+
+- (BOOL)validateMenuItem:(NSMenuItem *)mi
+{
+    if ([[mi title] isEqualToString: _NS("Information")]) {
+        return ![[[VLCMain sharedInstance] playlist] isSelectionEmpty];
+    }
+
+    return TRUE;
+}
+
+@end
+
+@implementation VLCInfo (NSTableDataSource)
+
+- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
+{
+    return (item == nil) ? [rootItem numberOfChildren] : [item numberOfChildren];
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
+    return ([item numberOfChildren] > 0);
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
+{
+    return (item == nil) ? [rootItem childAtIndex:index] : (id)[item childAtIndex:index];
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
+{
+    if ([[tableColumn identifier] isEqualToString:@"0"])
+        return (item == nil) ? @"" : (id)[item name];
+    else
+        return (item == nil) ? @"" : (id)[item value];
+}
+
+@end
+
+@interface VLCInfoTreeItem ()
+{
+    int i_object_id;
+    input_item_t *p_item;
+    VLCInfoTreeItem *_parent;
+    NSMutableArray *_children;
+    BOOL _isALeafNode;
+}
+
+@end
+
+@implementation VLCInfoTreeItem
+
+- (id)initWithName:(NSString *)item_name
+             value:(NSString *)item_value
+                ID:(int)i_id
+            parent:(VLCInfoTreeItem *)parent_item
+{
+    self = [super init];
+
+    if (self != nil) {
+        _name = [item_name copy];
+        _value = [item_value copy];
+        i_object_id = i_id;
+        _parent = parent_item;
+        p_item = [[VLCInfo sharedInstance] item];
+    }
+    return self;
+}
+
+- (id)init
+{
+    return [self initWithName:@"main" value:@"" ID:-1 parent:nil];
+}
+
+- (void)dealloc
+{
+    if (p_item)
+        vlc_gc_decref(p_item);
+}
+
+/* Creates and returns the array of children
+ *Loads children incrementally */
+- (void)_updateChildren
+{
+    if (!p_item)
+        return;
+
+    if (_children != nil)
+        return;
+
+    _children = [[NSMutableArray alloc] init];
+    if (i_object_id == -1) {
+        vlc_mutex_lock(&p_item->lock);
+        for (int i = 0 ; i < p_item->i_categories ; i++) {
+            NSString *name = toNSStr(p_item->pp_categories[i]->psz_name);
+            VLCInfoTreeItem *item = [[VLCInfoTreeItem alloc]
+                                      initWithName:name
+                                      value:@""
+                                      ID:i
+                                      parent:self];
+            [_children addObject:item];
+        }
+        vlc_mutex_unlock(&p_item->lock);
+        _isALeafNode = NO;
+    }
+    else if (_parent->i_object_id == -1) {
+        vlc_mutex_lock(&p_item->lock);
+        info_category_t *cat = p_item->pp_categories[i_object_id];
+        for (int i = 0 ; i < cat->i_infos ; i++) {
+            NSString *name = toNSStr(cat->pp_infos[i]->psz_name);
+            NSString *value  = toNSStr(cat->pp_infos[i]->psz_value);
+            VLCInfoTreeItem *item = [[VLCInfoTreeItem alloc]
+                                     initWithName:name
+                                     value:value
+                                     ID:i
+                                     parent:self];
+            [_children addObject:item];
+        }
+        vlc_mutex_unlock(&p_item->lock);
+        _isALeafNode = NO;
+    }
+    else
+        _isALeafNode = YES;
+}
+
+- (void)refresh
+{
+    if (p_item)
+        vlc_gc_decref(p_item);
+
+    p_item = [[VLCInfo sharedInstance] item];
+
+    _children = nil;
+}
+
+- (VLCInfoTreeItem *)childAtIndex:(NSUInteger)i_index
+{
+    return [_children objectAtIndex:i_index];
+}
+
+- (int)numberOfChildren
+{
+    [self _updateChildren];
+
+    if (_isALeafNode)
+        return -1;
+
+    return [_children count];
+}
+
+@end
diff --git a/modules/gui/macosx/VLCPlaylistView.h b/modules/gui/macosx/VLCPlaylistView.h
new file mode 100644 (file)
index 0000000..83f2a19
--- /dev/null
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * VLCPlaylistView.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2002-2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Derk-Jan Hartman <hartman at videolan dot org>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+@interface VLCPlaylistView : NSOutlineView
+
+@end
diff --git a/modules/gui/macosx/VLCPlaylistView.m b/modules/gui/macosx/VLCPlaylistView.m
new file mode 100644 (file)
index 0000000..132d86f
--- /dev/null
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * VLCPlaylistView.m: MacOS X interface module
+ *****************************************************************************
+* Copyright (C) 2003-2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Derk-Jan Hartman <hartman at videola/n dot org>
+ *          Benjamin Pracht <bigben at videolab dot org>
+ *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "intf.h"
+#import "VLCPlaylistView.h"
+#import "VLCPlaylist.h"
+
+@implementation VLCPlaylistView
+
+- (NSMenu *)menuForEvent:(NSEvent *)event
+{
+    return([(VLCPlaylist *)[self delegate] menuForEvent: event]);
+}
+
+- (void)keyDown:(NSEvent *)event
+{
+    unichar key = 0;
+
+    if ([[event characters] length])
+        key = [[event characters] characterAtIndex: 0];
+
+    switch(key) {
+        case NSDeleteCharacter:
+        case NSDeleteFunctionKey:
+        case NSDeleteCharFunctionKey:
+        case NSBackspaceCharacter:
+            [(VLCPlaylist *)[self delegate] deleteItem:self];
+            break;
+
+        case NSEnterCharacter:
+        case NSCarriageReturnCharacter:
+            [(VLCPlaylist *)[[VLCMain sharedInstance] playlist] playItem:nil];
+            break;
+
+        default:
+            [super keyDown: event];
+            break;
+    }
+}
+
+- (BOOL)validateMenuItem:(NSMenuItem *)item
+{
+    if (([self numberOfSelectedRows] >= 1 && [item action] == @selector(delete:)) || [item action] == @selector(selectAll:))
+        return YES;
+
+    return NO;
+}
+
+- (BOOL)acceptsFirstResponder
+{
+    return YES;
+}
+
+- (BOOL)becomeFirstResponder
+{
+    [self setNeedsDisplay:YES];
+    return YES;
+}
+
+- (BOOL)resignFirstResponder
+{
+    [self setNeedsDisplay:YES];
+    return YES;
+}
+
+- (IBAction)delete:(id)sender
+{
+    [[[VLCMain sharedInstance] playlist] deleteItem: sender];
+}
+
+@end
index 9db2312..bbd1a84 100644 (file)
 
 #import "VideoEffects.h"
 #import "AudioEffects.h"
-#import "playlistinfo.h"
+#import "VLCPlaylistInfo.h"
 #import "bookmarks.h"
 #import "TrackSynchronization.h"
 #import "ResumeDialogController.h"
-#import "playlist.h"
+#import "VLCPlaylist.h"
 
 static atomic_bool b_intf_starting = ATOMIC_VAR_INIT(false);
 
index 3fa7fae..296c5e6 100644 (file)
@@ -28,7 +28,7 @@
 #import "intf.h"
 #import "applescript.h"
 #import "CoreInteraction.h"
-#import "playlist.h"
+#import "VLCPlaylist.h"
 #import <vlc_url.h>
 
 /*****************************************************************************
index dd9bc66..96fb2e7 100644 (file)
@@ -47,8 +47,8 @@
 #import "MainMenu.h"
 #import "VideoView.h"
 #import "prefs.h"
-#import "playlist.h"
-#import "playlistinfo.h"
+#import "VLCPlaylist.h"
+#import "VLCPlaylistInfo.h"
 #import "open.h"
 #import "bookmarks.h"
 #import "coredialogs.h"
index d84f47d..73b88ac 100644 (file)
@@ -36,7 +36,7 @@
 #import <QTKit/QTKit.h>
 
 #import "intf.h"
-#import "playlist.h"
+#import "VLCPlaylist.h"
 #import "open.h"
 #import "output.h"
 #import "eyetv.h"
diff --git a/modules/gui/macosx/playlist.h b/modules/gui/macosx/playlist.h
deleted file mode 100644 (file)
index b111aff..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*****************************************************************************
- * playlist.h: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2002-2015 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Benjamin Pracht <bigben at videolab dot org>
- *          Felix Paul Kühne <fkuehne at videolan dot org>
- *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#import "PXSourceList.h"
-#import "PLModel.h"
-#import "playlistview.h"
-
-@interface VLCPlaylist : NSObject<NSOutlineViewDelegate>
-
-@property (readwrite, weak) IBOutlet NSMenu *playlistMenu;
-@property (readwrite, weak) IBOutlet NSMenuItem *playPlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *deletePlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *infoPlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *preparsePlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *revealInFinderPlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *downloadCoverArtPlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *selectAllPlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *sortNamePlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *sortAuthorPlaylistMenuItem;
-@property (readwrite, weak) IBOutlet NSMenuItem *recursiveExpandPlaylistMenuItem;
-
-@property (nonatomic, readwrite, weak) VLCPlaylistView *outlineView;
-@property (nonatomic, readwrite, weak) NSTableHeaderView *playlistHeaderView;
-
-- (PLModel *)model;
-
-- (void)reloadStyles;
-
-- (NSMenu *)menuForEvent:(NSEvent *)o_event;
-
-- (void)playlistUpdated;
-- (void)playbackModeUpdated;
-- (void)updateTogglePlaylistState;
-- (void)outlineViewSelectionDidChange:(NSNotification *)notification;
-- (void)sortNode:(int)i_mode;
-
-- (void)currentlyPlayingItemChanged;
-
-- (BOOL)isSelectionEmpty;
-
-- (IBAction)playItem:(id)sender;
-- (IBAction)revealItemInFinder:(id)sender;
-- (IBAction)preparseItem:(id)sender;
-- (IBAction)downloadCoverArt:(id)sender;
-- (IBAction)deleteItem:(id)sender;
-- (IBAction)selectAll:(id)sender;
-- (IBAction)sortNodeByName:(id)sender;
-- (IBAction)sortNodeByAuthor:(id)sender;
-- (IBAction)recursiveExpandNode:(id)sender;
-- (IBAction)showInfoPanel:(id)sender;
-
-- (NSArray *)draggedItems;
-
-/**
- * Simplified version to add new items at the end of the current playlist
- */
-- (void)addPlaylistItems:(NSArray*)o_array;
-
-/**
- * Adds new items to the playlist, at specified parent node and index.
- * @param o_array array of items. Each item is a Dictionary with meta info.
- * @param i_plItemId parent playlist node id, -1 for default playlist
- * @param i_position index for new items, -1 for appending at end
- * @param b_start starts playback of first item if true
- */
-- (void)addPlaylistItems:(NSArray*)o_array withParentItemId:(int)i_plItemId atPos:(int)i_position startPlayback:(BOOL)b_start;
-
-
-- (void)setColumn: (NSString *)o_column state: (NSInteger)i_state translationDict:(NSDictionary *)o_dict;
-- (void)continuePlaybackWhereYouLeftOff:(input_thread_t *)p_input_thread;
-- (void)storePlaybackPositionForItem:(input_thread_t *)p_input_thread;
-
-@end
diff --git a/modules/gui/macosx/playlist.m b/modules/gui/macosx/playlist.m
deleted file mode 100644 (file)
index 923253d..0000000
+++ /dev/null
@@ -1,866 +0,0 @@
-/*****************************************************************************
- * playlist.m: MacOS X interface module
- *****************************************************************************
-* Copyright (C) 2002-2015 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Derk-Jan Hartman <hartman at videola/n dot org>
- *          Benjamin Pracht <bigben at videolan dot org>
- *          Felix Paul Kühne <fkuehne at videolan dot org>
- *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/* TODO
- * add 'icons' for different types of nodes? (http://www.cocoadev.com/index.pl?IconAndTextInTableCell)
- * reimplement enable/disable item
- */
-
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <sys/param.h>                                    /* for MAXPATHLEN */
-#include <string.h>
-#include <math.h>
-#include <sys/mount.h>
-
-#import "CompatibilityFixes.h"
-
-#import "intf.h"
-#import "playlist.h"
-#import "MainMenu.h"
-#import "playlistinfo.h"
-#import "ResumeDialogController.h"
-
-#include <vlc_keys.h>
-#import <vlc_interface.h>
-#include <vlc_url.h>
-
-/*****************************************************************************
- * An extension to NSOutlineView's interface to fix compilation warnings
- * and let us access these 2 functions properly.
- * This uses a private API, but works fine on all current OSX releases.
- * Radar ID 11739459 request a public API for this. However, it is probably
- * easier and faster to recreate similar looking bitmaps ourselves.
- *****************************************************************************/
-
-@interface NSOutlineView (UndocumentedSortImages)
-+ (NSImage *)_defaultTableHeaderSortImage;
-+ (NSImage *)_defaultTableHeaderReverseSortImage;
-@end
-
-@interface VLCPlaylist ()
-{
-    NSImage *_descendingSortingImage;
-    NSImage *_ascendingSortingImage;
-
-    BOOL b_selected_item_met;
-    BOOL b_isSortDescending;
-    NSTableColumn *_sortTableColumn;
-
-    BOOL b_playlistmenu_nib_loaded;
-    BOOL b_view_setup;
-
-    PLModel *_model;
-}
-
-- (void)saveTableColumns;
-@end
-
-@implementation VLCPlaylist
-
-+ (void)initialize
-{
-    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-    NSMutableArray *columnArray = [[NSMutableArray alloc] init];
-    [columnArray addObject: [NSArray arrayWithObjects:TITLE_COLUMN, [NSNumber numberWithFloat:190.], nil]];
-    [columnArray addObject: [NSArray arrayWithObjects:ARTIST_COLUMN, [NSNumber numberWithFloat:95.], nil]];
-    [columnArray addObject: [NSArray arrayWithObjects:DURATION_COLUMN, [NSNumber numberWithFloat:95.], nil]];
-
-    NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
-                                 [NSArray arrayWithArray:columnArray], @"PlaylistColumnSelection",
-                                 [NSArray array], @"recentlyPlayedMediaList",
-                                 [NSDictionary dictionary], @"recentlyPlayedMedia", nil];
-
-    [defaults registerDefaults:appDefaults];
-}
-
-- (PLModel *)model
-{
-    return _model;
-}
-
-- (void)reloadStyles
-{
-    NSFont *fontToUse;
-    CGFloat rowHeight;
-    if (var_InheritBool(VLCIntf, "macosx-large-text")) {
-        fontToUse = [NSFont systemFontOfSize:13.];
-        rowHeight = 21.;
-    } else {
-        fontToUse = [NSFont systemFontOfSize:11.];
-        rowHeight = 16.;
-    }
-
-    NSArray *columns = [_outlineView tableColumns];
-    NSUInteger count = columns.count;
-    for (NSUInteger x = 0; x < count; x++)
-        [[columns[x] dataCell] setFont:fontToUse];
-    [_outlineView setRowHeight:rowHeight];
-}
-
-- (void)awakeFromNib
-{
-    if (b_view_setup)
-        return;
-
-    [self reloadStyles];
-    [self initStrings];
-
-    /* This uses a private API, but works fine on all current OSX releases.
-     * Radar ID 11739459 request a public API for this. However, it is probably
-     * easier and faster to recreate similar looking bitmaps ourselves. */
-    _ascendingSortingImage = [[NSOutlineView class] _defaultTableHeaderSortImage];
-    _descendingSortingImage = [[NSOutlineView class] _defaultTableHeaderReverseSortImage];
-
-    _sortTableColumn = nil;
-
-    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(applicationWillTerminate:) name: NSApplicationWillTerminateNotification object: nil];
-
-    b_view_setup = YES;
-}
-
-- (void)setOutlineView:(VLCPlaylistView * __nullable)outlineView
-{
-    _outlineView = outlineView;
-    [_outlineView setDelegate:self];
-
-    playlist_t * p_playlist = pl_Get(VLCIntf);
-
-    _model = [[PLModel alloc] initWithOutlineView:_outlineView playlist:p_playlist rootItem:p_playlist->p_playing playlistObject:self];
-    [_outlineView setDataSource:_model];
-    [_outlineView reloadData];
-
-    [_outlineView setTarget: self];
-    [_outlineView setDoubleAction: @selector(playItem:)];
-
-    [_outlineView setAllowsEmptySelection: NO];
-    [_outlineView registerForDraggedTypes: [NSArray arrayWithObjects:NSFilenamesPboardType, @"VLCPlaylistItemPboardType", nil]];
-    [_outlineView setIntercellSpacing: NSMakeSize (0.0, 1.0)];
-}
-
-- (void)setPlaylistHeaderView:(NSTableHeaderView * __nullable)playlistHeaderView
-{
-    VLCMainMenu *mainMenu = [[VLCMain sharedInstance] mainMenu];
-    _playlistHeaderView = playlistHeaderView;
-    NSMenu *contextMenu = [mainMenu setupPlaylistTableColumnsMenu];
-    [_playlistHeaderView setMenu: contextMenu];
-
-    NSArray * columnArray = [[NSUserDefaults standardUserDefaults] arrayForKey:@"PlaylistColumnSelection"];
-    NSUInteger columnCount = [columnArray count];
-    NSString * column;
-
-    for (NSUInteger i = 0; i < columnCount; i++) {
-        column = [columnArray[i] firstObject];
-        if ([column isEqualToString:@"status"])
-            continue;
-
-        if(![mainMenu setPlaylistColumnTableState: NSOnState forColumn:column])
-            continue;
-
-        [[_outlineView tableColumnWithIdentifier: column] setWidth: [columnArray[i][1] floatValue]];
-    }
-}
-
-- (void)applicationWillTerminate:(NSNotification *)notification
-{
-    /* let's make sure we save the correct widths and positions, since this likely changed since the last time the user played with the column selection */
-    [self saveTableColumns];
-}
-
-- (void)initStrings
-{
-    [_playPlaylistMenuItem setTitle: _NS("Play")];
-    [_deletePlaylistMenuItem setTitle: _NS("Delete")];
-    [_recursiveExpandPlaylistMenuItem setTitle: _NS("Expand Node")];
-    [_selectAllPlaylistMenuItem setTitle: _NS("Select All")];
-    [_infoPlaylistMenuItem setTitle: _NS("Media Information...")];
-    [_downloadCoverArtPlaylistMenuItem setTitle: _NS("Download Cover Art")];
-    [_preparsePlaylistMenuItem setTitle: _NS("Fetch Meta Data")];
-    [_revealInFinderPlaylistMenuItem setTitle: _NS("Reveal in Finder")];
-    [_sortNamePlaylistMenuItem setTitle: _NS("Sort Node by Name")];
-    [_sortAuthorPlaylistMenuItem setTitle: _NS("Sort Node by Author")];
-}
-
-- (void)playlistUpdated
-{
-    [_outlineView reloadData];
-}
-
-- (void)playbackModeUpdated
-{
-    [_model playbackModeUpdated];
-}
-
-- (void)updateTogglePlaylistState
-{
-    [self outlineViewSelectionDidChange: NULL];
-}
-
-- (void)outlineViewSelectionDidChange:(NSNotification *)notification
-{
-//    // FIXME: unsafe
-//    playlist_item_t * p_item = [[_outlineView itemAtRow:[_outlineView selectedRow]] pointerValue];
-//
-//    if (p_item) {
-//        /* update the state of our Reveal-in-Finder menu items */
-//        NSMutableString *o_mrl;
-//        char *psz_uri = input_item_GetURI(p_item->p_input);
-//
-//        [o_mi_revealInFinder setEnabled: NO];
-//        [o_mm_mi_revealInFinder setEnabled: NO];
-//        if (psz_uri) {
-//            o_mrl = [NSMutableString stringWithUTF8String: psz_uri];
-//
-//            /* perform some checks whether it is a file and if it is local at all... */
-//            NSRange prefix_range = [o_mrl rangeOfString: @"file:"];
-//            if (prefix_range.location != NSNotFound)
-//                [o_mrl deleteCharactersInRange: prefix_range];
-//
-//            if ([o_mrl characterAtIndex:0] == '/') {
-//                [o_mi_revealInFinder setEnabled: YES];
-//                [o_mm_mi_revealInFinder setEnabled: YES];
-//            }
-//            free(psz_uri);
-//        }
-//
-//        /* update our info-panel to reflect the new item */
-//        [[VLCInfo sharedInstance] updatePanelWithItem:p_item->p_input];
-//    }
-}
-
-- (BOOL)isSelectionEmpty
-{
-    return [_outlineView selectedRow] == -1;
-}
-
-- (void)currentlyPlayingItemChanged
-{
-    PLItem *item = [[self model] currentlyPlayingItem];
-    if (!item)
-        return;
-
-    // select item
-    NSInteger itemIndex = [_outlineView rowForItem:item];
-    if (itemIndex < 0) {
-        // expand if needed
-        while (item != nil) {
-            PLItem *parent = [item parent];
-
-            if (![_outlineView isExpandable: parent])
-                break;
-            if (![_outlineView isItemExpanded: parent])
-                [_outlineView expandItem: parent];
-            item = parent;
-        }
-
-        // search for row again
-        itemIndex = [_outlineView rowForItem:item];
-        if (itemIndex < 0) {
-            return;
-        }
-    }
-
-    [_outlineView selectRowIndexes: [NSIndexSet indexSetWithIndex: itemIndex] byExtendingSelection: NO];
-}
-
-/* When called retrieves the selected outlineview row and plays that node or item */
-- (IBAction)playItem:(id)sender
-{
-    playlist_t *p_playlist = pl_Get(VLCIntf);
-
-    // ignore clicks on column header when handling double action
-    if (sender == _outlineView && [_outlineView clickedRow] == -1)
-        return;
-
-    PLItem *o_item = [_outlineView itemAtRow:[_outlineView selectedRow]];
-    if (!o_item)
-        return;
-
-    PL_LOCK;
-    playlist_item_t *p_item = playlist_ItemGetById(p_playlist, [o_item plItemId]);
-    playlist_item_t *p_node = playlist_ItemGetById(p_playlist, [[[self model] rootItem] plItemId]);
-
-    if (p_item && p_node) {
-        playlist_Control(p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, p_node, p_item);
-    }
-    PL_UNLOCK;
-}
-
-- (IBAction)revealItemInFinder:(id)sender
-{
-    NSIndexSet *selectedRows = [_outlineView selectedRowIndexes];
-    [selectedRows enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
-
-        PLItem *o_item = [_outlineView itemAtRow:idx];
-
-        /* perform some checks whether it is a file and if it is local at all... */
-        char *psz_url = input_item_GetURI([o_item input]);
-        NSURL *url = [NSURL URLWithString:toNSStr(psz_url)];
-        free(psz_url);
-        if (![url isFileURL])
-            return;
-        if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]])
-            return;
-
-        msg_Dbg(VLCIntf, "Reveal url %s in finder", [[url path] UTF8String]);
-        [[NSWorkspace sharedWorkspace] selectFile: [url path] inFileViewerRootedAtPath: [url path]];
-    }];
-
-}
-
-/* When called retrieves the selected outlineview row and plays that node or item */
-- (IBAction)preparseItem:(id)sender
-{
-    int i_count;
-    NSIndexSet *o_selected_indexes;
-    intf_thread_t * p_intf = VLCIntf;
-    playlist_t * p_playlist = pl_Get(p_intf);
-    playlist_item_t *p_item = NULL;
-
-    o_selected_indexes = [_outlineView selectedRowIndexes];
-    i_count = [o_selected_indexes count];
-
-    NSUInteger indexes[i_count];
-    [o_selected_indexes getIndexes:indexes maxCount:i_count inIndexRange:nil];
-    for (int i = 0; i < i_count; i++) {
-        PLItem *o_item = [_outlineView itemAtRow:indexes[i]];
-        [_outlineView deselectRow: indexes[i]];
-
-        if (![o_item isLeaf]) {
-            msg_Dbg(p_intf, "preparsing nodes not implemented");
-            continue;
-        }
-
-        libvlc_MetaRequest(p_intf->p_libvlc, [o_item input], META_REQUEST_OPTION_NONE);
-
-    }
-    [self playlistUpdated];
-}
-
-- (IBAction)downloadCoverArt:(id)sender
-{
-    int i_count;
-    NSIndexSet *o_selected_indexes;
-    intf_thread_t * p_intf = VLCIntf;
-    playlist_t * p_playlist = pl_Get(p_intf);
-    playlist_item_t *p_item = NULL;
-
-    o_selected_indexes = [_outlineView selectedRowIndexes];
-    i_count = [o_selected_indexes count];
-
-    NSUInteger indexes[i_count];
-    [o_selected_indexes getIndexes:indexes maxCount:i_count inIndexRange:nil];
-    for (int i = 0; i < i_count; i++) {
-        PLItem *o_item = [_outlineView itemAtRow: indexes[i]];
-
-        if (![o_item isLeaf])
-            continue;
-
-        libvlc_ArtRequest(p_intf->p_libvlc, [o_item input], META_REQUEST_OPTION_NONE);
-    }
-    [self playlistUpdated];
-}
-
-- (IBAction)selectAll:(id)sender
-{
-    [_outlineView selectAll: nil];
-}
-
-- (IBAction)showInfoPanel:(id)sender
-{
-    [[VLCInfo sharedInstance] initPanel];
-}
-
-- (IBAction)deleteItem:(id)sender
-{
-    [_model deleteSelectedItem];
-}
-
-- (IBAction)sortNodeByName:(id)sender
-{
-    [self sortNode: SORT_TITLE];
-}
-
-- (IBAction)sortNodeByAuthor:(id)sender
-{
-    [self sortNode: SORT_ARTIST];
-}
-
-- (void)sortNode:(int)i_mode
-{
-    playlist_t * p_playlist = pl_Get(VLCIntf);
-    playlist_item_t * p_item;
-
-    // TODO why do we need this kind of sort? It looks crap and confusing...
-
-//    if ([_outlineView selectedRow] > -1) {
-//        p_item = [[_outlineView itemAtRow: [_outlineView selectedRow]] pointerValue];
-//        if (!p_item)
-//            return;
-//    } else
-//        p_item = [self currentPlaylistRoot]; // If no item is selected, sort the whole playlist
-//
-//    PL_LOCK;
-//    if (p_item->i_children > -1) // the item is a node
-//        playlist_RecursiveNodeSort(p_playlist, p_item, i_mode, ORDER_NORMAL);
-//    else
-//        playlist_RecursiveNodeSort(p_playlist, p_item->p_parent, i_mode, ORDER_NORMAL);
-//
-//    PL_UNLOCK;
-//    [self playlistUpdated];
-}
-
-- (input_item_t *)createItem:(NSDictionary *)itemToCreateDict
-{
-    intf_thread_t *p_intf = VLCIntf;
-    playlist_t *p_playlist = pl_Get(p_intf);
-
-    input_item_t *p_input;
-    BOOL b_rem = FALSE, b_dir = FALSE, b_writable = FALSE;
-    NSString *uri, *name, *path;
-    NSURL * url;
-    NSArray *optionsArray;
-
-    /* Get the item */
-    uri = (NSString *)[itemToCreateDict objectForKey: @"ITEM_URL"];
-    url = [NSURL URLWithString: uri];
-    path = [url path];
-    name = (NSString *)[itemToCreateDict objectForKey: @"ITEM_NAME"];
-    optionsArray = (NSArray *)[itemToCreateDict objectForKey: @"ITEM_OPTIONS"];
-
-    if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&b_dir] && b_dir &&
-        [[NSWorkspace sharedWorkspace] getFileSystemInfoForPath:path isRemovable: &b_rem
-                                                     isWritable:&b_writable isUnmountable:NULL description:NULL type:NULL] && b_rem && !b_writable && [url isFileURL]) {
-
-        NSString *diskType = [[VLCStringUtility sharedInstance] getVolumeTypeFromMountPath: path];
-        msg_Dbg(p_intf, "detected optical media of type %s in the file input", [diskType UTF8String]);
-
-        if ([diskType isEqualToString: kVLCMediaDVD])
-            uri = [NSString stringWithFormat: @"dvdnav://%@", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
-        else if ([diskType isEqualToString: kVLCMediaVideoTSFolder])
-            uri = [NSString stringWithFormat: @"dvdnav://%@", path];
-        else if ([diskType isEqualToString: kVLCMediaAudioCD])
-            uri = [NSString stringWithFormat: @"cdda://%@", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
-        else if ([diskType isEqualToString: kVLCMediaVCD])
-            uri = [NSString stringWithFormat: @"vcd://%@#0:0", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
-        else if ([diskType isEqualToString: kVLCMediaSVCD])
-            uri = [NSString stringWithFormat: @"vcd://%@@0:0", [[VLCStringUtility sharedInstance] getBSDNodeFromMountPath: path]];
-        else if ([diskType isEqualToString: kVLCMediaBD] || [diskType isEqualToString: kVLCMediaBDMVFolder])
-            uri = [NSString stringWithFormat: @"bluray://%@", path];
-        else
-            msg_Warn(VLCIntf, "unknown disk type, treating %s as regular input", [path UTF8String]);
-
-        p_input = input_item_New([uri UTF8String], [[[NSFileManager defaultManager] displayNameAtPath:path] UTF8String]);
-    }
-    else
-        p_input = input_item_New([uri fileSystemRepresentation], name ? [name UTF8String] : NULL);
-
-    if (!p_input)
-        return NULL;
-
-    if (optionsArray) {
-        NSUInteger count = [optionsArray count];
-        for (NSUInteger i = 0; i < count; i++)
-            input_item_AddOption(p_input, [optionsArray[i] UTF8String], VLC_INPUT_OPTION_TRUSTED);
-    }
-
-    /* Recent documents menu */
-    if (url != nil && (BOOL)config_GetInt(p_playlist, "macosx-recentitems") == YES)
-        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:url];
-
-    return p_input;
-}
-
-- (void)addPlaylistItems:(NSArray*)array
-{
-
-    int i_plItemId = -1;
-
-    // add items directly to media library if this is the current root
-    if ([[self model] currentRootType] == ROOT_TYPE_MEDIALIBRARY)
-        i_plItemId = [[[self model] rootItem] plItemId];
-
-    BOOL b_autoplay = var_InheritBool(VLCIntf, "macosx-autoplay");
-
-    [self addPlaylistItems:array withParentItemId:i_plItemId atPos:-1 startPlayback:b_autoplay];
-}
-
-- (void)addPlaylistItems:(NSArray*)array withParentItemId:(int)i_plItemId atPos:(int)i_position startPlayback:(BOOL)b_start
-{
-    playlist_t * p_playlist = pl_Get(VLCIntf);
-    PL_LOCK;
-
-    playlist_item_t *p_parent = NULL;
-    if (i_plItemId >= 0)
-        p_parent = playlist_ItemGetById(p_playlist, i_plItemId);
-    else
-        p_parent = p_playlist->p_playing;
-
-    if (!p_parent) {
-        PL_UNLOCK;
-        return;
-    }
-
-    NSUInteger count = [array count];
-    int i_current_offset = 0;
-    for (NSUInteger i = 0; i < count; ++i) {
-
-        NSDictionary *o_current_item = array[i];
-        input_item_t *p_input = [self createItem: o_current_item];
-        if (!p_input)
-            continue;
-
-        int i_pos = (i_position == -1) ? PLAYLIST_END : i_position + i_current_offset++;
-        playlist_item_t *p_item = playlist_NodeAddInput(p_playlist, p_input, p_parent,
-                                                        PLAYLIST_INSERT, i_pos, pl_Locked);
-        if (!p_item)
-            continue;
-
-        if (i == 0 && b_start) {
-            playlist_Control(p_playlist, PLAYLIST_VIEWPLAY, pl_Locked, p_parent, p_item);
-        }
-        input_item_Release(p_input);
-    }
-    PL_UNLOCK;
-}
-
-- (IBAction)recursiveExpandNode:(id)sender
-{
-    NSIndexSet * selectedRows = [_outlineView selectedRowIndexes];
-    NSUInteger count = [selectedRows count];
-    NSUInteger indexes[count];
-    [selectedRows getIndexes:indexes maxCount:count inIndexRange:nil];
-
-    id item;
-    playlist_item_t *p_item;
-    for (NSUInteger i = 0; i < count; i++) {
-        item = [_outlineView itemAtRow: indexes[i]];
-
-        /* We need to collapse the node first, since OSX refuses to recursively
-         expand an already expanded node, even if children nodes are collapsed. */
-        if ([_outlineView isExpandable:item]) {
-            [_outlineView collapseItem: item collapseChildren: YES];
-            [_outlineView expandItem: item expandChildren: YES];
-        }
-
-        selectedRows = [_outlineView selectedRowIndexes];
-        [selectedRows getIndexes:indexes maxCount:count inIndexRange:nil];
-    }
-}
-
-- (NSMenu *)menuForEvent:(NSEvent *)o_event
-{
-    if (!b_playlistmenu_nib_loaded)
-        b_playlistmenu_nib_loaded = [NSBundle loadNibNamed:@"PlaylistMenu" owner:self];
-
-    NSPoint pt;
-    bool b_rows;
-    bool b_item_sel;
-
-    pt = [_outlineView convertPoint: [o_event locationInWindow] fromView: nil];
-    int row = [_outlineView rowAtPoint:pt];
-    if (row != -1 && ![[_outlineView selectedRowIndexes] containsIndex: row])
-        [_outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
-
-    b_item_sel = (row != -1 && [_outlineView selectedRow] != -1);
-    b_rows = [_outlineView numberOfRows] != 0;
-
-    playlist_t *p_playlist = pl_Get(VLCIntf);
-    bool b_del_allowed = [[self model] editAllowed];
-
-    [_playPlaylistMenuItem setEnabled: b_item_sel];
-    [_deletePlaylistMenuItem setEnabled: b_item_sel && b_del_allowed];
-    [_selectAllPlaylistMenuItem setEnabled: b_rows];
-    [_infoPlaylistMenuItem setEnabled: b_item_sel];
-    [_preparsePlaylistMenuItem setEnabled: b_item_sel];
-    [_recursiveExpandPlaylistMenuItem setEnabled: b_item_sel];
-    [_sortNamePlaylistMenuItem setEnabled: b_item_sel];
-    [_sortAuthorPlaylistMenuItem setEnabled: b_item_sel];
-    [_downloadCoverArtPlaylistMenuItem setEnabled: b_item_sel];
-
-    return _playlistMenu;
-}
-
-- (void)outlineView:(NSOutlineView *)outlineView didClickTableColumn:(NSTableColumn *)aTableColumn
-{
-    int type = 0;
-    intf_thread_t *p_intf = VLCIntf;
-    NSString * identifier = [aTableColumn identifier];
-
-    playlist_t *p_playlist = pl_Get(p_intf);
-
-    if (_sortTableColumn == aTableColumn)
-        b_isSortDescending = !b_isSortDescending;
-    else
-        b_isSortDescending = false;
-
-    if (b_isSortDescending)
-        type = ORDER_REVERSE;
-    else
-        type = ORDER_NORMAL;
-
-    [[self model] sortForColumn:identifier withMode:type];
-
-    // TODO rework, why do we need a full call here?
-//    [self playlistUpdated];
-
-    /* Clear indications of any existing column sorting */
-    NSUInteger count = [[_outlineView tableColumns] count];
-    for (NSUInteger i = 0 ; i < count ; i++)
-        [_outlineView setIndicatorImage:nil inTableColumn: [_outlineView tableColumns][i]];
-
-    [_outlineView setHighlightedTableColumn:nil];
-    _sortTableColumn = aTableColumn;
-    [_outlineView setHighlightedTableColumn:aTableColumn];
-
-    if (b_isSortDescending)
-        [_outlineView setIndicatorImage:_descendingSortingImage inTableColumn:aTableColumn];
-    else
-        [_outlineView setIndicatorImage:_ascendingSortingImage inTableColumn:aTableColumn];
-}
-
-
-- (void)outlineView:(NSOutlineView *)outlineView
-    willDisplayCell:(id)cell
-     forTableColumn:(NSTableColumn *)tableColumn
-               item:(id)item
-{
-    /* this method can be called when VLC is already dead, hence the extra checks */
-    intf_thread_t * p_intf = VLCIntf;
-    if (!p_intf)
-        return;
-    playlist_t *p_playlist = pl_Get(p_intf);
-
-    NSFont *fontToUse;
-    if (var_InheritBool(VLCIntf, "macosx-large-text"))
-        fontToUse = [NSFont systemFontOfSize:13.];
-    else
-        fontToUse = [NSFont systemFontOfSize:11.];
-
-    BOOL b_is_playing = NO;
-    PL_LOCK;
-    playlist_item_t *p_current_item = playlist_CurrentPlayingItem(p_playlist);
-    if (p_current_item) {
-        b_is_playing = p_current_item->i_id == [item plItemId];
-    }
-    PL_UNLOCK;
-
-    /*
-     TODO: repaint all items bold:
-     [self isItem: [o_playing_item pointerValue] inNode: [item pointerValue] checkItemExistence:YES locked:NO]
-     || [o_playing_item isEqual: item]
-     */
-
-    if (b_is_playing)
-        [cell setFont: [[NSFontManager sharedFontManager] convertFont:fontToUse toHaveTrait:NSBoldFontMask]];
-    else
-        [cell setFont: [[NSFontManager sharedFontManager] convertFont:fontToUse toNotHaveTrait:NSBoldFontMask]];
-}
-
-// TODO remove method
-- (NSArray *)draggedItems
-{
-    return [[self model] draggedItems];
-}
-
-- (void)setColumn:(NSString *)columnIdentifier state:(NSInteger)i_state translationDict:(NSDictionary *)translationDict
-{
-    if (i_state == NSOnState) {
-        NSString *title = [translationDict objectForKey:columnIdentifier];
-        if (!title)
-            return;
-
-        NSTableColumn *tableColumn = [[NSTableColumn alloc] initWithIdentifier:columnIdentifier];
-        [tableColumn setEditable:NO];
-        [[tableColumn dataCell] setFont:[NSFont controlContentFontOfSize:11.]];
-
-        [[tableColumn headerCell] setStringValue:[translationDict objectForKey:columnIdentifier]];
-
-        if ([columnIdentifier isEqualToString: TRACKNUM_COLUMN]) {
-            [tableColumn setWidth:20.];
-            [tableColumn setResizingMask:NSTableColumnNoResizing];
-            [[tableColumn headerCell] setStringValue:@"#"];
-        }
-
-        [_outlineView addTableColumn:tableColumn];
-        [_outlineView reloadData];
-        [_outlineView setNeedsDisplay: YES];
-    }
-    else
-        [_outlineView removeTableColumn: [_outlineView tableColumnWithIdentifier:columnIdentifier]];
-
-    [_outlineView setOutlineTableColumn: [_outlineView tableColumnWithIdentifier:TITLE_COLUMN]];
-}
-
-- (void)saveTableColumns
-{
-    NSMutableArray *arrayToSave = [[NSMutableArray alloc] init];
-    NSArray *columns = [[NSArray alloc] initWithArray:[_outlineView tableColumns]];
-    NSUInteger columnCount = [columns count];
-    NSTableColumn *currentColumn;
-    for (NSUInteger i = 0; i < columnCount; i++) {
-        currentColumn = columns[i];
-        [arrayToSave addObject:[NSArray arrayWithObjects:[currentColumn identifier], [NSNumber numberWithFloat:[currentColumn width]], nil]];
-    }
-    [[NSUserDefaults standardUserDefaults] setObject:arrayToSave forKey:@"PlaylistColumnSelection"];
-    [[NSUserDefaults standardUserDefaults] synchronize];
-}
-
-- (BOOL)isValidResumeItem:(input_item_t *)p_item
-{
-    char *psz_url = input_item_GetURI(p_item);
-    NSString *urlString = toNSStr(psz_url);
-    free(psz_url);
-
-    if ([urlString isEqualToString:@""])
-        return NO;
-
-    NSURL *url = [NSURL URLWithString:urlString];
-
-    if (![url isFileURL])
-        return NO;
-
-    BOOL isDir = false;
-    if (![[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDir])
-        return NO;
-
-    if (isDir)
-        return NO;
-
-    return YES;
-}
-
-- (void)continuePlaybackWhereYouLeftOff:(input_thread_t *)p_input_thread
-{
-    NSDictionary *recentlyPlayedFiles = [[NSUserDefaults standardUserDefaults] objectForKey:@"recentlyPlayedMedia"];
-    if (!recentlyPlayedFiles)
-        return;
-
-    input_item_t *p_item = input_GetItem(p_input_thread);
-    if (!p_item)
-        return;
-
-    /* allow the user to over-write the start/stop/run-time */
-    if (var_GetFloat(p_input_thread, "run-time") > 0 ||
-        var_GetFloat(p_input_thread, "start-time") > 0 ||
-        var_GetFloat(p_input_thread, "stop-time") != 0) {
-        return;
-    }
-
-    /* check for file existance before resuming */
-    if (![self isValidResumeItem:p_item])
-        return;
-
-    char *psz_url = decode_URI(input_item_GetURI(p_item));
-    if (!psz_url)
-        return;
-    NSString *url = toNSStr(psz_url);
-    free(psz_url);
-
-    NSNumber *lastPosition = [recentlyPlayedFiles objectForKey:url];
-    if (!lastPosition || lastPosition.intValue <= 0)
-        return;
-
-    int settingValue = config_GetInt(VLCIntf, "macosx-continue-playback");
-    if (settingValue == 2) // never resume
-        return;
-
-    CompletionBlock completionBlock = ^(enum ResumeResult result) {
-
-        if (result == RESUME_RESTART)
-            return;
-
-        mtime_t lastPos = (mtime_t)lastPosition.intValue * 1000000;
-        msg_Dbg(VLCIntf, "continuing playback at %lld", lastPos);
-        var_SetInteger(p_input_thread, "time", lastPos);
-
-        if (result == RESUME_ALWAYS)
-            config_PutInt(VLCIntf, "macosx-continue-playback", 1);
-    };
-
-    if (settingValue == 1) { // always
-        completionBlock(RESUME_NOW);
-        return;
-    }
-
-    [[[VLCMain sharedInstance] resumeDialog] showWindowWithItem:p_item
-                                               withLastPosition:lastPosition.intValue
-                                                completionBlock:completionBlock];
-
-}
-
-- (void)storePlaybackPositionForItem:(input_thread_t *)p_input_thread
-{
-    if (!var_InheritBool(VLCIntf, "macosx-recentitems"))
-        return;
-
-    input_item_t *p_item = input_GetItem(p_input_thread);
-    if (!p_item)
-        return;
-
-    if (![self isValidResumeItem:p_item])
-        return;
-
-    char *psz_url = decode_URI(input_item_GetURI(p_item));
-    if (!psz_url)
-        return;
-    NSString *url = toNSStr(psz_url);
-    free(psz_url);
-
-    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-    NSMutableDictionary *mutDict = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:@"recentlyPlayedMedia"]];
-
-    float relativePos = var_GetFloat(p_input_thread, "position");
-    mtime_t pos = var_GetInteger(p_input_thread, "time") / CLOCK_FREQ;
-    mtime_t dur = input_item_GetDuration(p_item) / 1000000;
-
-    NSMutableArray *mediaList = [[defaults objectForKey:@"recentlyPlayedMediaList"] mutableCopy];
-
-    if (relativePos > .05 && relativePos < .95 && dur > 180) {
-        [mutDict setObject:[NSNumber numberWithInt:pos] forKey:url];
-
-        [mediaList removeObject:url];
-        [mediaList addObject:url];
-        NSUInteger mediaListCount = mediaList.count;
-        if (mediaListCount > 30) {
-            for (NSUInteger x = 0; x < mediaListCount - 30; x++) {
-                [mutDict removeObjectForKey:[mediaList firstObject]];
-                [mediaList removeObjectAtIndex:0];
-            }
-        }
-    } else {
-        [mutDict removeObjectForKey:url];
-        [mediaList removeObject:url];
-    }
-    [defaults setObject:mutDict forKey:@"recentlyPlayedMedia"];
-    [defaults setObject:mediaList forKey:@"recentlyPlayedMediaList"];
-    [defaults synchronize];
-}
-
-@end
diff --git a/modules/gui/macosx/playlistinfo.h b/modules/gui/macosx/playlistinfo.h
deleted file mode 100644 (file)
index 6511a5f..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*****************************************************************************
- * playlistinfo.h: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2002-2015 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Benjamin Pracht <bigben at videolan dot org>
- *          Felix Paul Kühne <fkuehne at videolan dot org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * VLCPlaylistInfo interface
- *****************************************************************************/
-
-@class VLCInfoTreeItem;
-
-@interface VLCInfo : NSObject
-
-@property (readonly) input_item_t *item;
-
-@property (readwrite, weak) IBOutlet NSPanel *infoPanel;
-@property (readwrite, weak) IBOutlet NSOutlineView *outlineView;
-@property (readwrite, weak) IBOutlet NSTabView *tabView;
-
-@property (readwrite, weak) IBOutlet NSTextField *uriLabel;
-@property (readwrite, weak) IBOutlet NSTextField *titleLabel;
-@property (readwrite, weak) IBOutlet NSTextField *authorLabel;
-@property (readwrite, weak) IBOutlet NSTextField *uriTextField;
-@property (readwrite, weak) IBOutlet NSTextField *titleTextField;
-@property (readwrite, weak) IBOutlet NSTextField *authorTextField;
-@property (readwrite, weak) IBOutlet NSTextField *collectionLabel;
-@property (readwrite, weak) IBOutlet NSTextField *collectionTextField;
-@property (readwrite, weak) IBOutlet NSTextField *copyrightLabel;
-@property (readwrite, weak) IBOutlet NSTextField *copyrightTextField;
-@property (readwrite, weak) IBOutlet NSTextField *dateLabel;
-@property (readwrite, weak) IBOutlet NSTextField *dateTextField;
-@property (readwrite, weak) IBOutlet NSTextField *descriptionLabel;
-@property (readwrite, weak) IBOutlet NSTextField *descriptionTextField;
-@property (readwrite, weak) IBOutlet NSTextField *encodedbyLabel;
-@property (readwrite, weak) IBOutlet NSTextField *encodedbyTextField;
-@property (readwrite, weak) IBOutlet NSTextField *genreLabel;
-@property (readwrite, weak) IBOutlet NSTextField *genreTextField;
-@property (readwrite, weak) IBOutlet NSTextField *languageLabel;
-@property (readwrite, weak) IBOutlet NSTextField *languageTextField;
-@property (readwrite, weak) IBOutlet NSTextField *nowPlayingLabel;
-@property (readwrite, weak) IBOutlet NSTextField *nowPlayingTextField;
-@property (readwrite, weak) IBOutlet NSTextField *publisherLabel;
-@property (readwrite, weak) IBOutlet NSTextField *publisherTextField;
-@property (readwrite, weak) IBOutlet NSTextField *seqNumLabel;
-@property (readwrite, weak) IBOutlet NSTextField *seqNumTextField;
-@property (readwrite, weak) IBOutlet NSImageView *imageWell;
-@property (readwrite, weak) IBOutlet NSButton *saveMetaDataButton;
-
-@property (readwrite, weak) IBOutlet NSTextField *audioLabel;
-@property (readwrite, weak) IBOutlet NSTextField *audioDecodedLabel;
-@property (readwrite, weak) IBOutlet NSTextField *audioDecodedTextField;
-@property (readwrite, weak) IBOutlet NSTextField *demuxBitrateLabel;
-@property (readwrite, weak) IBOutlet NSTextField *demuxBitrateTextField;
-@property (readwrite, weak) IBOutlet NSTextField *demuxBytesLabel;
-@property (readwrite, weak) IBOutlet NSTextField *demuxBytesTextField;
-@property (readwrite, weak) IBOutlet NSTextField *displayedLabel;
-@property (readwrite, weak) IBOutlet NSTextField *displayedTextField;
-@property (readwrite, weak) IBOutlet NSTextField *inputBitrateLabel;
-@property (readwrite, weak) IBOutlet NSTextField *inputBitrateTextField;
-@property (readwrite, weak) IBOutlet NSTextField *inputLabel;
-@property (readwrite, weak) IBOutlet NSTextField *lostAudioBuffersLabel;
-@property (readwrite, weak) IBOutlet NSTextField *lostAudioBuffersTextField;
-@property (readwrite, weak) IBOutlet NSTextField *lostFramesLabel;
-@property (readwrite, weak) IBOutlet NSTextField *lostFramesTextField;
-@property (readwrite, weak) IBOutlet NSTextField *playedAudioBuffersLabel;
-@property (readwrite, weak) IBOutlet NSTextField *playedAudioBuffersTextField;
-@property (readwrite, weak) IBOutlet NSTextField *readBytesLabel;
-@property (readwrite, weak) IBOutlet NSTextField *readBytesTextField;
-@property (readwrite, weak) IBOutlet NSTextField *sentBitrateLabel;
-@property (readwrite, weak) IBOutlet NSTextField *sentBitrateTextField;
-@property (readwrite, weak) IBOutlet NSTextField *sentBytesLabel;
-@property (readwrite, weak) IBOutlet NSTextField *sentBytesTextField;
-@property (readwrite, weak) IBOutlet NSTextField *sentPacketsLabel;
-@property (readwrite, weak) IBOutlet NSTextField *sentPacketsTextField;
-@property (readwrite, weak) IBOutlet NSTextField *soutLabel;
-@property (readwrite, weak) IBOutlet NSTextField *videoLabel;
-@property (readwrite, weak) IBOutlet NSTextField *videoDecodedLabel;
-@property (readwrite, weak) IBOutlet NSTextField *videoDecodedTextField;
-
-- (void)updateCocoaWindowLevel:(NSInteger)i_level;
-- (void)initPanel;
-
-- (IBAction)metaFieldChanged:(id)sender;
-- (IBAction)saveMetaData:(id)sender;
-- (IBAction)downloadCoverArt:(id)sender;
-- (void)initMediaPanelStats;
-- (void)updatePanelWithItem:(input_item_t *)_p_item;
-- (void)setMeta:(char *)meta forLabel:(id)theItem;
-- (void)updateMetadata;
-- (void)updateStatistics;
-
-+ (VLCInfo *)sharedInstance;
-@end
-
-@interface VLCInfoTreeItem : NSObject
-
-@property (readonly) int numberOfChildren;
-@property (readonly) NSString *name;
-@property (readonly) NSString *value;
-
-- (VLCInfoTreeItem *)childAtIndex:(NSUInteger)i_index;
-- (void)refresh;
-
-@end
diff --git a/modules/gui/macosx/playlistinfo.m b/modules/gui/macosx/playlistinfo.m
deleted file mode 100644 (file)
index bb4e6cd..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-/*****************************************************************************
- * playlistinfo.m: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2002-2015 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Benjamin Pracht <bigben at videolan dot org>
- *          Felix Paul Kühne <fkuehne at videolan dot org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- ******************************************************************************/
-
-#import "CompatibilityFixes.h"
-#import "intf.h"
-#import "playlistinfo.h"
-#import "playlist.h"
-#import <vlc_url.h>
-
-@interface VLCInfo () <NSOutlineViewDataSource, NSOutlineViewDelegate>
-{
-    VLCInfoTreeItem *rootItem;
-
-    input_item_t *p_item;
-
-    BOOL b_nibLoaded;
-    BOOL b_awakeFromNib;
-    BOOL b_stats;
-}
-@end
-
-@implementation VLCInfo
-
-+ (VLCInfo *)sharedInstance
-{
-    static VLCInfo *sharedInstance = nil;
-    static dispatch_once_t pred;
-
-    dispatch_once(&pred, ^{
-        sharedInstance = [VLCInfo new];
-    });
-
-    return sharedInstance;
-}
-
-- (void)awakeFromNib
-{
-    [_infoPanel setExcludedFromWindowsMenu: YES];
-    [_infoPanel setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
-
-    [_infoPanel setTitle: _NS("Media Information")];
-
-    _outlineView.dataSource = self;
-    _outlineView.delegate = self;
-
-    [_uriLabel setStringValue: _NS("Location")];
-    [_titleLabel setStringValue: _NS("Title")];
-    [_authorLabel setStringValue: _NS("Artist")];
-    [_saveMetaDataButton setStringValue: _NS("Save Metadata")];
-
-    [[_tabView tabViewItemAtIndex: 0] setLabel: _NS("General")];
-    [[_tabView tabViewItemAtIndex: 1] setLabel: _NS("Codec Details")];
-    [[_tabView tabViewItemAtIndex: 2] setLabel: _NS("Statistics")];
-    [_tabView selectTabViewItemAtIndex: 0];
-
-    /* constants defined in vlc_meta.h */
-    [_genreLabel setStringValue: _NS(VLC_META_GENRE)];
-    [_copyrightLabel setStringValue: _NS(VLC_META_COPYRIGHT)];
-    [_collectionLabel setStringValue: _NS(VLC_META_ALBUM)];
-    [_seqNumLabel setStringValue: _NS(VLC_META_TRACK_NUMBER)];
-    [_descriptionLabel setStringValue: _NS(VLC_META_DESCRIPTION)];
-    [_dateLabel setStringValue: _NS(VLC_META_DATE)];
-    [_languageLabel setStringValue: _NS(VLC_META_LANGUAGE)];
-    [_nowPlayingLabel setStringValue: _NS(VLC_META_NOW_PLAYING)];
-    [_publisherLabel setStringValue: _NS(VLC_META_PUBLISHER)];
-    [_encodedbyLabel setStringValue: _NS(VLC_META_ENCODED_BY)];
-
-    /* statistics */
-    [_inputLabel setStringValue: _NS("Input")];
-    [_readBytesLabel setStringValue: _NS("Read at media")];
-    [_inputBitrateLabel setStringValue: _NS("Input bitrate")];
-    [_demuxBytesLabel setStringValue: _NS("Demuxed")];
-    [_demuxBitrateLabel setStringValue: _NS("Stream bitrate")];
-
-    [_videoLabel setStringValue: _NS("Video")];
-    [_videoDecodedLabel setStringValue: _NS("Decoded blocks")];
-    [_displayedLabel setStringValue: _NS("Displayed frames")];
-    [_lostFramesLabel setStringValue: _NS("Lost frames")];
-
-    [_soutLabel setStringValue: _NS("Streaming")];
-    [_sentPacketsLabel setStringValue: _NS("Sent packets")];
-    [_sentBytesLabel setStringValue: _NS("Sent bytes")];
-    [_sentBitrateLabel setStringValue: _NS("Send rate")];
-
-    [_audioLabel setStringValue: _NS("Audio")];
-    [_audioDecodedLabel setStringValue: _NS("Decoded blocks")];
-    [_playedAudioBuffersLabel setStringValue: _NS("Played buffers")];
-    [_lostAudioBuffersLabel setStringValue: _NS("Lost buffers")];
-
-    [_infoPanel setInitialFirstResponder: _uriLabel];
-
-    b_awakeFromNib = YES;
-
-    /* We may be awoken from nib way after initialisation
-     *Update ourselves */
-    [self updatePanelWithItem:p_item];
-}
-
-
-- (void)dealloc
-{
-    if (p_item)
-        vlc_gc_decref(p_item);
-}
-
-- (void)updateCocoaWindowLevel:(NSInteger)i_level
-{
-    if (_infoPanel && [_infoPanel isVisible] && [_infoPanel level] != i_level)
-        [_infoPanel setLevel: i_level];
-}
-
-- (void)initPanel
-{
-    if (!b_nibLoaded)
-        b_nibLoaded = [NSBundle loadNibNamed:@"MediaInfo" owner: self];
-
-    b_stats = var_InheritBool(VLCIntf, "stats");
-    if (!b_stats) {
-        if ([_tabView numberOfTabViewItems] > 2)
-            [_tabView removeTabViewItem: [_tabView tabViewItemAtIndex: 2]];
-    }
-    else
-        [self initMediaPanelStats];
-
-    NSInteger i_level = [[[VLCMain sharedInstance] voutController] currentStatusWindowLevel];
-    [_infoPanel setLevel: i_level];
-    [_infoPanel makeKeyAndOrderFront:nil];
-}
-
-- (void)initMediaPanelStats
-{
-    //Initializing Input Variables
-    [_readBytesTextField setStringValue: [NSString stringWithFormat:_NS("%.1f KiB"), (float)0]];
-    [_inputBitrateTextField setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]];
-    [_demuxBytesTextField setStringValue: [NSString stringWithFormat:_NS("%.1f KiB"), (float)0]];
-    [_demuxBitrateTextField setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]];
-
-    //Initializing Video Variables
-    [_videoDecodedTextField setIntValue:0];
-    [_displayedTextField setIntValue:0];
-    [_lostFramesTextField setIntValue:0];
-
-    //Initializing Output Variables
-    [_sentPacketsTextField setIntValue: 0];
-    [_sentBytesTextField setStringValue: [NSString stringWithFormat:_NS("%.1f KiB"), (float)0]];
-    [_sentBitrateTextField setStringValue: [NSString stringWithFormat:@"%6.0f kb/s", (float)0]];
-
-    //Initializing Audio Variables
-    [_audioDecodedTextField setIntValue:0];
-    [_playedAudioBuffersTextField setIntValue: 0];
-    [_lostAudioBuffersTextField setIntValue: 0];
-}
-
-- (void)updateMetadata
-{
-    if (!p_item)
-        return;
-
-    [self updatePanelWithItem:p_item];
-}
-
-- (void)updatePanelWithItem:(input_item_t *)_p_item;
-{
-    @autoreleasepool {
-        rootItem = [[VLCInfoTreeItem alloc] init];
-
-        if (_p_item != p_item) {
-            if (p_item)
-                vlc_gc_decref(p_item);
-            [_saveMetaDataButton setEnabled: NO];
-            if (_p_item)
-                vlc_gc_incref(_p_item);
-            p_item = _p_item;
-        }
-
-        if (!p_item) {
-            /* Erase */
-        #define SET( foo ) \
-            [self setMeta: "" forLabel: _##foo##TextField];
-            SET( uri );
-            SET( title );
-            SET( author );
-            SET( collection );
-            SET( seqNum );
-            SET( genre );
-            SET( copyright );
-            SET( publisher );
-            SET( nowPlaying );
-            SET( language );
-            SET( date );
-            SET( description );
-            SET( encodedby );
-        #undef SET
-            [_imageWell setImage: [NSImage imageNamed: @"noart.png"]];
-        } else {
-            if (!input_item_IsPreparsed(p_item))
-                libvlc_MetaRequest(VLCIntf->p_libvlc, p_item, META_REQUEST_OPTION_NONE);
-
-            /* fill uri info */
-            char *psz_url = decode_URI(input_item_GetURI(p_item));
-            [_uriTextField setStringValue:toNSStr(psz_url)];
-            free(psz_url);
-
-            /* fill title info */
-            char *psz_title = input_item_GetTitle(p_item);
-            if (!psz_title)
-                psz_title = input_item_GetName(p_item);
-            [_titleTextField setStringValue:toNSStr(psz_title)];
-            free(psz_title);
-
-        #define SET( foo, bar ) \
-            char *psz_##foo = input_item_Get##bar ( p_item ); \
-            [self setMeta: psz_##foo forLabel: _##foo##TextField]; \
-            FREENULL( psz_##foo );
-
-            /* fill the other fields */
-            SET( author, Artist );
-            SET( collection, Album );
-            SET( seqNum, TrackNum );
-            SET( genre, Genre );
-            SET( copyright, Copyright );
-            SET( publisher, Publisher );
-            SET( nowPlaying, NowPlaying );
-            SET( language, Language );
-            SET( date, Date );
-            SET( description, Description );
-            SET( encodedby, EncodedBy );
-
-        #undef SET
-
-            char *psz_meta;
-            NSImage *image;
-            psz_meta = input_item_GetArtURL(p_item);
-
-            /* FIXME Can also be attachment:// */
-            if (psz_meta && strncmp(psz_meta, "attachment://", 13))
-                image = [[NSImage alloc] initWithContentsOfURL: [NSURL URLWithString:toNSStr(psz_meta)]];
-            else
-                image = [NSImage imageNamed: @"noart.png"];
-            [_imageWell setImage: image];
-            FREENULL(psz_meta);
-        }
-
-        /* reload the advanced table */
-        [rootItem refresh];
-        [_outlineView reloadData];
-        [_outlineView expandItem:nil expandChildren:YES];
-
-        /* update the stats once to display p_item change faster */
-        [self updateStatistics];
-    }
-}
-
-- (void)setMeta: (char *)psz_meta forLabel: (id)theItem
-{
-    if (psz_meta != NULL && *psz_meta)
-        [theItem setStringValue: toNSStr(psz_meta)];
-    else
-        [theItem setStringValue: @""];
-}
-
-- (void)updateStatistics
-{
-    if (!b_awakeFromNib || !b_stats)
-        return;
-
-    if ([_infoPanel isVisible]) {
-        if (!p_item || !p_item->p_stats) {
-            [self initMediaPanelStats];
-            return;
-        }
-
-        vlc_mutex_lock(&p_item->p_stats->lock);
-
-        /* input */
-        [_readBytesTextField setStringValue: [NSString stringWithFormat:
-            @"%8.0f KiB", (float)(p_item->p_stats->i_read_bytes)/1024]];
-        [_inputBitrateTextField setStringValue: [NSString stringWithFormat:
-            @"%6.0f kb/s", (float)(p_item->p_stats->f_input_bitrate)*8000]];
-        [_demuxBytesTextField setStringValue: [NSString stringWithFormat:
-            @"%8.0f KiB", (float)(p_item->p_stats->i_demux_read_bytes)/1024]];
-        [_demuxBitrateTextField setStringValue: [NSString stringWithFormat:
-            @"%6.0f kb/s", (float)(p_item->p_stats->f_demux_bitrate)*8000]];
-
-        /* Video */
-        [_videoDecodedTextField setIntValue: p_item->p_stats->i_decoded_video];
-        [_displayedTextField setIntValue: p_item->p_stats->i_displayed_pictures];
-        [_lostFramesTextField setIntValue: p_item->p_stats->i_lost_pictures];
-
-        /* Sout */
-        [_sentPacketsTextField setIntValue: p_item->p_stats->i_sent_packets];
-        [_sentBytesTextField setStringValue: [NSString stringWithFormat: @"%8.0f KiB",
-            (float)(p_item->p_stats->i_sent_bytes)/1024]];
-        [_sentBitrateTextField setStringValue: [NSString stringWithFormat:
-            @"%6.0f kb/s", (float)(p_item->p_stats->f_send_bitrate*8)*1000]];
-
-        /* Audio */
-        [_audioDecodedTextField setIntValue: p_item->p_stats->i_decoded_audio];
-        [_playedAudioBuffersTextField setIntValue: p_item->p_stats->i_played_abuffers];
-        [_lostAudioBuffersTextField setIntValue: p_item->p_stats->i_lost_abuffers];
-
-        vlc_mutex_unlock(&p_item->p_stats->lock);
-    }
-}
-
-- (IBAction)metaFieldChanged:(id)sender
-{
-    [_saveMetaDataButton setEnabled: YES];
-}
-
-- (IBAction)saveMetaData:(id)sender
-{
-    if (!p_item)
-        goto error;
-
-    #define utf8( _blub ) \
-        [[_blub stringValue] UTF8String]
-
-    input_item_SetName( p_item, utf8( _titleTextField ) );
-    input_item_SetTitle( p_item, utf8( _titleTextField ) );
-    input_item_SetArtist( p_item, utf8( _authorTextField ) );
-    input_item_SetAlbum( p_item, utf8( _collectionTextField ) );
-    input_item_SetGenre( p_item, utf8( _genreTextField ) );
-    input_item_SetTrackNum( p_item, utf8( _seqNumTextField ) );
-    input_item_SetDate( p_item, utf8( _dateTextField ) );
-    input_item_SetCopyright( p_item, utf8( _copyrightTextField ) );
-    input_item_SetPublisher( p_item, utf8( _publisherTextField ) );
-    input_item_SetDescription( p_item, utf8( _descriptionTextField ) );
-    input_item_SetLanguage( p_item, utf8( _languageTextField ) );
-
-    playlist_t *p_playlist = pl_Get(VLCIntf);
-    input_item_WriteMeta(VLC_OBJECT(p_playlist), p_item);
-
-    var_SetBool(p_playlist, "intf-change", true);
-    [self updatePanelWithItem: p_item];
-
-    [_saveMetaDataButton setEnabled: NO];
-    return;
-
-error:
-    NSRunAlertPanel(_NS("Error while saving meta"),
-        @"%@",_NS("VLC was unable to save the meta data."),
-        _NS("OK"), nil, nil);
-}
-
-- (IBAction)downloadCoverArt:(id)sender
-{
-    playlist_t *p_playlist = pl_Get(VLCIntf);
-    if (p_item) libvlc_ArtRequest(VLCIntf->p_libvlc, p_item, META_REQUEST_OPTION_NONE);
-}
-
-- (input_item_t *)item
-{
-    if (p_item) vlc_gc_incref(p_item);
-    return p_item;
-}
-
-@end
-
-@implementation VLCInfo (NSMenuValidation)
-
-- (BOOL)validateMenuItem:(NSMenuItem *)mi
-{
-    if ([[mi title] isEqualToString: _NS("Information")]) {
-        return ![[[VLCMain sharedInstance] playlist] isSelectionEmpty];
-    }
-
-    return TRUE;
-}
-
-@end
-
-@implementation VLCInfo (NSTableDataSource)
-
-- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
-{
-    return (item == nil) ? [rootItem numberOfChildren] : [item numberOfChildren];
-}
-
-- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
-    return ([item numberOfChildren] > 0);
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
-{
-    return (item == nil) ? [rootItem childAtIndex:index] : (id)[item childAtIndex:index];
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
-{
-    if ([[tableColumn identifier] isEqualToString:@"0"])
-        return (item == nil) ? @"" : (id)[item name];
-    else
-        return (item == nil) ? @"" : (id)[item value];
-}
-
-@end
-
-@interface VLCInfoTreeItem ()
-{
-    int i_object_id;
-    input_item_t *p_item;
-    VLCInfoTreeItem *_parent;
-    NSMutableArray *_children;
-    BOOL _isALeafNode;
-}
-
-@end
-
-@implementation VLCInfoTreeItem
-
-- (id)initWithName:(NSString *)item_name
-             value:(NSString *)item_value
-                ID:(int)i_id
-            parent:(VLCInfoTreeItem *)parent_item
-{
-    self = [super init];
-
-    if (self != nil) {
-        _name = [item_name copy];
-        _value = [item_value copy];
-        i_object_id = i_id;
-        _parent = parent_item;
-        p_item = [[VLCInfo sharedInstance] item];
-    }
-    return self;
-}
-
-- (id)init
-{
-    return [self initWithName:@"main" value:@"" ID:-1 parent:nil];
-}
-
-- (void)dealloc
-{
-    if (p_item)
-        vlc_gc_decref(p_item);
-}
-
-/* Creates and returns the array of children
- *Loads children incrementally */
-- (void)_updateChildren
-{
-    if (!p_item)
-        return;
-
-    if (_children != nil)
-        return;
-
-    _children = [[NSMutableArray alloc] init];
-    if (i_object_id == -1) {
-        vlc_mutex_lock(&p_item->lock);
-        for (int i = 0 ; i < p_item->i_categories ; i++) {
-            NSString *name = toNSStr(p_item->pp_categories[i]->psz_name);
-            VLCInfoTreeItem *item = [[VLCInfoTreeItem alloc]
-                                      initWithName:name
-                                      value:@""
-                                      ID:i
-                                      parent:self];
-            [_children addObject:item];
-        }
-        vlc_mutex_unlock(&p_item->lock);
-        _isALeafNode = NO;
-    }
-    else if (_parent->i_object_id == -1) {
-        vlc_mutex_lock(&p_item->lock);
-        info_category_t *cat = p_item->pp_categories[i_object_id];
-        for (int i = 0 ; i < cat->i_infos ; i++) {
-            NSString *name = toNSStr(cat->pp_infos[i]->psz_name);
-            NSString *value  = toNSStr(cat->pp_infos[i]->psz_value);
-            VLCInfoTreeItem *item = [[VLCInfoTreeItem alloc]
-                                     initWithName:name
-                                     value:value
-                                     ID:i
-                                     parent:self];
-            [_children addObject:item];
-        }
-        vlc_mutex_unlock(&p_item->lock);
-        _isALeafNode = NO;
-    }
-    else
-        _isALeafNode = YES;
-}
-
-- (void)refresh
-{
-    if (p_item)
-        vlc_gc_decref(p_item);
-
-    p_item = [[VLCInfo sharedInstance] item];
-
-    _children = nil;
-}
-
-- (VLCInfoTreeItem *)childAtIndex:(NSUInteger)i_index
-{
-    return [_children objectAtIndex:i_index];
-}
-
-- (int)numberOfChildren
-{
-    [self _updateChildren];
-
-    if (_isALeafNode)
-        return -1;
-
-    return [_children count];
-}
-
-@end
-
diff --git a/modules/gui/macosx/playlistview.h b/modules/gui/macosx/playlistview.h
deleted file mode 100644 (file)
index fe96528..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*****************************************************************************
- * playlist.h: MacOS X interface module
- *****************************************************************************
- * Copyright (C) 2002-2015 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Derk-Jan Hartman <hartman at videolan dot org>
- *          Felix Paul Kühne <fkuehne at videolan dot org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#import <Cocoa/Cocoa.h>
-
-@interface VLCPlaylistView : NSOutlineView
-
-@end
diff --git a/modules/gui/macosx/playlistview.m b/modules/gui/macosx/playlistview.m
deleted file mode 100644 (file)
index 24a08f9..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*****************************************************************************
- * playlistview.m: MacOS X interface module
- *****************************************************************************
-* Copyright (C) 2003-2015 VLC authors and VideoLAN
- * $Id$
- *
- * Authors: Derk-Jan Hartman <hartman at videola/n dot org>
- *          Benjamin Pracht <bigben at videolab dot org>
- *          Felix Paul Kühne <fkuehne at videolan dot org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#import "intf.h"
-#import "playlistview.h"
-#import "playlist.h"
-
-@implementation VLCPlaylistView
-
-- (NSMenu *)menuForEvent:(NSEvent *)event
-{
-    return([(VLCPlaylist *)[self delegate] menuForEvent: event]);
-}
-
-- (void)keyDown:(NSEvent *)event
-{
-    unichar key = 0;
-
-    if ([[event characters] length])
-        key = [[event characters] characterAtIndex: 0];
-
-    switch(key) {
-        case NSDeleteCharacter:
-        case NSDeleteFunctionKey:
-        case NSDeleteCharFunctionKey:
-        case NSBackspaceCharacter:
-            [(VLCPlaylist *)[self delegate] deleteItem:self];
-            break;
-
-        case NSEnterCharacter:
-        case NSCarriageReturnCharacter:
-            [(VLCPlaylist *)[[VLCMain sharedInstance] playlist] playItem:nil];
-            break;
-
-        default:
-            [super keyDown: event];
-            break;
-    }
-}
-
-- (BOOL)validateMenuItem:(NSMenuItem *)item
-{
-    if (([self numberOfSelectedRows] >= 1 && [item action] == @selector(delete:)) || [item action] == @selector(selectAll:))
-        return YES;
-
-    return NO;
-}
-
-- (BOOL)acceptsFirstResponder
-{
-    return YES;
-}
-
-- (BOOL)becomeFirstResponder
-{
-    [self setNeedsDisplay:YES];
-    return YES;
-}
-
-- (BOOL)resignFirstResponder
-{
-    [self setNeedsDisplay:YES];
-    return YES;
-}
-
-- (IBAction)delete:(id)sender
-{
-    [[[VLCMain sharedInstance] playlist] deleteItem: sender];
-}
-
-@end
index 8077a0c..a5b21c8 100644 (file)
@@ -589,12 +589,12 @@ modules/gui/macosx/open.h
 modules/gui/macosx/open.m
 modules/gui/macosx/output.h
 modules/gui/macosx/output.m
-modules/gui/macosx/playlist.h
-modules/gui/macosx/playlist.m
-modules/gui/macosx/playlistinfo.h
-modules/gui/macosx/playlistinfo.m
-modules/gui/macosx/playlistview.h
-modules/gui/macosx/playlistview.m
+modules/gui/macosx/VLCPlaylist.h
+modules/gui/macosx/VLCPlaylist.m
+modules/gui/macosx/VLCPlaylistInfo.h
+modules/gui/macosx/VLCPlaylistInfo.m
+modules/gui/macosx/VLCPlaylistView.h
+modules/gui/macosx/VLCPlaylistView.m
 modules/gui/macosx/prefs.h
 modules/gui/macosx/prefs.m
 modules/gui/macosx/prefs_widgets.h