Implement dock icon progress bar indicator for many processing operations, including adding tracks, removing tracks, and loading or reloading track metadata
parent
0d90ccb7c1
commit
7fe67b1630
|
@ -16,6 +16,11 @@
|
||||||
IBOutlet PlaybackController *playbackController;
|
IBOutlet PlaybackController *playbackController;
|
||||||
|
|
||||||
NSInteger lastPlaybackStatus;
|
NSInteger lastPlaybackStatus;
|
||||||
|
NSInteger lastColorfulStatus;
|
||||||
|
NSNumber *lastProgressStatus;
|
||||||
|
|
||||||
|
NSImageView *imageView;
|
||||||
|
NSProgressIndicator *progressIndicator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -17,12 +17,14 @@ static NSString *DockIconPlaybackStatusObservationContext = @"DockIconPlaybackSt
|
||||||
- (void)startObserving
|
- (void)startObserving
|
||||||
{
|
{
|
||||||
[playbackController addObserver:self forKeyPath:@"playbackStatus" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:(__bridge void * _Nullable)(DockIconPlaybackStatusObservationContext)];
|
[playbackController addObserver:self forKeyPath:@"playbackStatus" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:(__bridge void * _Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
|
[playbackController addObserver:self forKeyPath:@"progressBarStatus" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:(__bridge void * _Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.colorfulDockIcons" options:0 context:(__bridge void * _Nullable)(DockIconPlaybackStatusObservationContext)];
|
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.colorfulDockIcons" options:0 context:(__bridge void * _Nullable)(DockIconPlaybackStatusObservationContext)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stopObserving
|
- (void)stopObserving
|
||||||
{
|
{
|
||||||
[playbackController removeObserver:self forKeyPath:@"playbackStatus"];
|
[playbackController removeObserver:self forKeyPath:@"playbackStatus"];
|
||||||
|
[playbackController removeObserver:self forKeyPath:@"progressBarStatus"];
|
||||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.colorfulDockIcons"];
|
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.colorfulDockIcons"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,17 +40,46 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)refreshDockIcon:(NSInteger)playbackStatus
|
- (void)refreshDockIcon:(NSInteger)playbackStatus withProgress:(double)progressStatus
|
||||||
{
|
{
|
||||||
|
BOOL displayChanged = NO;
|
||||||
|
BOOL drawIcon = NO;
|
||||||
|
BOOL removeProgress = NO;
|
||||||
|
|
||||||
if ( playbackStatus < 0 )
|
if ( playbackStatus < 0 )
|
||||||
playbackStatus = lastPlaybackStatus;
|
playbackStatus = lastPlaybackStatus;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
lastPlaybackStatus = playbackStatus;
|
lastPlaybackStatus = playbackStatus;
|
||||||
|
drawIcon = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( progressStatus < -2 )
|
||||||
|
progressStatus = [lastProgressStatus doubleValue];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (progressStatus < 0 && [lastProgressStatus doubleValue] >= 0)
|
||||||
|
removeProgress = YES;
|
||||||
|
lastProgressStatus = [NSNumber numberWithDouble:progressStatus];
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL displayProgress = (progressStatus >= 0.0);
|
||||||
|
|
||||||
NSImage *badgeImage = nil;
|
NSImage *badgeImage = nil;
|
||||||
|
|
||||||
BOOL colorfulIcons = [[NSUserDefaults standardUserDefaults] boolForKey:@"colorfulDockIcons"];
|
BOOL colorfulIcons = [[NSUserDefaults standardUserDefaults] boolForKey:@"colorfulDockIcons"];
|
||||||
|
|
||||||
|
if ((colorfulIcons && lastColorfulStatus < 1) ||
|
||||||
|
(!colorfulIcons && lastColorfulStatus != 0))
|
||||||
|
{
|
||||||
|
lastColorfulStatus = colorfulIcons ? 1 : 0;
|
||||||
|
drawIcon = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDockTile *dockTile = [NSApp dockTile];
|
||||||
|
|
||||||
|
if (drawIcon)
|
||||||
|
{
|
||||||
switch (playbackStatus) {
|
switch (playbackStatus) {
|
||||||
case CogStatusPlaying:
|
case CogStatusPlaying:
|
||||||
badgeImage = [NSImage imageNamed:getBadgeName(@"playDockBadge", colorfulIcons)];
|
badgeImage = [NSImage imageNamed:getBadgeName(@"playDockBadge", colorfulIcons)];
|
||||||
|
@ -72,7 +103,60 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons)
|
||||||
operation:NSCompositingOperationSourceOver fraction:1.0];
|
operation:NSCompositingOperationSourceOver fraction:1.0];
|
||||||
|
|
||||||
[newDockImage unlockFocus];
|
[newDockImage unlockFocus];
|
||||||
[NSApp setApplicationIconImage:newDockImage];
|
|
||||||
|
imageView = [[NSImageView alloc] init];
|
||||||
|
[imageView setImage:newDockImage];
|
||||||
|
[dockTile setContentView:imageView];
|
||||||
|
|
||||||
|
progressIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0.0, 0.0, dockTile.size.width, 10.0)];
|
||||||
|
[progressIndicator setStyle:NSProgressIndicatorBarStyle];
|
||||||
|
[progressIndicator setIndeterminate:NO];
|
||||||
|
[progressIndicator setBezeled:YES];
|
||||||
|
[progressIndicator setMinValue:0];
|
||||||
|
[progressIndicator setMaxValue:100];
|
||||||
|
[progressIndicator setHidden:YES];
|
||||||
|
|
||||||
|
[imageView addSubview:progressIndicator];
|
||||||
|
|
||||||
|
displayChanged = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayProgress)
|
||||||
|
{
|
||||||
|
if (!imageView)
|
||||||
|
{
|
||||||
|
imageView = [[NSImageView alloc] init];
|
||||||
|
[imageView setImage:[NSApp applicationIconImage]];
|
||||||
|
[dockTile setContentView:imageView];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!progressIndicator)
|
||||||
|
{
|
||||||
|
progressIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(0.0, 0.0, dockTile.size.width, 10.0)];
|
||||||
|
[progressIndicator setIndeterminate:NO];
|
||||||
|
[progressIndicator setBezeled:YES];
|
||||||
|
[progressIndicator setMinValue:0];
|
||||||
|
[progressIndicator setMaxValue:100];
|
||||||
|
|
||||||
|
[imageView addSubview:progressIndicator];
|
||||||
|
}
|
||||||
|
|
||||||
|
[progressIndicator setDoubleValue:progressStatus];
|
||||||
|
[progressIndicator setHidden:NO];
|
||||||
|
|
||||||
|
displayChanged = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeProgress)
|
||||||
|
{
|
||||||
|
if (progressIndicator)
|
||||||
|
[progressIndicator setHidden:YES];
|
||||||
|
|
||||||
|
displayChanged = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayChanged)
|
||||||
|
[dockTile display];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||||
|
@ -83,11 +167,17 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons)
|
||||||
{
|
{
|
||||||
NSInteger playbackStatus = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
|
NSInteger playbackStatus = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
|
||||||
|
|
||||||
[self refreshDockIcon:playbackStatus];
|
[self refreshDockIcon:playbackStatus withProgress:-10];
|
||||||
|
}
|
||||||
|
else if ([keyPath isEqualToString:@"progressBarStatus"])
|
||||||
|
{
|
||||||
|
double progressStatus = [[change objectForKey:NSKeyValueChangeNewKey] doubleValue];
|
||||||
|
|
||||||
|
[self refreshDockIcon:-1 withProgress:progressStatus];
|
||||||
}
|
}
|
||||||
else if ([keyPath isEqualToString:@"values.colorfulDockIcons"])
|
else if ([keyPath isEqualToString:@"values.colorfulDockIcons"])
|
||||||
{
|
{
|
||||||
[self refreshDockIcon:-1];
|
[self refreshDockIcon:-1 withProgress:-10];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -99,6 +189,10 @@ static NSString *getBadgeName(NSString *baseName, BOOL colorfulIcons)
|
||||||
- (void)awakeFromNib
|
- (void)awakeFromNib
|
||||||
{
|
{
|
||||||
dockImage = [[NSImage imageNamed:@"icon_blank"] copy];
|
dockImage = [[NSImage imageNamed:@"icon_blank"] copy];
|
||||||
|
lastColorfulStatus = -1;
|
||||||
|
lastProgressStatus = [NSNumber numberWithDouble:-1];
|
||||||
|
imageView = nil;
|
||||||
|
progressIndicator = nil;
|
||||||
[self startObserving];
|
[self startObserving];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,15 @@ extern NSDictionary * makeRGInfo(PlaylistEntry *pe);
|
||||||
double position;
|
double position;
|
||||||
BOOL seekable;
|
BOOL seekable;
|
||||||
BOOL fading;
|
BOOL fading;
|
||||||
|
|
||||||
|
// progress bar display
|
||||||
|
double progressBarStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property CogStatus playbackStatus;
|
@property CogStatus playbackStatus;
|
||||||
|
|
||||||
|
@property double progressBarStatus;
|
||||||
|
|
||||||
- (IBAction)changeVolume:(id)sender;
|
- (IBAction)changeVolume:(id)sender;
|
||||||
- (IBAction)volumeDown:(id)sender;
|
- (IBAction)volumeDown:(id)sender;
|
||||||
- (IBAction)volumeUp:(id)sender;
|
- (IBAction)volumeUp:(id)sender;
|
||||||
|
|
|
@ -27,6 +27,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
|
||||||
|
|
||||||
@synthesize playbackStatus;
|
@synthesize playbackStatus;
|
||||||
|
|
||||||
|
@synthesize progressBarStatus;
|
||||||
|
|
||||||
+ (NSSet *)keyPathsForValuesAffectingSeekable
|
+ (NSSet *)keyPathsForValuesAffectingSeekable
|
||||||
{
|
{
|
||||||
return [NSSet setWithObjects:@"playlistController.currentEntry",@"playlistController.currentEntry.seekable",nil];
|
return [NSSet setWithObjects:@"playlistController.currentEntry",@"playlistController.currentEntry.seekable",nil];
|
||||||
|
@ -42,6 +44,8 @@ NSString *CogPlaybackDidStopNotficiation = @"CogPlaybackDidStopNotficiation";
|
||||||
seekable = NO;
|
seekable = NO;
|
||||||
fading = NO;
|
fading = NO;
|
||||||
|
|
||||||
|
progressBarStatus = -1;
|
||||||
|
|
||||||
audioPlayer = [[AudioPlayer alloc] init];
|
audioPlayer = [[AudioPlayer alloc] init];
|
||||||
[audioPlayer setDelegate:self];
|
[audioPlayer setDelegate:self];
|
||||||
[self setPlaybackStatus: CogStatusStopped];
|
[self setPlaybackStatus: CogStatusStopped];
|
||||||
|
|
|
@ -1770,6 +1770,7 @@ Gw
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="playlistController" destination="218" id="1320"/>
|
<outlet property="playlistController" destination="218" id="1320"/>
|
||||||
<outlet property="playlistView" destination="206" id="6MS-vO-DQp"/>
|
<outlet property="playlistView" destination="206" id="6MS-vO-DQp"/>
|
||||||
|
<outlet property="playbackController" destination="705" id="EBV-A8-3bM"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
<menu title="Menu" id="1324" userLabel="TableMenu">
|
<menu title="Menu" id="1324" userLabel="TableMenu">
|
||||||
|
|
|
@ -117,6 +117,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_block_t block) {
|
||||||
|
if (dispatch_queue_get_label(queue) == dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)) {
|
||||||
|
block();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dispatch_sync(queue, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setProgressBarStatus:(double)status {
|
||||||
|
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||||
|
[self->playbackController setProgressBarStatus:status];
|
||||||
|
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.001]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
- (void)updatePlaylistIndexes {
|
- (void)updatePlaylistIndexes {
|
||||||
NSArray *arranged = [self arrangedObjects];
|
NSArray *arranged = [self arrangedObjects];
|
||||||
NSUInteger n = [arranged count];
|
NSUInteger n = [arranged count];
|
||||||
|
@ -129,7 +145,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updated) {
|
if (updated) {
|
||||||
[[SQLiteStore sharedStore] syncPlaylistEntries:arranged];
|
[[SQLiteStore sharedStore] syncPlaylistEntries:arranged progressCall:^(double progress) {
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +414,9 @@
|
||||||
[NSString stringWithFormat:@"Adding %lu entries", (unsigned long) [objects count]];
|
[NSString stringWithFormat:@"Adding %lu entries", (unsigned long) [objects count]];
|
||||||
[[self undoManager] setActionName:actionName];
|
[[self undoManager] setActionName:actionName];
|
||||||
|
|
||||||
[[SQLiteStore sharedStore] playlistInsertTracks:objects atObjectIndexes:indexes];
|
[[SQLiteStore sharedStore] playlistInsertTracks:objects atObjectIndexes:indexes progressCall:^(double progress) {
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
}];
|
||||||
|
|
||||||
[super insertObjects:objects atArrangedObjectIndexes:indexes];
|
[super insertObjects:objects atArrangedObjectIndexes:indexes];
|
||||||
|
|
||||||
|
@ -443,7 +463,9 @@
|
||||||
currentEntry.index = -i - 1;
|
currentEntry.index = -i - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[SQLiteStore sharedStore] playlistRemoveTracksAtIndexes:unarrangedIndexes];
|
[[SQLiteStore sharedStore] playlistRemoveTracksAtIndexes:unarrangedIndexes progressCall:^(double progress) {
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
}];
|
||||||
|
|
||||||
[super removeObjectsAtArrangedObjectIndexes:indexes];
|
[super removeObjectsAtArrangedObjectIndexes:indexes];
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ typedef enum {
|
||||||
@interface PlaylistLoader : NSObject {
|
@interface PlaylistLoader : NSObject {
|
||||||
IBOutlet PlaylistController *playlistController;
|
IBOutlet PlaylistController *playlistController;
|
||||||
IBOutlet NSScrollView *playlistView;
|
IBOutlet NSScrollView *playlistView;
|
||||||
|
IBOutlet PlaybackController *playbackController;
|
||||||
|
|
||||||
NSOperationQueue *queue;
|
NSOperationQueue *queue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
[fileHandle truncateFileAtOffset:0];
|
[fileHandle truncateFileAtOffset:0];
|
||||||
|
[fileHandle writeData:[@"#\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||||
|
|
||||||
for (PlaylistEntry *pe in [playlistController arrangedObjects])
|
for (PlaylistEntry *pe in [playlistController arrangedObjects])
|
||||||
{
|
{
|
||||||
|
@ -281,6 +282,21 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_block_t block) {
|
||||||
|
if (dispatch_queue_get_label(queue) == dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)) {
|
||||||
|
block();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dispatch_sync(queue, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setProgressBarStatus:(double)status {
|
||||||
|
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||||
|
[self->playbackController setProgressBarStatus:status];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
- (NSArray*)insertURLs:(NSArray *)urls atIndex:(NSInteger)index sort:(BOOL)sort
|
- (NSArray*)insertURLs:(NSArray *)urls atIndex:(NSInteger)index sort:(BOOL)sort
|
||||||
{
|
{
|
||||||
NSMutableSet *uniqueURLs = [NSMutableSet set];
|
NSMutableSet *uniqueURLs = [NSMutableSet set];
|
||||||
|
@ -291,12 +307,21 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
NSMutableArray *validURLs = [NSMutableArray array];
|
NSMutableArray *validURLs = [NSMutableArray array];
|
||||||
NSDictionary *xmlData = nil;
|
NSDictionary *xmlData = nil;
|
||||||
|
|
||||||
|
double progress = 0.0;
|
||||||
|
|
||||||
if (!urls)
|
if (!urls)
|
||||||
|
{
|
||||||
|
[self setProgressBarStatus:-1];
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
|
}
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
|
double progressstep = [urls count] ? 20.0 / (double)([urls count]) : 0;
|
||||||
|
|
||||||
NSURL *url;
|
NSURL *url;
|
||||||
for (url in urls)
|
for (url in urls)
|
||||||
{
|
{
|
||||||
|
@ -320,8 +345,16 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
//Non-file URL..
|
//Non-file URL..
|
||||||
[expandedURLs addObject:url];
|
[expandedURLs addObject:url];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress += progressstep;
|
||||||
|
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress = 20.0;
|
||||||
|
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
DLog(@"Expanded urls: %@", expandedURLs);
|
DLog(@"Expanded urls: %@", expandedURLs);
|
||||||
|
|
||||||
NSArray *sortedURLs;
|
NSArray *sortedURLs;
|
||||||
|
@ -335,6 +368,8 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
sortedURLs = expandedURLs;
|
sortedURLs = expandedURLs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progressstep = [sortedURLs count] ? 20.0 / (double)([sortedURLs count]) : 0;
|
||||||
|
|
||||||
for (url in sortedURLs)
|
for (url in sortedURLs)
|
||||||
{
|
{
|
||||||
//Container vs non-container url
|
//Container vs non-container url
|
||||||
|
@ -360,14 +395,24 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
{
|
{
|
||||||
[fileURLs addObject:url];
|
[fileURLs addObject:url];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress += progressstep;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress = 40.0;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
DLog(@"File urls: %@", fileURLs);
|
DLog(@"File urls: %@", fileURLs);
|
||||||
|
|
||||||
DLog(@"Contained urls: %@", containedURLs);
|
DLog(@"Contained urls: %@", containedURLs);
|
||||||
|
|
||||||
|
progressstep = [fileURLs count] ? 20.0 / (double)([fileURLs count]) : 0;
|
||||||
|
|
||||||
for (url in fileURLs)
|
for (url in fileURLs)
|
||||||
{
|
{
|
||||||
|
progress += progressstep;
|
||||||
|
|
||||||
if (![[AudioPlayer schemes] containsObject:[url scheme]])
|
if (![[AudioPlayer schemes] containsObject:[url scheme]])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -383,12 +428,22 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
|
|
||||||
[uniqueURLs addObject:url];
|
[uniqueURLs addObject:url];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress = 60.0;
|
||||||
|
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
DLog(@"Valid urls: %@", validURLs);
|
DLog(@"Valid urls: %@", validURLs);
|
||||||
|
|
||||||
|
progressstep = [containedURLs count] ? 20.0 / (double)([containedURLs count]) : 0;
|
||||||
|
|
||||||
for (url in containedURLs)
|
for (url in containedURLs)
|
||||||
{
|
{
|
||||||
|
progress += progressstep;
|
||||||
|
|
||||||
if (![[AudioPlayer schemes] containsObject:[url scheme]])
|
if (![[AudioPlayer schemes] containsObject:[url scheme]])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -397,15 +452,26 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
[validURLs addObject:url];
|
[validURLs addObject:url];
|
||||||
|
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress = 80.0;
|
||||||
|
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
//Create actual entries
|
//Create actual entries
|
||||||
int count = (int) [validURLs count];
|
int count = (int) [validURLs count];
|
||||||
if (xmlData) count += [[xmlData objectForKey:@"entries"] count];
|
if (xmlData) count += [[xmlData objectForKey:@"entries"] count];
|
||||||
|
|
||||||
// no valid URLs, or they use an unsupported URL scheme
|
// no valid URLs, or they use an unsupported URL scheme
|
||||||
if (!count)
|
if (!count)
|
||||||
|
{
|
||||||
|
[self setProgressBarStatus:-1];
|
||||||
return [NSArray array];
|
return [NSArray array];
|
||||||
|
}
|
||||||
|
|
||||||
|
progressstep = 20.0 / (double)(count);
|
||||||
|
|
||||||
NSInteger i = 0;
|
NSInteger i = 0;
|
||||||
NSMutableArray *entries = [NSMutableArray arrayWithCapacity:count];
|
NSMutableArray *entries = [NSMutableArray arrayWithCapacity:count];
|
||||||
|
@ -421,6 +487,9 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
[entries addObject:pe];
|
[entries addObject:pe];
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
|
progress += progressstep;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSInteger j = index + i;
|
NSInteger j = index + i;
|
||||||
|
@ -441,6 +510,9 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progress = 100.0;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
NSIndexSet *is = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, [entries count])];
|
NSIndexSet *is = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(index, [entries count])];
|
||||||
|
|
||||||
[playlistController insertObjects:entries atArrangedObjectIndexes:is];
|
[playlistController insertObjects:entries atArrangedObjectIndexes:is];
|
||||||
|
@ -471,22 +543,23 @@ NSMutableDictionary * dictionaryWithPropertiesOfObject(id obj, NSArray * filterL
|
||||||
NSMutableArray* arrayRest = [entries mutableCopy];
|
NSMutableArray* arrayRest = [entries mutableCopy];
|
||||||
[arrayRest removeObjectAtIndex:0];
|
[arrayRest removeObjectAtIndex:0];
|
||||||
|
|
||||||
|
progress = 0.0;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
[self performSelectorOnMainThread:@selector(syncLoadInfoForEntries:) withObject:arrayFirst waitUntilDone:YES];
|
[self performSelectorOnMainThread:@selector(syncLoadInfoForEntries:) withObject:arrayFirst waitUntilDone:YES];
|
||||||
|
|
||||||
|
progressstep = 100.0 / (double)([entries count]);
|
||||||
|
progress += progressstep;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
if ([arrayRest count])
|
if ([arrayRest count])
|
||||||
[self performSelectorInBackground:@selector(loadInfoForEntries:) withObject:arrayRest];
|
[self performSelectorInBackground:@selector(loadInfoForEntries:) withObject:arrayRest];
|
||||||
|
else
|
||||||
|
[self setProgressBarStatus:-1];
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_block_t block) {
|
|
||||||
if (dispatch_queue_get_label(queue) == dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)) {
|
|
||||||
block();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dispatch_sync(queue, block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)loadInfoForEntries:(NSArray *)entries
|
- (void)loadInfoForEntries:(NSArray *)entries
|
||||||
{
|
{
|
||||||
NSMutableIndexSet *update_indexes = [[NSMutableIndexSet alloc] init];
|
NSMutableIndexSet *update_indexes = [[NSMutableIndexSet alloc] init];
|
||||||
|
@ -495,6 +568,18 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
|
|
||||||
SQLiteStore *store = [SQLiteStore sharedStore];
|
SQLiteStore *store = [SQLiteStore sharedStore];
|
||||||
|
|
||||||
|
__block double progress = [playbackController progressBarStatus];
|
||||||
|
|
||||||
|
if (progress < 0 || progress >= 100)
|
||||||
|
progress = 0;
|
||||||
|
|
||||||
|
double progressRemaining = 100.0 - progress;
|
||||||
|
|
||||||
|
// 50% for properties reading, 50% for applying them to the main thread
|
||||||
|
const double progressstep = [entries count] ? (progressRemaining / 2.0) / [entries count] : 0;
|
||||||
|
|
||||||
|
progressRemaining = progress + (progressRemaining / 2.0);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
j = 0;
|
j = 0;
|
||||||
for (PlaylistEntry *pe in entries)
|
for (PlaylistEntry *pe in entries)
|
||||||
|
@ -529,6 +614,10 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
NSBlockOperation *op = [[NSBlockOperation alloc] init];
|
NSBlockOperation *op = [[NSBlockOperation alloc] init];
|
||||||
|
|
||||||
[op addExecutionBlock:^{
|
[op addExecutionBlock:^{
|
||||||
|
[weakLock lock];
|
||||||
|
progress += progressstep;
|
||||||
|
[weakLock unlock];
|
||||||
|
|
||||||
NSMutableDictionary *entryInfo = [NSMutableDictionary dictionaryWithCapacity:20];
|
NSMutableDictionary *entryInfo = [NSMutableDictionary dictionaryWithCapacity:20];
|
||||||
|
|
||||||
NSDictionary *entryProperties = [AudioPropertiesReader propertiesForURL:weakPe.URL];
|
NSDictionary *entryProperties = [AudioPropertiesReader propertiesForURL:weakPe.URL];
|
||||||
|
@ -541,6 +630,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
[weakLock lock];
|
[weakLock lock];
|
||||||
[weakArray addObject:weakPe];
|
[weakArray addObject:weakPe];
|
||||||
[weakArray addObject:entryInfo];
|
[weakArray addObject:entryInfo];
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
[weakLock unlock];
|
[weakLock unlock];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -550,12 +640,17 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
|
|
||||||
[queue waitUntilAllOperationsAreFinished];
|
[queue waitUntilAllOperationsAreFinished];
|
||||||
|
|
||||||
|
progress = progressRemaining;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
|
|
||||||
for (i = 0, j = [outArray count]; i < j; i += 2) {
|
for (i = 0, j = [outArray count]; i < j; i += 2) {
|
||||||
__block PlaylistEntry *weakPe = [outArray objectAtIndex:i];
|
__block PlaylistEntry *weakPe = [outArray objectAtIndex:i];
|
||||||
__block NSDictionary *entryInfo = [outArray objectAtIndex:i + 1];
|
__block NSDictionary *entryInfo = [outArray objectAtIndex:i + 1];
|
||||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||||
[weakPe setMetadata:entryInfo];
|
[weakPe setMetadata:entryInfo];
|
||||||
[store trackUpdate:weakPe];
|
[store trackUpdate:weakPe];
|
||||||
|
progress += progressstep;
|
||||||
|
[self setProgressBarStatus:progress];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,6 +664,8 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
[weakPlaylistView.documentView reloadDataForRowIndexes:weakIndexSet columnIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,columns)]];
|
[weakPlaylistView.documentView reloadDataForRowIndexes:weakIndexSet columnIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,columns)]];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self setProgressBarStatus:-1];
|
||||||
}
|
}
|
||||||
// To be called on main thread only
|
// To be called on main thread only
|
||||||
- (void)syncLoadInfoForEntries:(NSArray *)entries
|
- (void)syncLoadInfoForEntries:(NSArray *)entries
|
||||||
|
|
|
@ -27,17 +27,17 @@
|
||||||
|
|
||||||
- (void) trackUpdate:(PlaylistEntry *)track;
|
- (void) trackUpdate:(PlaylistEntry *)track;
|
||||||
|
|
||||||
- (void)playlistInsertTracks:(NSArray *)tracks atIndex:(int64_t)index;
|
- (void)playlistInsertTracks:(NSArray *)tracks atIndex:(int64_t)index progressCall:(void(^)(double progress))callback;
|
||||||
- (void)playlistInsertTracks:(NSArray *)tracks atObjectIndexes:(NSIndexSet *)indexes;
|
- (void)playlistInsertTracks:(NSArray *)tracks atObjectIndexes:(NSIndexSet *)indexes progressCall:(void(^)(double progress))callback;
|
||||||
- (void)playlistRemoveTracks:(int64_t)index forCount:(int64_t)count;
|
- (void)playlistRemoveTracks:(int64_t)index forCount:(int64_t)count progressCall:(void(^)(double progress))callback;
|
||||||
- (void)playlistRemoveTracksAtIndexes:(NSIndexSet *)indexes;
|
- (void)playlistRemoveTracksAtIndexes:(NSIndexSet *)indexes progressCall:(void(^)(double progress))callback;
|
||||||
- (PlaylistEntry *)playlistGetItem:(int64_t)index;
|
- (PlaylistEntry *)playlistGetItem:(int64_t)index;
|
||||||
- (int64_t)playlistGetCount;
|
- (int64_t)playlistGetCount;
|
||||||
#if 0
|
#if 0
|
||||||
- (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex;
|
- (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
- (void)syncPlaylistEntries:(NSArray *)entries;
|
- (void)syncPlaylistEntries:(NSArray *)entries progressCall:(void(^)(double progress))callback;
|
||||||
|
|
||||||
- (void)queueAddItem:(int64_t)playlistIndex;
|
- (void)queueAddItem:(int64_t)playlistIndex;
|
||||||
- (void)queueAddItems:(NSArray *)playlistIndexes;
|
- (void)queueAddItems:(NSArray *)playlistIndexes;
|
||||||
|
|
|
@ -1466,9 +1466,15 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)playlistInsertTracks:(NSArray *)tracks atIndex:(int64_t)index
|
- (void)playlistInsertTracks:(NSArray *)tracks atIndex:(int64_t)index progressCall:(void (^)(double))callback
|
||||||
{
|
{
|
||||||
if (!tracks) return;
|
if (!tracks)
|
||||||
|
{
|
||||||
|
callback(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(0);
|
||||||
|
|
||||||
sqlite3_stmt *st = stmt[stmt_increment_playlist_for_insert];
|
sqlite3_stmt *st = stmt[stmt_increment_playlist_for_insert];
|
||||||
|
|
||||||
|
@ -1478,9 +1484,15 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
sqlite3_step(st) != SQLITE_DONE ||
|
sqlite3_step(st) != SQLITE_DONE ||
|
||||||
sqlite3_reset(st))
|
sqlite3_reset(st))
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(25);
|
||||||
|
|
||||||
|
double progress = 25.0;
|
||||||
|
double progressstep = [tracks count] ? 75.0 / (double)([tracks count]) : 0;
|
||||||
|
|
||||||
st = stmt[stmt_add_playlist];
|
st = stmt[stmt_add_playlist];
|
||||||
|
|
||||||
for (PlaylistEntry *entry in tracks)
|
for (PlaylistEntry *entry in tracks)
|
||||||
|
@ -1492,32 +1504,61 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
sqlite3_bind_int64(st, add_playlist_in_track_id, trackId) ||
|
sqlite3_bind_int64(st, add_playlist_in_track_id, trackId) ||
|
||||||
sqlite3_step(st) != SQLITE_DONE)
|
sqlite3_step(st) != SQLITE_DONE)
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
++index;
|
++index;
|
||||||
|
|
||||||
|
progress += progressstep;
|
||||||
|
callback(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_reset(st);
|
sqlite3_reset(st);
|
||||||
|
|
||||||
|
callback(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)playlistInsertTracks:(NSArray *)tracks atObjectIndexes:(NSIndexSet *)indexes
|
- (void)playlistInsertTracks:(NSArray *)tracks atObjectIndexes:(NSIndexSet *)indexes progressCall:(void (^)(double))callback
|
||||||
{
|
{
|
||||||
if (!tracks || !indexes) return;
|
if (!tracks || !indexes)
|
||||||
|
{
|
||||||
|
callback(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
__block int64_t total_count = 0;
|
||||||
|
[indexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
||||||
|
total_count += range.length;
|
||||||
|
}];
|
||||||
|
|
||||||
__block int64_t i = 0;
|
__block int64_t i = 0;
|
||||||
|
|
||||||
|
__block double progress = 0;
|
||||||
|
|
||||||
[indexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
[indexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
||||||
|
double progresschunk = (double)range.length / (double)total_count;
|
||||||
|
double progressbase = progress;
|
||||||
NSRange trackRange = NSMakeRange(i, range.length);
|
NSRange trackRange = NSMakeRange(i, range.length);
|
||||||
NSArray *trackSet = (i == 0 && range.length == [tracks count]) ? tracks : [tracks subarrayWithRange:trackRange];
|
NSArray *trackSet = (i == 0 && range.length == [tracks count]) ? tracks : [tracks subarrayWithRange:trackRange];
|
||||||
[self playlistInsertTracks:trackSet atIndex:range.location];
|
[self playlistInsertTracks:trackSet atIndex:range.location progressCall:^(double _progress){
|
||||||
i += range.length;
|
if (_progress < 0) return;
|
||||||
|
callback(progressbase + progresschunk * _progress);
|
||||||
}];
|
}];
|
||||||
|
i += range.length;
|
||||||
|
progress += 100.0 * progresschunk;
|
||||||
|
callback(progress);
|
||||||
|
}];
|
||||||
|
callback(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)playlistRemoveTracks:(int64_t)index forCount:(int64_t)count
|
- (void)playlistRemoveTracks:(int64_t)index forCount:(int64_t)count progressCall:(void (^)(double))callback
|
||||||
{
|
{
|
||||||
if (!count) return;
|
if (!count)
|
||||||
|
{
|
||||||
|
callback(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3_stmt *st = stmt[stmt_select_playlist_range];
|
sqlite3_stmt *st = stmt[stmt_select_playlist_range];
|
||||||
|
|
||||||
|
@ -1525,9 +1566,15 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
sqlite3_bind_int64(st, select_playlist_range_in_id_low, index) ||
|
sqlite3_bind_int64(st, select_playlist_range_in_id_low, index) ||
|
||||||
sqlite3_bind_int64(st, select_playlist_range_in_id_high, index + count - 1))
|
sqlite3_bind_int64(st, select_playlist_range_in_id_high, index + count - 1))
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(0);
|
||||||
|
|
||||||
|
double progress = 0;
|
||||||
|
double progressstep = 100.0 / ((double)count);
|
||||||
|
|
||||||
int rc = sqlite3_step(st);
|
int rc = sqlite3_step(st);
|
||||||
|
|
||||||
while (rc == SQLITE_ROW)
|
while (rc == SQLITE_ROW)
|
||||||
|
@ -1535,8 +1582,12 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
int64_t trackId = sqlite3_column_int64(st, select_playlist_range_out_track_id);
|
int64_t trackId = sqlite3_column_int64(st, select_playlist_range_out_track_id);
|
||||||
[self removeTrack:trackId];
|
[self removeTrack:trackId];
|
||||||
rc = sqlite3_step(st);
|
rc = sqlite3_step(st);
|
||||||
|
progress += progressstep;
|
||||||
|
callback(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(100);
|
||||||
|
|
||||||
sqlite3_reset(st);
|
sqlite3_reset(st);
|
||||||
|
|
||||||
if (rc != SQLITE_DONE)
|
if (rc != SQLITE_DONE)
|
||||||
|
@ -1552,6 +1603,7 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
sqlite3_step(st) != SQLITE_DONE ||
|
sqlite3_step(st) != SQLITE_DONE ||
|
||||||
sqlite3_reset(st))
|
sqlite3_reset(st))
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1563,6 +1615,7 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
sqlite3_step(st) != SQLITE_DONE ||
|
sqlite3_step(st) != SQLITE_DONE ||
|
||||||
sqlite3_reset(st))
|
sqlite3_reset(st))
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1574,18 +1627,42 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
[self queueRemovePlaylistItems:items];
|
[self queueRemovePlaylistItems:items];
|
||||||
|
|
||||||
|
callback(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)playlistRemoveTracksAtIndexes:(NSIndexSet *)indexes
|
- (void)playlistRemoveTracksAtIndexes:(NSIndexSet *)indexes progressCall:(void (^)(double))callback
|
||||||
{
|
{
|
||||||
if (!indexes) return;
|
if (!indexes)
|
||||||
|
{
|
||||||
|
callback(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
__block int64_t total_count = 0;
|
||||||
|
|
||||||
|
[indexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
||||||
|
total_count += range.length;
|
||||||
|
}];
|
||||||
|
|
||||||
__block int64_t i = 0;
|
__block int64_t i = 0;
|
||||||
|
|
||||||
|
__block double progress = 0;
|
||||||
|
|
||||||
|
callback(progress);
|
||||||
|
|
||||||
[indexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
[indexes enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
||||||
[self playlistRemoveTracks:(range.location - i) forCount:range.length];
|
double progresschunk = (double)range.length / (double)total_count;
|
||||||
i += range.length;
|
double progressbase = progress;
|
||||||
|
[self playlistRemoveTracks:(range.location - i) forCount:range.length progressCall:^(double _progress) {
|
||||||
|
if (_progress < 0) return;
|
||||||
|
callback(progressbase + progresschunk * _progress);
|
||||||
}];
|
}];
|
||||||
|
i += range.length;
|
||||||
|
progress += 100.0 * progresschunk;
|
||||||
|
callback(progress);
|
||||||
|
}];
|
||||||
|
callback(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (PlaylistEntry *)playlistGetItem:(int64_t)index
|
- (PlaylistEntry *)playlistGetItem:(int64_t)index
|
||||||
|
@ -1740,18 +1817,27 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
- (void)syncPlaylistEntries:(NSArray *)entries
|
- (void)syncPlaylistEntries:(NSArray *)entries progressCall:(void (^)(double))callback
|
||||||
{
|
{
|
||||||
if (!entries || ![entries count])
|
if (!entries || ![entries count])
|
||||||
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t count = [self playlistGetCount];
|
int64_t count = [self playlistGetCount];
|
||||||
|
|
||||||
if (count != [entries count])
|
if (count != [entries count])
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(0);
|
||||||
|
|
||||||
|
double progress = 0;
|
||||||
|
double progressstep = 50.0 / (double)(count);
|
||||||
|
|
||||||
NSMutableArray * entryIds = [[NSMutableArray alloc] init];
|
NSMutableArray * entryIds = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray * entryIndexes = [[NSMutableArray alloc] init];
|
NSMutableArray * entryIndexes = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray * trackIds = [[NSMutableArray alloc] init];
|
NSMutableArray * trackIds = [[NSMutableArray alloc] init];
|
||||||
|
@ -1763,6 +1849,7 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
if (sqlite3_reset(st) ||
|
if (sqlite3_reset(st) ||
|
||||||
(rc = sqlite3_step(st)) != SQLITE_ROW)
|
(rc = sqlite3_step(st)) != SQLITE_ROW)
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1777,11 +1864,17 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
[trackIds addObject:[NSNumber numberWithInteger:trackId]];
|
[trackIds addObject:[NSNumber numberWithInteger:trackId]];
|
||||||
|
|
||||||
rc = sqlite3_step(st);
|
rc = sqlite3_step(st);
|
||||||
|
|
||||||
|
progress += progressstep;
|
||||||
|
callback(progress);
|
||||||
}
|
}
|
||||||
while (rc == SQLITE_ROW);
|
while (rc == SQLITE_ROW);
|
||||||
|
|
||||||
sqlite3_reset(st);
|
sqlite3_reset(st);
|
||||||
|
|
||||||
|
progress = 50;
|
||||||
|
callback(progress);
|
||||||
|
|
||||||
st = stmt[stmt_update_playlist];
|
st = stmt[stmt_update_playlist];
|
||||||
|
|
||||||
int64_t i = 0;
|
int64_t i = 0;
|
||||||
|
@ -1793,6 +1886,7 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
int64_t trackId = [[trackIds objectAtIndex:i] integerValue];
|
int64_t trackId = [[trackIds objectAtIndex:i] integerValue];
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
|
progress += progressstep;
|
||||||
|
|
||||||
if ([entry index] == entryIndex &&
|
if ([entry index] == entryIndex &&
|
||||||
[entry dbIndex] == trackId)
|
[entry dbIndex] == trackId)
|
||||||
|
@ -1804,11 +1898,16 @@ static SQLiteStore *g_sharedStore = NULL;
|
||||||
sqlite3_bind_int64(st, update_playlist_in_id, entryId) ||
|
sqlite3_bind_int64(st, update_playlist_in_id, entryId) ||
|
||||||
sqlite3_step(st) != SQLITE_DONE)
|
sqlite3_step(st) != SQLITE_DONE)
|
||||||
{
|
{
|
||||||
|
callback(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_reset(st);
|
sqlite3_reset(st);
|
||||||
|
|
||||||
|
callback(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)queueAddItem:(int64_t)playlistIndex
|
- (void)queueAddItem:(int64_t)playlistIndex
|
||||||
|
|
Loading…
Reference in New Issue