source: trunk/SapphireVirtualDirectory.m @ 411

Revision 411, 6.6 KB checked in by gbooker, 7 years ago (diff)
  • Background importer is getting nice and usable.
  • Removed unnecessary nslogs
  • The optimization in the VirtualDirectory? class wasn't working properly. It really makes a difference; fixed.
Line 
1/*
2 * SapphireVirtualDirectory.m
3 * Sapphire
4 *
5 * Created by Graham Booker on Nov. 18, 2007.
6 * Copyright 2007 Sapphire Development Team and/or www.nanopi.net
7 * All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License as published by the Free Software Foundation; either version 3 of the License,
11 * or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
14 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 * Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with this program; if not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 */
20
21#import "SapphireVirtualDirectory.h"
22
23//Defined in MetaData.m but this is essentially private
24NSString *searchCoverArtExtForPath(NSString *path);
25
26@interface SapphireDirectoryMetaData (privateFunctions)
27- (id)initWithDictionary:(NSDictionary *)dict parent:(SapphireMetaData *)myParent path:(NSString *)myPath;
28@end
29
30@implementation SapphireVirtualDirectory
31- (id)initWithParent:(SapphireVirtualDirectory *)myParent path:(NSString *)myPath
32{
33        self = [super initWithDictionary:nil parent:myParent path:myPath];
34        if(self == nil)
35                return nil;
36       
37        directory = [[NSMutableDictionary alloc] init];
38        reloadTimer = nil;
39        scannedDirectory = YES;
40       
41        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
42        [nc addObserver:self selector:@selector(startedLoading) name:META_DATA_FILE_INFO_STARTED_LOADING object:nil];
43        [nc addObserver:self selector:@selector(finishedLoading) name:META_DATA_FILE_INFO_FINISHED_LOADING object:nil];
44       
45        return self;
46}
47
48- (void) dealloc
49{
50        [[NSNotificationCenter defaultCenter] removeObserver:self];
51        [directory release];
52        [reloadTimer invalidate];
53        [super dealloc];
54}
55
56- (void)reloadDirectoryContents
57{
58        [files removeAllObjects];
59        [directories removeAllObjects];
60        [metaFiles removeAllObjects];
61        [metaDirs removeAllObjects];
62        [cachedMetaFiles removeAllObjects];
63        [cachedMetaDirs removeAllObjects];
64        [reloadTimer invalidate];
65        reloadTimer = nil;
66        [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(completeReloadOfDirectoryContents) userInfo:nil repeats:NO];
67}
68
69- (void)completeReloadOfDirectoryContents
70{
71        [delegate directoryContentsChanged];
72}
73
74- (void)setReloadTimer
75{
76        [reloadTimer invalidate];
77        if(!loading)
78                reloadTimer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(reloadDirectoryContents) userInfo:nil repeats:NO];
79        else
80                reloadTimer = nil;
81}
82
83- (void)processFile:(SapphireFileMetaData *)file
84{
85}
86
87- (void)removeFile:(SapphireFileMetaData *)file
88{
89}
90
91- (NSString *)classDefaultCoverPath
92{
93        return nil;
94}
95
96- (NSString *)coverArtPathUpToParents:(int)parents
97{
98        NSString *coverPath = searchCoverArtExtForPath([[[SapphireMetaData collectionArtPath] stringByAppendingPathComponent:[self path]] stringByAppendingPathComponent:@"cover"]);
99        if([[NSFileManager defaultManager] fileExistsAtPath:coverPath])
100                return coverPath;
101        if(parents != 0 && [parent isKindOfClass:[SapphireDirectoryMetaData class]])
102                return [(SapphireVirtualDirectory *)parent coverArtPathUpToParents:parents-1];
103        return nil;
104}
105
106- (NSString *)coverArtPath
107{
108        NSString *ret = [self coverArtPathUpToParents:2];
109        if(ret != nil)
110                return ret;
111        return [self classDefaultCoverPath];
112}
113
114- (void)childDisplayChanged
115{
116        /*The way the timings work out, if the timer exists already, it is more efficient to leave it set rather than set a new one*/
117        if(reloadTimer == nil)
118                [self setReloadTimer];
119}
120
121- (NSMutableDictionary *)directoryEntries
122{
123        NSMutableDictionary *ret = [NSMutableDictionary dictionary];
124        NSEnumerator *pathEnum = [directory keyEnumerator];
125        NSString *subPath = nil;
126        while((subPath = [pathEnum nextObject]) != nil)
127        {
128                SapphireMetaData *data = [directory objectForKey:subPath];
129                if([data isKindOfClass:[SapphireVirtualDirectory class]])
130                        [ret setObject:[(SapphireVirtualDirectory *)data directoryEntries] forKey:subPath];
131                else
132                        [ret setObject:[data path] forKey:subPath];
133        }
134        return ret;
135}
136
137- (void)writeToFile:(NSString *)filePath
138{
139        NSMutableDictionary *fileData = [self directoryEntries];
140        [fileData writeToFile:filePath  atomically:YES];
141}
142
143- (BOOL)isDisplayEmpty
144{
145        return [files count] == 0 && [directories count] == 0;
146}
147
148- (BOOL)isEmpty
149{
150        return [directory count] == 0;
151}
152
153- (BOOL)isLoaded
154{
155        return !loading && reloadTimer == nil;
156}
157
158- (void)startedLoading
159{
160        loading = YES;
161}
162
163- (void)finishedLoading
164{
165        if(loading == NO)
166                //Already handled
167                return;
168        loading = NO;
169        [self setReloadTimer];
170}
171
172@end
173
174@implementation SapphireVirtualDirectoryOfDirectories
175- (void)reloadDirectoryContents
176{
177        [super reloadDirectoryContents];
178        NSMutableDictionary *mutDict = [[NSMutableDictionary alloc] init];
179        NSEnumerator *keyEnum = [directory keyEnumerator];
180        NSString *key = nil;
181        while((key = [keyEnum nextObject]) != nil)
182        {
183                SapphireVirtualDirectory *dir = [directory objectForKey:key];
184                if(![dir isDisplayEmpty])
185                        [mutDict setObject:dir forKey:key];
186        }
187        [directories addObjectsFromArray:[mutDict allKeys]];
188        [directories sortUsingSelector:@selector(directoryNameCompare:)];
189        [cachedMetaDirs addEntriesFromDictionary:mutDict];
190        [metaDirs addEntriesFromDictionary:mutDict];
191        [mutDict release];
192        [(SapphireVirtualDirectory *)parent childDisplayChanged];
193        reloadTimer = nil;
194}
195
196- (void)finishedLoading
197{
198        NSEnumerator *keyEnum = [directory keyEnumerator];
199        NSString *key = nil;
200        while((key = [keyEnum nextObject]) != nil)
201        {
202                SapphireVirtualDirectory *dir = [directory objectForKey:key];
203                [dir finishedLoading];
204        }
205        [super finishedLoading];
206}
207
208- (BOOL)addFile:(SapphireFileMetaData *)file toKey:(NSString *)key withChildClass:(Class)childClass
209{
210        BOOL added = NO;
211        SapphireVirtualDirectory *child = [directory objectForKey:key];
212        if(child == nil)
213        {
214                child = [[childClass alloc] initWithParent:self path:[[self path] stringByAppendingPathComponent:key]];
215                if(loading)
216                        [child startedLoading];
217                [directory setObject:child forKey:key];
218                [child release];
219                added = YES;
220        }
221        [child processFile:file];
222        if(added == YES)
223        {
224                if([child isEmpty])
225                        [directory removeObjectForKey:key];
226                else
227                        [self setReloadTimer];
228        }
229        return added;
230}
231
232- (BOOL)removeFile:(SapphireFileMetaData *)file fromKey:(NSString *)key
233{
234        SapphireVirtualDirectory *child = [directory objectForKey:key];
235        BOOL ret = NO;
236        if(child != nil)
237        {
238                [child removeFile:file];
239                if([child isEmpty])
240                {
241                        [directory removeObjectForKey:key];
242                        [self setReloadTimer];
243                        ret = YES;
244                }
245        }
246        return ret;
247}
248@end
Note: See TracBrowser for help on using the repository browser.