[vlc-devel] [vlc-commits] macosx: basic implementation of the playlist data model

Thomas Guillem thomas at gllm.fr
Thu Feb 7 13:22:29 CET 2019



On Thu, Jan 31, 2019, at 14:02, Felix Paul Kühne wrote:
> vlc | branch: master | Felix Paul Kühne <felix at feepk.net> | Thu Jan 31 
> 12:50:20 2019 +0100| [d14583a48d513cadbdd9b5c1b522685acd530ca4] | 
> committer: Felix Paul Kühne
> 
> macosx: basic implementation of the playlist data model
> 
> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d14583a48d513cadbdd9b5c1b522685acd530ca4
> ---
> 
>  .../package/macosx/VLC.xcodeproj/project.pbxproj   |  24 ++
>  modules/gui/macosx/Makefile.am                     |   4 +
>  modules/gui/macosx/VLCLibraryWindow.h              |   4 -
>  modules/gui/macosx/VLCLibraryWindow.m              |  50 +---
>  modules/gui/macosx/VLCMain.h                       |   2 +
>  modules/gui/macosx/VLCMain.m                       |   2 +
>  modules/gui/macosx/VLCPlaylistController.h         |  56 ++++
>  modules/gui/macosx/VLCPlaylistController.m         | 316 +++++++++++++++++++++
>  modules/gui/macosx/VLCPlaylistDataSource.h         |  38 +++
>  modules/gui/macosx/VLCPlaylistDataSource.m         |  97 +++++++
>  modules/gui/macosx/VLCPlaylistItem.h               |  42 +++
>  modules/gui/macosx/VLCPlaylistItem.m               |  53 ++++
>  modules/gui/macosx/VLCPlaylistModel.h              |  42 +++
>  modules/gui/macosx/VLCPlaylistModel.m              |  72 +++++
>  14 files changed, 755 insertions(+), 47 deletions(-)
> 
> diff --git a/extras/package/macosx/VLC.xcodeproj/project.pbxproj 
> b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
> index bac1891aab..27381cfe78 100644
> --- a/extras/package/macosx/VLC.xcodeproj/project.pbxproj
> +++ b/extras/package/macosx/VLC.xcodeproj/project.pbxproj
> @@ -120,8 +120,12 @@
>  		6BF5C5041EFE66EF008A9C12 /* VLCHUDTableView.m in Sources */ = {isa = 
> PBXBuildFile; fileRef = 6BF5C5031EFE66EF008A9C12 /* VLCHUDTableView.m 
> */; };
>  		7D0F63FF2201F63400FDB91F /* VLCPlaylistTableCellView.m in Sources */ 
> = {isa = PBXBuildFile; fileRef = 7D0F63FE2201F63400FDB91F /* 
> VLCPlaylistTableCellView.m */; };
>  		7D0F64062202047900FDB91F /* VLCLibraryCollectionViewItem.m in 
> Sources */ = {isa = PBXBuildFile; fileRef = 7D0F64042202047900FDB91F /* 
> VLCLibraryCollectionViewItem.m */; };
> +		7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */ = 
> {isa = PBXBuildFile; fileRef = 7D0F640B2202163E00FDB91F /* 
> VLCPlaylistDataSource.m */; };
>  		7D2E0EDB20CD204D0033A221 /* VLCWindow.m in Sources */ = {isa = 
> PBXBuildFile; fileRef = 7D2E0ED920CD204D0033A221 /* VLCWindow.m */; };
>  		7D2E0EDE20CD206F0033A221 /* VLCVideoWindowCommon.m in Sources */ = 
> {isa = PBXBuildFile; fileRef = 7D2E0EDD20CD206F0033A221 /* 
> VLCVideoWindowCommon.m */; };
> +		7D445D812202524000263D34 /* VLCPlaylistController.m in Sources */ = 
> {isa = PBXBuildFile; fileRef = 7D445D802202524000263D34 /* 
> VLCPlaylistController.m */; };
> +		7D445D842202524D00263D34 /* VLCPlaylistItem.m in Sources */ = {isa = 
> PBXBuildFile; fileRef = 7D445D832202524D00263D34 /* VLCPlaylistItem.m 
> */; };
> +		7D445D872202574B00263D34 /* VLCPlaylistModel.m in Sources */ = {isa 
> = PBXBuildFile; fileRef = 7D445D862202574B00263D34 /* 
> VLCPlaylistModel.m */; };
>  		7D66D4362200BC340040D04A /* VLCClickerManager.m in Sources */ = {isa 
> = PBXBuildFile; fileRef = 7D66D4352200BC340040D04A /* 
> VLCClickerManager.m */; };
>  		7D66D4392200C5B80040D04A /* VLCVideoFilterHelper.m in Sources */ = 
> {isa = PBXBuildFile; fileRef = 7D66D4382200C5B80040D04A /* 
> VLCVideoFilterHelper.m */; };
>  		7D66D43C2200D6090040D04A /* VLCDetachedVideoWindow.m in Sources */ = 
> {isa = PBXBuildFile; fileRef = 7D66D43B2200D6090040D04A /* 
> VLCDetachedVideoWindow.m */; };
> @@ -442,10 +446,18 @@
>  		7D0F64052202047900FDB91F /* VLCLibraryCollectionViewItem.xib */ = 
> {isa = PBXFileReference; lastKnownFileType = file.xib; path = 
> VLCLibraryCollectionViewItem.xib; sourceTree = "<group>"; };
>  		7D0F64082202058700FDB91F /* libraryCellGradient at 1x.png */ = {isa = 
> PBXFileReference; lastKnownFileType = image.png; name = 
> "libraryCellGradient at 1x.png"; path = 
> "../librarywindow/libraryCellGradient at 1x.png"; sourceTree = "<group>"; 
> };
>  		7D0F64092202058700FDB91F /* libraryCellGradient at 2x.png */ = {isa = 
> PBXFileReference; lastKnownFileType = image.png; name = 
> "libraryCellGradient at 2x.png"; path = 
> "../librarywindow/libraryCellGradient at 2x.png"; sourceTree = "<group>"; 
> };
> +		7D0F640A2202163E00FDB91F /* VLCPlaylistDataSource.h */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 
> VLCPlaylistDataSource.h; sourceTree = "<group>"; };
> +		7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
> VLCPlaylistDataSource.m; sourceTree = "<group>"; };
>  		7D2E0ED920CD204D0033A221 /* VLCWindow.m */ = {isa = 
> PBXFileReference; fileEncoding = 4; lastKnownFileType = 
> sourcecode.c.objc; path = VLCWindow.m; sourceTree = "<group>"; };
>  		7D2E0EDA20CD204D0033A221 /* VLCWindow.h */ = {isa = 
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; 
> path = VLCWindow.h; sourceTree = "<group>"; };
>  		7D2E0EDC20CD206F0033A221 /* VLCVideoWindowCommon.h */ = {isa = 
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; 
> path = VLCVideoWindowCommon.h; sourceTree = "<group>"; };
>  		7D2E0EDD20CD206F0033A221 /* VLCVideoWindowCommon.m */ = {isa = 
> PBXFileReference; fileEncoding = 4; lastKnownFileType = 
> sourcecode.c.objc; path = VLCVideoWindowCommon.m; sourceTree = 
> "<group>"; };
> +		7D445D7F2202524000263D34 /* VLCPlaylistController.h */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 
> VLCPlaylistController.h; sourceTree = "<group>"; };
> +		7D445D802202524000263D34 /* VLCPlaylistController.m */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
> VLCPlaylistController.m; sourceTree = "<group>"; };
> +		7D445D822202524D00263D34 /* VLCPlaylistItem.h */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 
> VLCPlaylistItem.h; sourceTree = "<group>"; };
> +		7D445D832202524D00263D34 /* VLCPlaylistItem.m */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
> VLCPlaylistItem.m; sourceTree = "<group>"; };
> +		7D445D852202574B00263D34 /* VLCPlaylistModel.h */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 
> VLCPlaylistModel.h; sourceTree = "<group>"; };
> +		7D445D862202574B00263D34 /* VLCPlaylistModel.m */ = {isa = 
> PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
> VLCPlaylistModel.m; sourceTree = "<group>"; };
>  		7D5678EB1D5BA1DC002698F3 /* VLCApplication.h */ = {isa = 
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; 
> path = VLCApplication.h; sourceTree = "<group>"; };
>  		7D5678EC1D5BA1DC002698F3 /* VLCApplication.m */ = {isa = 
> PBXFileReference; fileEncoding = 4; lastKnownFileType = 
> sourcecode.c.objc; path = VLCApplication.m; sourceTree = "<group>"; };
>  		7D5678EE1D5BA397002698F3 /* VLCMainWindowControlsBar.h */ = {isa = 
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; 
> path = VLCMainWindowControlsBar.h; sourceTree = "<group>"; };
> @@ -1308,6 +1320,14 @@
>  			children = (
>  				7D713D302201AE350042BEB7 /* VLCLibraryWindow.h */,
>  				7D713D312201AE350042BEB7 /* VLCLibraryWindow.m */,
> +				7D0F640A2202163E00FDB91F /* VLCPlaylistDataSource.h */,
> +				7D0F640B2202163E00FDB91F /* VLCPlaylistDataSource.m */,
> +				7D445D7F2202524000263D34 /* VLCPlaylistController.h */,
> +				7D445D802202524000263D34 /* VLCPlaylistController.m */,
> +				7D445D852202574B00263D34 /* VLCPlaylistModel.h */,
> +				7D445D862202574B00263D34 /* VLCPlaylistModel.m */,
> +				7D445D822202524D00263D34 /* VLCPlaylistItem.h */,
> +				7D445D832202524D00263D34 /* VLCPlaylistItem.m */,
>  				7D0F63FD2201F63400FDB91F /* VLCPlaylistTableCellView.h */,
>  				7D0F63FE2201F63400FDB91F /* VLCPlaylistTableCellView.m */,
>  				7D0F64032202047900FDB91F /* VLCLibraryCollectionViewItem.h */,
> @@ -1640,6 +1660,7 @@
>  				1CCC88F52078A3D500E5626F /* SyncTracks.xib in Sources */,
>  				1CCC88F62078A3D500E5626F /* MediaInfo.xib in Sources */,
>  				7D66D4392200C5B80040D04A /* VLCVideoFilterHelper.m in Sources */,
> +				7D445D812202524000263D34 /* VLCPlaylistController.m in Sources */,
>  				1CCC88F72078A3D500E5626F /* ConvertAndSave.xib in Sources */,
>  				1CCC88F82078A3D500E5626F /* CoreDialogs.xib in Sources */,
>  				1CCC88F92078A3D500E5626F /* DetachedVideoWindow.xib in Sources */,
> @@ -1699,6 +1720,8 @@
>  				1C3113A71E508C6900D4DD76 /* VLCLogWindowController.m in Sources */,
>  				1C3113A91E508C6900D4DD76 /* VLCDocumentController.m in Sources */,
>  				1C3113AB1E508C6900D4DD76 /* VLCExtensionsDialogProvider.m in 
> Sources */,
> +				7D445D872202574B00263D34 /* VLCPlaylistModel.m in Sources */,
> +				7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */,
>  				1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */,
>  				1C3113AF1E508C6900D4DD76 /* VLCFSPanelController.m in Sources */,
>  				7D66D4362200BC340040D04A /* VLCClickerManager.m in Sources */,
> @@ -1721,6 +1744,7 @@
>  				6BBB05DA1EEFEA29003A1019 /* VLCHUDOutlineView.m in Sources */,
>  				1C3113CB1E508C6900D4DD76 /* VLCPLItem.m in Sources */,
>  				6B8A6B0B2128697E00DC29F3 /* VLCSourceListTableCellView.m in 
> Sources */,
> +				7D445D842202524D00263D34 /* VLCPlaylistItem.m in Sources */,
>  				1C3113CD1E508C6900D4DD76 /* VLCPLModel.m in Sources */,
>  				1C3113CF1E508C6900D4DD76 /* prefs_widgets.m in Sources */,
>  				7D0F63FF2201F63400FDB91F /* VLCPlaylistTableCellView.m in Sources 
> */,
> diff --git a/modules/gui/macosx/Makefile.am 
> b/modules/gui/macosx/Makefile.am
> index bd69ff7105..140fc30039 100644
> --- a/modules/gui/macosx/Makefile.am
> +++ b/modules/gui/macosx/Makefile.am
> @@ -91,6 +91,10 @@ libmacosx_plugin_la_SOURCES = \
>  	gui/macosx/VLCRemoteControlService.h 
> gui/macosx/VLCRemoteControlService.m \
>  	gui/macosx/VLCMainWindow.h gui/macosx/VLCMainWindow.m \
>  	gui/macosx/VLCLibraryWindow.h gui/macosx/VLCLibraryWindow.m \
> +	gui/macosx/VLCPlaylistController.h gui/macosx/VLCPlaylistController.m 
> \
> +	gui/macosx/VLCPlaylistDataSource.h gui/macosx/VLCPlaylistDataSource.m 
> \
> +	gui/macosx/VLCPlaylistItem.h gui/macosx/VLCPlaylistItem.m \
> +	gui/macosx/VLCPlaylistModel.h gui/macosx/VLCPlaylistModel.m \
>  	gui/macosx/VLCPlaylistTableCellView.h 
> gui/macosx/VLCPlaylistTableCellView.m \
>  	gui/macosx/VLCLibraryCollectionViewItem.h 
> gui/macosx/VLCLibraryCollectionViewItem.m \
>  	gui/macosx/VLCDetachedVideoWindow.h 
> gui/macosx/VLCDetachedVideoWindow.m \
> diff --git a/modules/gui/macosx/VLCLibraryWindow.h 
> b/modules/gui/macosx/VLCLibraryWindow.h
> index ff46748952..8fe7e638fa 100644
> --- a/modules/gui/macosx/VLCLibraryWindow.h
> +++ b/modules/gui/macosx/VLCLibraryWindow.h
> @@ -38,10 +38,6 @@ NS_ASSUME_NONNULL_BEGIN
>  
>  @end
>  
> - at interface VLCPlaylistDataSource : NSObject <NSTableViewDataSource, 
> NSTableViewDelegate>
> -
> - at end
> -
>  @interface VLCLibraryDataSource : NSObject 
> <NSCollectionViewDataSource, NSCollectionViewDelegate>
>  
>  @end
> diff --git a/modules/gui/macosx/VLCLibraryWindow.m 
> b/modules/gui/macosx/VLCLibraryWindow.m
> index d1b762ede9..b4e72a5af9 100644
> --- a/modules/gui/macosx/VLCLibraryWindow.m
> +++ b/modules/gui/macosx/VLCLibraryWindow.m
> @@ -23,13 +23,15 @@
>  #import "VLCLibraryWindow.h"
>  #import "NSString+Helpers.h"
>  #import "VLCPlaylistTableCellView.h"
> +#import "VLCPlaylistController.h"
> +#import "VLCPlaylistDataSource.h"
>  #import "VLCLibraryCollectionViewItem.h"
> +#import "VLCMain.h"
>  
>  static const float f_min_window_width = 604.;
>  static const float f_min_window_height = 307.;
>  static const float f_playlist_row_height = 40.;
>  
> -static NSString *VLCPlaylistCellIdentifier = @"VLCPlaylistCellIdentifier";
>  static NSString *VLCLibraryCellIdentifier = @"VLCLibraryCellIdentifier";
>  
>  @interface VLCLibraryWindow ()
> @@ -51,7 +53,11 @@ static NSString *VLCLibraryCellIdentifier = 
> @"VLCLibraryCellIdentifier";
>      [_segmentedTitleControl setLabel:_NS("Network") forSegment:2];
>      [_segmentedTitleControl sizeToFit];
>  
> +    VLCPlaylistController *playlistController = [[VLCMain 
> sharedInstance] playlistController];
>      _playlistDataSource = [[VLCPlaylistDataSource alloc] init];
> +    _playlistDataSource.playlistController = playlistController;
> +    _playlistDataSource.tableView = _playlistTableView;
> +    playlistController.playlistDataSource = _playlistDataSource;
>  
>      _playlistTableView.dataSource = _playlistDataSource;
>      _playlistTableView.delegate = _playlistDataSource;
> @@ -71,48 +77,6 @@ static NSString *VLCLibraryCellIdentifier = 
> @"VLCLibraryCellIdentifier";
>  
>  @end
>  
> - at implementation VLCPlaylistDataSource
> -
> -- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
> -{
> -    return 2;
> -}
> -
> -- (NSView *)tableView:(NSTableView *)tableView 
> viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
> -{
> -    VLCPlaylistTableCellView *cellView = [tableView 
> makeViewWithIdentifier:VLCPlaylistCellIdentifier owner:self];
> -
> -    if (cellView == nil) {
> -        /* the following code saves us an instance of NSViewController 
> which we don't need */
> -        NSNib *nib = [[NSNib alloc] 
> initWithNibNamed:@"VLCPlaylistTableCellView" bundle:nil];
> -        NSArray *topLevelObjects;
> -        if (![nib instantiateWithOwner:self 
> topLevelObjects:&topLevelObjects]) {
> -            NSLog(@"Failed to load nib %@", nib);
> -            return nil;
> -        }
> -
> -        for (id topLevelObject in topLevelObjects) {
> -            if ([topLevelObject 
> isKindOfClass:[VLCPlaylistTableCellView class]]) {
> -                cellView = topLevelObject;
> -                break;
> -            }
> -        }
> -        cellView.identifier = VLCPlaylistCellIdentifier;
> -    }
> -
> -    cellView.mediaTitleTextField.stringValue = @"Custom Cell Label 
> Text";
> -    cellView.durationTextField.stringValue = @"00:00";
> -    cellView.mediaImageView.image = [NSImage imageNamed: @"noart.png"];
> -    return cellView;
> -}
> -
> -- (void)tableViewSelectionDidChange:(NSNotification *)notification
> -{
> -    NSLog(@"playlist selection changed: %li", (long)[(NSTableView 
> *)notification.object selectedRow]);
> -}
> -
> - at end
> -
>  @implementation VLCLibraryDataSource
>  
>  - (NSInteger)collectionView:(NSCollectionView *)collectionView 
> numberOfItemsInSection:(NSInteger)section
> diff --git a/modules/gui/macosx/VLCMain.h b/modules/gui/macosx/VLCMain.h
> index 7863d1f497..5b55a59de6 100644
> --- a/modules/gui/macosx/VLCMain.h
> +++ b/modules/gui/macosx/VLCMain.h
> @@ -77,6 +77,7 @@ static NSString * 
> VLCAppleRemoteSettingChangedNotification = @"VLCAppleRemoteSet
>  @class VLCExtensionsManager;
>  @class VLCInfo;
>  @class VLCStatusBarIcon;
> + at class VLCPlaylistController;
>  
>  @interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
>  
> @@ -84,6 +85,7 @@ static NSString * 
> VLCAppleRemoteSettingChangedNotification = @"VLCAppleRemoteSet
>  @property (readonly) BOOL nativeFullscreenMode;
>  @property (nonatomic, readwrite) BOOL playlistUpdatedSelectorInQueue;
>  @property (readonly) VLCLibraryWindowController 
> *libraryWindowController;
> + at property (readonly) VLCPlaylistController *playlistController;
>  
>  + (VLCMain *)sharedInstance;
>  + (void)killInstance;
> diff --git a/modules/gui/macosx/VLCMain.m b/modules/gui/macosx/VLCMain.m
> index c2c07f0859..b0c57fad0b 100644
> --- a/modules/gui/macosx/VLCMain.m
> +++ b/modules/gui/macosx/VLCMain.m
> @@ -61,6 +61,7 @@
>  #import "VLCLogWindowController.h"
>  #import "VLCConvertAndSaveWindowController.h"
>  #import "VLCLibraryWindow.h"
> +#import "VLCPlaylistController.h"
>  
>  #import "VLCVideoEffectsWindowController.h"
>  #import "VLCAudioEffectsWindowController.h"
> @@ -221,6 +222,7 @@ static VLCMain *sharedInstance = nil;
>  
>          [VLCApplication sharedApplication].delegate = self;
>  
> +        _playlistController = [[VLCPlaylistController alloc] init];
>          _input_manager = [[VLCInputManager alloc] initWithMain:self];
>  
>          // first initalize extensions dialog provider, then core dialog
> diff --git a/modules/gui/macosx/VLCPlaylistController.h 
> b/modules/gui/macosx/VLCPlaylistController.h
> new file mode 100644
> index 0000000000..63652603cb
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistController.h
> @@ -0,0 +1,56 @@
> +/*****************************************************************************
> + * VLCPlaylistController.h: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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 <Foundation/Foundation.h>
> +#import <vlc_playlist.h>
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at class VLCPlaylistModel;
> + at class VLCPlaylistDataSource;
> +
> + at interface VLCPlaylistController : NSObject
> +
> + at property (readonly) vlc_playlist_t *p_playlist;
> + at property (readonly) VLCPlaylistModel *playlistModel;
> + at property (readwrite, assign) VLCPlaylistDataSource 
> *playlistDataSource;
> +
> +/**
> + * Simplified version to add new items at the end of the current 
> playlist
> + * @param array array of items. Each item is a Dictionary with meta 
> info.
> + */
> +- (void)addPlaylistItems:(NSArray*)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*)itemArray
> +              atPosition:(size_t)insertionIndex
> +           startPlayback:(BOOL)b_start;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistController.m 
> b/modules/gui/macosx/VLCPlaylistController.m
> new file mode 100644
> index 0000000000..878ccb0d6d
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistController.m
> @@ -0,0 +1,316 @@
> +/*****************************************************************************
> + * VLCPlaylistController.m: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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 "VLCPlaylistController.h"
> +#import "VLCPlaylistModel.h"
> +#import "VLCPlaylistDataSource.h"
> +#import "VLCMain.h"
> +#import <vlc_interface.h>
> +
> + at interface VLCPlaylistController ()
> +{
> +    vlc_playlist_t *_p_playlist;
> +    vlc_playlist_listener_id *_playlistListenerID;
> +}
> +
> +- (void)playlistAdded:(vlc_playlist_item_t *const *)items 
> atIndex:(size_t)insertionIndex count:(size_t)numberOfItems;
> +- (void)playlistRemovedItemsAtIndex:(size_t)index 
> count:(size_t)numberOfItems;
> +- (void)currentPlaylistItemChanged:(ssize_t)index;
> +
> + at end
> +
> +#pragma mark -
> +#pragma mark core callbacks
> +
> +static void
> +cb_playlist_items_reset(vlc_playlist_t *playlist,
> +                        vlc_playlist_item_t *const items[],
> +                        size_t numberOfItems,
> +                        void *p_data)
> +{
> +    NSLog(@"%s: numberOfItems %zu", __func__, numberOfItems);
> +}
> +
> +static void
> +cb_playlist_items_added(vlc_playlist_t *playlist,
> +                        size_t insertionIndex,
> +                        vlc_playlist_item_t *const items[],
> +                        size_t numberOfAddedItems,
> +                        void *p_data)
> +{
> +    NSLog(@"%s: insertionIndex: %zu numberOfAddedItems: %zu", 
> __func__, insertionIndex, numberOfAddedItems);
> +    VLCPlaylistController *playlistController = (__bridge 
> VLCPlaylistController *)p_data;
> +    [playlistController playlistAdded:items atIndex:insertionIndex 
> count:numberOfAddedItems];
> +}
> +
> +static void
> +cb_playlist_items_removed(vlc_playlist_t *playlist,
> +                          size_t index,
> +                          size_t count,
> +                          void *p_data)
> +{
> +    NSLog(@"%s: index: %zu count: %zu", __func__, index, count);
> +    VLCPlaylistController *playlistController = (__bridge 
> VLCPlaylistController *)p_data;
> +    [playlistController playlistRemovedItemsAtIndex:index count:count];
> +}
> +
> +static void
> +cb_playlist_items_updated(vlc_playlist_t *playlist,
> +                          size_t index,
> +                          vlc_playlist_item_t *const items[],
> +                          size_t len,
> +                          void *p_data)
> +{
> +    NSLog(@"%s: index: %zu len: %zu", __func__, index, len);
> +}
> +
> +static void
> +cb_playlist_playback_repeat_changed(vlc_playlist_t *playlist,
> +                                    enum vlc_playlist_playback_repeat 
> repeat,
> +                                    void *userdata)
> +{
> +    NSLog(@"%s: repeat mode: %u", __func__, repeat);
> +}
> +
> +static void
> +cb_playlist_playback_order_changed(vlc_playlist_t *playlist,
> +                                   enum vlc_playlist_playback_order 
> order,
> +                                   void *userdata)
> +{
> +    NSLog(@"%s: playback order: %u", __func__, order);
> +}
> +
> +static void
> +cb_playlist_current_item_changed(vlc_playlist_t *playlist,
> +                                 ssize_t index,
> +                                 void *p_data)
> +{
> +    if (index == UINT64_MAX) {
> +        NSLog(@"%s: no current item", __func__);
> +    }
> +    VLCPlaylistController *playlistController = (__bridge 
> VLCPlaylistController *)p_data;
> +    [playlistController currentPlaylistItemChanged:index];
> +
> +    NSLog(@"%s: index: %zu", __func__, index);
> +}
> +
> +static const struct vlc_playlist_callbacks playlist_callbacks = {
> +    cb_playlist_items_reset,
> +    cb_playlist_items_added,
> +    NULL,
> +    cb_playlist_items_removed,
> +    cb_playlist_items_updated,
> +    cb_playlist_playback_repeat_changed,
> +    cb_playlist_playback_order_changed,
> +    cb_playlist_current_item_changed,
> +    NULL,
> +    NULL,
> +};
> +
> +#pragma mark -
> +#pragma mark class initialization
> +
> + at implementation VLCPlaylistController
> +
> +- (instancetype)init
> +{
> +    self = [super init];
> +    if (self) {
> +        intf_thread_t *p_intf = getIntf();
> +        _p_playlist = vlc_intf_GetMainPlaylist( p_intf );
> +        _playlistListenerID = vlc_playlist_AddListener(_p_playlist,
> +                                                       
> &playlist_callbacks,
> +                                                       (__bridge void 
> *)self,
> +                                                       YES);
> +        _playlistModel = [[VLCPlaylistModel alloc] init];
> +        _playlistModel.playlistController = self;
> +    }
> +    return self;
> +}
> +
> +- (void)dealloc
> +{
> +    if (_p_playlist) {
> +        if (_playlistListenerID) {
> +            vlc_playlist_RemoveListener(_p_playlist, 
> _playlistListenerID);
> +        }
> +        vlc_playlist_Delete(_p_playlist);
> +    }
> +}
> +
> +#pragma mark - callback forwarders
> +
> +- (void)playlistAdded:(vlc_playlist_item_t *const *)items 
> atIndex:(size_t)insertionIndex count:(size_t)numberOfItems
> +{
> +    NSLog(@"%s", __func__);
> +
> +    for (size_t i = 0; i < numberOfItems; i++) {
> +        [_playlistModel addItem:items[i] atIndex:insertionIndex];
> +        insertionIndex++;
> +    }
> +
> +    [_playlistDataSource playlistUpdated];
> +}
> +
> +- (void)playlistRemovedItemsAtIndex:(size_t)index 
> count:(size_t)numberOfItems
> +{
> +    NSLog(@"%s", __func__);
> +
> +    for (size_t i = index + numberOfItems; i > index; i--) {
> +        [_playlistModel removeItemAtIndex:i];
> +    }
> +}
> +
> +- (void)currentPlaylistItemChanged:(ssize_t)index
> +{
> +    [_playlistDataSource playlistUpdated];
> +}
> +
> +#pragma mark - controller functions for use within the UI
> +
> +- (void)addPlaylistItems:(NSArray*)array
> +{
> +    BOOL b_autoplay = var_InheritBool(getIntf(), "macosx-autoplay");
> +    [self addPlaylistItems:array atPosition:-1 
> startPlayback:b_autoplay];
> +}
> +
> +- (void)addPlaylistItems:(NSArray*)itemArray
> +              atPosition:(size_t)insertionIndex
> +           startPlayback:(BOOL)startPlayback;
> +{
> +    intf_thread_t *p_intf = getIntf();
> +    NSUInteger numberOfItems = [itemArray count];
> +
> +    for (NSUInteger i = 0; i < numberOfItems; i++) {
> +        NSDictionary *itemMetadata = itemArray[i];
> +        input_item_t *p_input = [self 
> createInputItemBasedOnMetadata:itemMetadata];
> +        NSString *itemURLString = itemMetadata[@"ITEM_URL"];
> +
> +        if (!p_input) {
> +            if (itemURLString) {
> +                msg_Warn(p_intf, "failed to create input for %s", 
> [itemURLString UTF8String]);
> +            } else {
> +                msg_Warn(p_intf, "failed to create input because no 
> URL was provided");
> +            }
> +            continue;
> +        }
> +
> +        vlc_playlist_Lock(_p_playlist);
> +
> +        int ret = 0;
> +        size_t actualInsertionIndex = insertionIndex;
> +        if (insertionIndex == -1) {
> +            actualInsertionIndex = vlc_playlist_Count(_p_playlist);
> +        }
> +        ret = vlc_playlist_Insert(_p_playlist,
> +                                      actualInsertionIndex,
> +                                      &p_input,
> +                                      1);
> +
> +        if (ret != VLC_SUCCESS) {
> +            msg_Err(p_intf, "failed to insert input item at insertion 
> index: %zu", insertionIndex);
> +        } else {
> +            msg_Dbg(p_intf, "Added item %s at insertion index: %zu", 
> [itemURLString UTF8String], insertionIndex);
> +        }
> +
> +        if (i == 0 && startPlayback) {
> +            vlc_playlist_PlayAt(_p_playlist, actualInsertionIndex);
> +        }
> +
> +        vlc_playlist_Unlock(_p_playlist);
> +        input_item_Release(p_input);
> +
> +        if (insertionIndex != -1) {
> +            insertionIndex++;
> +        }
> +    }
> +}
> +
> +#pragma mark - helper methods
> +
> +- (input_item_t *)createInputItemBasedOnMetadata:(NSDictionary 
> *)itemToCreateDict
> +{
> +    intf_thread_t *p_intf = getIntf();
> +
> +    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 = 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://%@", 
> getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaVideoTSFolder])
> +            uri = [NSString stringWithFormat: @"dvdnav://%@", path];
> +        else if ([diskType isEqualToString: kVLCMediaAudioCD])
> +            uri = [NSString stringWithFormat: @"cdda://%@", 
> getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaVCD])
> +            uri = [NSString stringWithFormat: @"vcd://%@#0:0", 
> getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaSVCD])
> +            uri = [NSString stringWithFormat: @"vcd://%@@0:0", 
> getBSDNodeFromMountPath(path)];
> +        else if ([diskType isEqualToString: kVLCMediaBD] || [diskType 
> isEqualToString: kVLCMediaBDMVFolder])
> +            uri = [NSString stringWithFormat: @"bluray://%@", path];
> +        else
> +            msg_Warn(getIntf(), "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 
> objectAtIndex:i] UTF8String], VLC_INPUT_OPTION_TRUSTED);
> +    }
> +
> +    /* Recent documents menu */
> +    if (url != nil && var_InheritBool(getIntf(), "macosx-recentitems"))
> +        [[NSDocumentController sharedDocumentController] 
> noteNewRecentDocumentURL:url];
> +
> +    return p_input;
> +}
> +
> + at end
> diff --git a/modules/gui/macosx/VLCPlaylistDataSource.h 
> b/modules/gui/macosx/VLCPlaylistDataSource.h
> new file mode 100644
> index 0000000000..8dab982c68
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistDataSource.h
> @@ -0,0 +1,38 @@
> +/*****************************************************************************
> + * VLCPlaylistDataSource.h: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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>
> +
> + at class VLCPlaylistController;
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at interface VLCPlaylistDataSource : NSObject <NSTableViewDataSource, 
> NSTableViewDelegate>
> +
> + at property (readwrite, assign, nonatomic) VLCPlaylistController 
> *playlistController;
> + at property (readwrite, assign) NSTableView *tableView;
> +
> +- (void)playlistUpdated;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistDataSource.m 
> b/modules/gui/macosx/VLCPlaylistDataSource.m
> new file mode 100644
> index 0000000000..05e7df8a55
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistDataSource.m
> @@ -0,0 +1,97 @@
> +/*****************************************************************************
> + * VLCPlaylistDataSource.m: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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 "VLCPlaylistDataSource.h"
> +#import "VLCPlaylistTableCellView.h"
> +#import "VLCPlaylistController.h"
> +#import "VLCPlaylistModel.h"
> +#import "VLCPlaylistItem.h"
> +#import "NSString+Helpers.h"
> +
> +static NSString *VLCPlaylistCellIdentifier = 
> @"VLCPlaylistCellIdentifier";
> +
> + at interface VLCPlaylistDataSource ()
> +{
> +    VLCPlaylistModel *_playlistModel;
> +}
> + at end
> +
> + at implementation VLCPlaylistDataSource
> +
> +- (void)setPlaylistController:(VLCPlaylistController 
> *)playlistController
> +{
> +    _playlistController = playlistController;
> +    _playlistModel = _playlistController.playlistModel;
> +}
> +
> +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
> +{
> +    return _playlistModel.numberOfPlaylistItems;
> +}
> +
> +- (NSView *)tableView:(NSTableView *)tableView 
> viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
> +{
> +    VLCPlaylistTableCellView *cellView = [tableView 
> makeViewWithIdentifier:VLCPlaylistCellIdentifier owner:self];
> +
> +    if (cellView == nil) {
> +        /* the following code saves us an instance of NSViewController 
> which we don't need */
> +        NSNib *nib = [[NSNib alloc] 
> initWithNibNamed:@"VLCPlaylistTableCellView" bundle:nil];
> +        NSArray *topLevelObjects;
> +        if (![nib instantiateWithOwner:self 
> topLevelObjects:&topLevelObjects]) {
> +            NSLog(@"Failed to load nib %@", nib);
> +            return nil;
> +        }
> +
> +        for (id topLevelObject in topLevelObjects) {
> +            if ([topLevelObject 
> isKindOfClass:[VLCPlaylistTableCellView class]]) {
> +                cellView = topLevelObject;
> +                break;
> +            }
> +        }
> +        cellView.identifier = VLCPlaylistCellIdentifier;
> +    }
> +
> +    VLCPlaylistItem *item = [_playlistModel playlistItemAtIndex:row];
> +    if (!item) {
> +        NSLog(@"%s: model did not return an item!", __func__);
> +        return cellView;
> +    }
> +
> +    cellView.mediaTitleTextField.stringValue = item.title;
> +    cellView.durationTextField.stringValue = [NSString 
> stringWithTime:item.duration];
> +    cellView.mediaImageView.image = [NSImage imageNamed: @"noart.png"];
> +    // TODO: show more data if available
> +
> +    return cellView;
> +}
> +
> +- (void)tableViewSelectionDidChange:(NSNotification *)notification
> +{
> +    NSLog(@"playlist selection changed: %li", (long)[(NSTableView 
> *)notification.object selectedRow]);
> +}
> +
> +- (void)playlistUpdated
> +{
> +    [_tableView reloadData];
> +}
> +
> + at end
> diff --git a/modules/gui/macosx/VLCPlaylistItem.h 
> b/modules/gui/macosx/VLCPlaylistItem.h
> new file mode 100644
> index 0000000000..210a6682f9
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistItem.h
> @@ -0,0 +1,42 @@
> +/*****************************************************************************
> + * VLCPlaylistItem.h: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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 <Foundation/Foundation.h>
> +#import <vlc_playlist.h>
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at interface VLCPlaylistItem : NSObject
> +
> + at property (readwrite, assign) input_item_t *inputItem;
> + at property (readwrite, retain) NSString *title;
> + at property (readwrite, assign) vlc_tick_t duration;
> +
> + at property (readwrite, retain) NSString *artistName;
> + at property (readwrite, retain) NSString *albumName;
> + at property (readwrite, retain) NSString *artworkURLString;
> +
> +- (instancetype)initWithPlaylistItem:(vlc_playlist_item_t *)p_item;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistItem.m 
> b/modules/gui/macosx/VLCPlaylistItem.m
> new file mode 100644
> index 0000000000..8fa6c0633b
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistItem.m
> @@ -0,0 +1,53 @@
> +/*****************************************************************************
> + * VLCPlaylistItem.m: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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 "VLCPlaylistItem.h"
> +#import "NSString+Helpers.h"
> +#import <vlc_input.h>
> +
> + at implementation VLCPlaylistItem
> +
> +- (instancetype)initWithPlaylistItem:(vlc_playlist_item_t *)p_item
> +{
> +    self = [super init];
> +    if (self) {
> +        input_item_t *p_media = vlc_playlist_item_GetMedia(p_item);
> +        vlc_mutex_lock(&p_media->lock);
> +        _title = toNSStr(p_media->psz_name);
> +        _duration = p_media->i_duration;
> +
> +        if (p_media->p_meta) {
> +            _artistName = toNSStr(vlc_meta_Get(p_media->p_meta, 
> vlc_meta_Artist));
> +            _albumName = toNSStr(vlc_meta_Get(p_media->p_meta, 
> vlc_meta_Album));
> +            _artworkURLString = toNSStr(vlc_meta_Get(p_media->p_meta, 
> vlc_meta_ArtworkURL));
> +        }
> +        vlc_mutex_unlock(&p_media->lock);
> +    }
> +    return self;
> +}
> +
> +- (NSString *)description
> +{
> +    return [NSString stringWithFormat:@"item %p, title: %@", 
> &_inputItem, _title];
> +}
> +
> + at end
> diff --git a/modules/gui/macosx/VLCPlaylistModel.h 
> b/modules/gui/macosx/VLCPlaylistModel.h
> new file mode 100644
> index 0000000000..d5697739e0
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistModel.h
> @@ -0,0 +1,42 @@
> +/*****************************************************************************
> + * VLCPlaylistModel.h: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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 <Foundation/Foundation.h>
> +#import <vlc_playlist.h>
> +
> + at class VLCPlaylistController;
> + at class VLCPlaylistItem;
> +
> +NS_ASSUME_NONNULL_BEGIN
> +
> + at interface VLCPlaylistModel : NSObject
> +
> + at property (readwrite, assign) VLCPlaylistController 
> *playlistController;
> + at property (readonly) size_t numberOfPlaylistItems;
> +
> +- (VLCPlaylistItem *)playlistItemAtIndex:(NSInteger)index;
> +- (void)addItem:(vlc_playlist_item_t *)item atIndex:(size_t)index;
> +- (void)removeItemAtIndex:(size_t)index;
> +
> + at end
> +
> +NS_ASSUME_NONNULL_END
> diff --git a/modules/gui/macosx/VLCPlaylistModel.m 
> b/modules/gui/macosx/VLCPlaylistModel.m
> new file mode 100644
> index 0000000000..795f691e15
> --- /dev/null
> +++ b/modules/gui/macosx/VLCPlaylistModel.m
> @@ -0,0 +1,72 @@
> +/*****************************************************************************
> + * VLCPlaylistModel.m: MacOS X interface module
> + 
> *****************************************************************************
> + * Copyright (C) 2019 VLC authors and VideoLAN
> + *
> + * Authors: Felix Paul Kühne <fkuehne # 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 "VLCPlaylistModel.h"
> +#import "VLCPlaylistController.h"
> +#import "VLCPlaylistItem.h"
> +#import <vlc_common.h>
> +
> + at interface VLCPlaylistModel ()
> +{
> +    NSMutableArray *_playlistArray;
> +}
> + at end
> +
> + at implementation VLCPlaylistModel
> +
> +- (instancetype)init
> +{
> +    self = [super init];
> +    if (self) {
> +        _playlistArray = [[NSMutableArray alloc] init];
> +    }
> +    return self;
> +}
> +
> +- (size_t)numberOfPlaylistItems
> +{
> +    size_t ret = 0;
> +
> +    vlc_playlist_t *p_playlist = self.playlistController.p_playlist;
> +
> +    ret = vlc_playlist_Count(p_playlist);

You forgot a vlc_playlist_Lock();

You really need to configure vlc with "--enable-debug", that will help you catch such things.

> +
> +    return ret;
> +}
> +
> +- (VLCPlaylistItem *)playlistItemAtIndex:(NSInteger)index
> +{
> +    return _playlistArray[index];
> +}
> +
> +- (void)addItem:(vlc_playlist_item_t *)item atIndex:(size_t)index
> +{
> +    VLCPlaylistItem *playlistItem = [[VLCPlaylistItem alloc] 
> initWithPlaylistItem:item];
> +    [_playlistArray insertObject:playlistItem atIndex:index];
> +}
> +
> +- (void)removeItemAtIndex:(size_t)index
> +{
> +    [_playlistArray removeObjectAtIndex:index];
> +}
> +
> + at end
> 
> 
> _______________________________________________
> vlc-commits mailing list
> vlc-commits at videolan.org
> https://mailman.videolan.org/listinfo/vlc-commits
>



More information about the vlc-devel mailing list