diff --git a/modules/gui/macosx/library/VLCInputItem.h b/modules/gui/macosx/library/VLCInputItem.h index b2a1d432672f799e9a6e55abdde7114433c8fe03..8cfd2e6bc0118b8f8376bebc63beee1eea8b979f 100644 --- a/modules/gui/macosx/library/VLCInputItem.h +++ b/modules/gui/macosx/library/VLCInputItem.h @@ -84,6 +84,7 @@ extern NSString *VLCInputItemPreparsingSucceeded; - (instancetype)initWithInputNode:(struct input_item_node_t *)p_inputNode; +@property (readonly) struct input_item_node_t *vlcInputItemNode; @property (readonly, nullable) VLCInputItem *inputItem; @property (readonly) int numberOfChildren; @property (readonly) NSArray <VLCInputNode *> *children; diff --git a/modules/gui/macosx/library/VLCInputItem.m b/modules/gui/macosx/library/VLCInputItem.m index 83aa189e5749bef265638de8da79d321a36c861d..7e677d6b22a98d72e8f66888c5b6d6248aa07da1 100644 --- a/modules/gui/macosx/library/VLCInputItem.m +++ b/modules/gui/macosx/library/VLCInputItem.m @@ -573,11 +573,6 @@ static const struct input_preparser_callbacks_t preparseCallbacks = { @end -@interface VLCInputNode() -{ - struct input_item_node_t *_p_inputNode; -} -@end @implementation VLCInputNode @@ -585,7 +580,7 @@ static const struct input_preparser_callbacks_t preparseCallbacks = { { self = [super init]; if (self && p_inputNode != NULL) { - _p_inputNode = p_inputNode; + _vlcInputItemNode = p_inputNode; } return self; } @@ -593,31 +588,31 @@ static const struct input_preparser_callbacks_t preparseCallbacks = { - (NSString *)description { NSString *inputItemName; - if (_p_inputNode->p_item) - inputItemName = toNSStr(_p_inputNode->p_item->psz_name); + if (_vlcInputItemNode->p_item) + inputItemName = toNSStr(_vlcInputItemNode->p_item->psz_name); else inputItemName = @"p_item == nil"; - return [NSString stringWithFormat:@"%@: node: %p input name: %@, number of children: %i", NSStringFromClass([self class]), _p_inputNode, inputItemName, self.numberOfChildren]; + return [NSString stringWithFormat:@"%@: node: %p input name: %@, number of children: %i", NSStringFromClass([self class]),_vlcInputItemNode, inputItemName, self.numberOfChildren]; } - (VLCInputItem *)inputItem { - if (_p_inputNode->p_item) { - return [[VLCInputItem alloc] initWithInputItem:_p_inputNode->p_item]; + if (_vlcInputItemNode->p_item) { + return [[VLCInputItem alloc] initWithInputItem:_vlcInputItemNode->p_item]; } return nil; } - (int)numberOfChildren { - return _p_inputNode->i_children; + return _vlcInputItemNode->i_children; } - (NSArray<VLCInputNode *> *)children { - NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:_p_inputNode->i_children]; - for (int i = 0; i < _p_inputNode->i_children; i++) { - VLCInputNode *inputNode = [[VLCInputNode alloc] initWithInputNode:_p_inputNode->pp_children[i]]; + NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:_vlcInputItemNode->i_children]; + for (int i = 0; i < _vlcInputItemNode->i_children; i++) { + VLCInputNode *inputNode = [[VLCInputNode alloc] initWithInputNode:_vlcInputItemNode->pp_children[i]]; if (inputNode) { [mutableArray addObject:inputNode]; } diff --git a/modules/gui/macosx/media-source/VLCMediaSource.h b/modules/gui/macosx/media-source/VLCMediaSource.h index 101495ca828bf4145fb053e318fd09f7d14ca551..a80889cf2cb65c614188d23ca5d1e0403fdbc781 100644 --- a/modules/gui/macosx/media-source/VLCMediaSource.h +++ b/modules/gui/macosx/media-source/VLCMediaSource.h @@ -41,7 +41,7 @@ extern NSString *VLCMediaSourcePreparsingEnded; andLibVLCInstance:(libvlc_int_t *)p_libvlcInstance forCategory:(enum services_discovery_category_e)category; -- (void)preparseInputItemWithinTree:(VLCInputItem *)inputItem; +- (void)preparseInputNodeWithinTree:(VLCInputNode *)inputNode; @property (nonatomic, readonly) NSString *mediaSourceDescription; @property (nonatomic, readonly) VLCInputNode *rootNode; diff --git a/modules/gui/macosx/media-source/VLCMediaSource.m b/modules/gui/macosx/media-source/VLCMediaSource.m index bde8173c643c927f7c25f70e8059ac904c369c54..f747e0cd18c3915e50b654b492211e5d8dcb9cd4 100644 --- a/modules/gui/macosx/media-source/VLCMediaSource.m +++ b/modules/gui/macosx/media-source/VLCMediaSource.m @@ -178,16 +178,36 @@ static const char *const localDevicesDescription = "My Machine"; } } -- (void)preparseInputItemWithinTree:(VLCInputItem *)inputItem +- (void)preparseInputNodeWithinTree:(VLCInputNode *)inputNode { if (_p_mediaSource->description == localDevicesDescription) { [self generateLocalDevicesTree]; - return; } - if (inputItem == nil) { + + if (inputNode == nil || inputNode.inputItem == nil) { return; } - vlc_media_tree_Preparse(_p_mediaSource->tree, _p_libvlcInstance, inputItem.vlcInputItem, NULL); + + if (inputNode.inputItem.inputType == ITEM_TYPE_DIRECTORY) { + input_item_node_t *vlcInputNode = inputNode.vlcInputItemNode; + + [self clearChildNodesForNode:vlcInputNode]; + NSURL *dirUrl = [NSURL URLWithString:inputNode.inputItem.MRL]; + [self generateChildNodesForDirectoryNode:vlcInputNode withUrl:dirUrl]; + + return; + } + + vlc_media_tree_Preparse(_p_mediaSource->tree, _p_libvlcInstance, inputNode.inputItem.vlcInputItem, NULL); +} + +- (void)clearChildNodesForNode:(input_item_node_t*)inputNode +{ + while(inputNode->i_children > 0) { + input_item_node_t *childNode = inputNode->pp_children[0]; + input_item_node_RemoveNode(inputNode, childNode); + input_item_node_Delete(childNode); + } } - (void)generateLocalDevicesTree @@ -201,7 +221,7 @@ static const char *const localDevicesDescription = "My Machine"; mountedVolumeURLsIncludingResourceValuesForKeys:@[NSURLVolumeIsEjectableKey, NSURLVolumeIsRemovableKey] options:NSVolumeEnumerationSkipHiddenVolumes]; - NSURL *homeDirectoryURL = [NSURL fileURLWithPath:NSHomeDirectoryForUser(NSUserName())]; + NSURL *homeDirectoryURL = [NSURL fileURLWithPath:NSHomeDirectoryForUser(NSUserName())]; NSString *homeDirectoryDescription = [NSString stringWithFormat:@"%@'s home", NSUserName()]; if (homeDirectoryURL) { @@ -270,6 +290,50 @@ static const char *const localDevicesDescription = "My Machine"; }); } +- (void)generateChildNodesForDirectoryNode:(input_item_node_t*)directoryNode withUrl:(NSURL*)directoryUrl +{ + if(directoryNode == NULL || directoryUrl == nil) { + return; + } + + NSError *error; + NSArray<NSURL *> *subDirectories = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:directoryUrl + includingPropertiesForKeys:@[NSURLIsDirectoryKey] + options:NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsSubdirectoryDescendants + error:&error]; + if (subDirectories == nil || subDirectories.count == 0 || error) { + NSLog(@"Failed to get directories: %@.", error); + return; + } + + for (NSURL *url in subDirectories) { + NSNumber *isDirectory; + NSNumber *isVolume; + NSNumber *isEjectable; + NSNumber *isInternal; + NSNumber *isLocal; + + [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil]; + [url getResourceValue:&isVolume forKey:NSURLIsVolumeKey error:nil]; + [url getResourceValue:&isEjectable forKey:NSURLVolumeIsEjectableKey error:nil]; + [url getResourceValue:&isInternal forKey:NSURLVolumeIsInternalKey error:nil]; + [url getResourceValue:&isLocal forKey:NSURLVolumeIsLocalKey error:nil]; + + const enum input_item_type_e inputType = isDirectory.boolValue ? isEjectable.boolValue ? ITEM_TYPE_DISC : ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE; + const enum input_item_net_type netType = isLocal.boolValue ? ITEM_LOCAL : ITEM_NET; + + input_item_t *urlInputItem = input_item_NewExt(url.absoluteString.UTF8String, url.lastPathComponent.UTF8String, 0, inputType, netType); + if (urlInputItem != NULL) { + input_item_node_t *urlNode = input_item_node_Create(urlInputItem); + if (urlNode) { + input_item_node_AppendNode(directoryNode, urlNode); + } + input_item_Release(urlInputItem); + urlInputItem = NULL; + } + } +} + - (NSString *)mediaSourceDescription { if (_p_mediaSource != NULL) { diff --git a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m index c568e92b1127c9e7cecc102341cd58d6398f7982..a4d204dc15018113b9fb34e95572eea258e5dc38 100644 --- a/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m +++ b/modules/gui/macosx/media-source/VLCMediaSourceBaseDataSource.m @@ -127,7 +127,7 @@ NSString *VLCMediaSourceTableViewCellIdentifier = @"VLCMediaSourceTableViewCellI for (NSUInteger x = 0; x < count; x++) { VLCMediaSource *mediaSource = mediaSources[x]; VLCInputNode *rootNode = [mediaSource rootNode]; - [mediaSource preparseInputItemWithinTree:rootNode.inputItem]; + [mediaSource preparseInputNodeWithinTree:rootNode]; } } _mediaSources = mediaSources; diff --git a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m index 3cc116955b0ac8cb0bc299b988c984f1e71f6706..adce56351f4505fc04f593f72f2f3816ec405eba 100644 --- a/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m +++ b/modules/gui/macosx/media-source/VLCMediaSourceDataSource.m @@ -42,9 +42,7 @@ - (void)setNodeToDisplay:(VLCInputNode *)nodeToDisplay { _nodeToDisplay = nodeToDisplay; - - _childRootInput = _nodeToDisplay.inputItem; - [self.displayedMediaSource preparseInputItemWithinTree:_childRootInput]; + [self.displayedMediaSource preparseInputNodeWithinTree:_nodeToDisplay]; } - (void)setupViews @@ -171,6 +169,10 @@ - (void)performActionForNode:(VLCInputNode *)node allowPlayback:(BOOL)allowPlayback { + if(node == nil || node.inputItem == nil) { + return; + } + VLCInputItem *childRootInput = node.inputItem; if (childRootInput.inputType == ITEM_TYPE_DIRECTORY || childRootInput.inputType == ITEM_TYPE_NODE) { @@ -184,10 +186,12 @@ - (void)reloadData { - if (_gridViewMode) { - [self.collectionView reloadData]; - } else { - [self.tableView reloadData]; + if (!_collectionView.hidden) { + [_collectionView reloadData]; + } + + if(!_tableView.hidden) { + [_tableView reloadData]; } }