2 // ElisMediaBrowserController.m
5 // Created by 柳 on 09/09/17.
6 // Copyright 2009 __MyCompanyName__. All rights reserved.
9 #import "ElisMediaBrowserController.h"
11 /* openFiles is a simple C function that open an NSOpenPanel and return an array of selected filepath */
12 static NSArray *openFiles()
16 panel = [NSOpenPanel openPanel];
17 [panel setFloatingPanel:YES];
18 [panel setCanChooseDirectories:YES];
19 [panel setCanChooseFiles:YES];
20 [panel setAllowsMultipleSelection:YES];
21 int i = [panel runModalForTypes:nil];
23 return [panel filenames];
30 @implementation myImageObject
38 /* our datasource object is just a filepath representation */
39 - (void) setPath:(NSString *) path
45 - (void)setMoviePath:(NSString*)path
52 /* required methods of the IKImageBrowserItem protocol */
54 #pragma mark item data source protocol
56 /* let the image browser knows we use a path representation */
57 - (NSString *) imageRepresentationType
60 return IKImageBrowserQTMoviePathRepresentationType;
62 return IKImageBrowserQuickLookPathRepresentationType;
63 // return IKImageBrowserPathRepresentationType;
66 /* give our representation to the image browser */
67 - (id) imageRepresentation
72 /* use the absolute filepath as identifier */
73 - (NSString *) imageUID
78 - (NSString *)imageTitle
80 return [_path lastPathComponent];
88 @implementation ElisMediaBrowserController
93 [_importedImages release];
99 /* create two arrays : the first one is our datasource representation, the second one are temporary imported images (for thread safeness )
101 _images = [[NSMutableArray alloc] init];
102 _importedImages = [[NSMutableArray alloc] init];
103 _tempArray = [[NSMutableArray alloc] init];
105 //allow reordering, animations et set draggind destination delegate
106 [_mediaBrowser setAllowsReordering:YES];
107 [_mediaBrowser setAnimates:YES];
108 [_mediaBrowser setDraggingDestinationDelegate:self];
109 // [_imageBrowser setBackgroundColor:[NSColor clearColor]];
112 /* entry point for reloading image-browser's data and setNeedsDisplay */
113 - (void) updateDatasource
115 //-- update our datasource, add recently imported items
116 [_images addObjectsFromArray:_importedImages];
118 //-- empty our temporary array
119 [_importedImages removeAllObjects];
121 //-- reload the image browser and set needs display
122 [_mediaBrowser reloadData];
126 #pragma mark import images from file system
128 /* code that parse a repository and add all items in an independant array,
129 When done, call updateDatasource, add these items to our datasource array
130 This code is performed in an independant thread.
133 - (void) addAnImageWithPath:(NSString *) path
136 NSWorkspace* sharedWorkspace = [NSWorkspace sharedWorkspace];
139 if([sharedWorkspace type:[sharedWorkspace typeOfFile:path error:nil]
140 conformsToType:@"public.image"] ||
141 [sharedWorkspace type:[sharedWorkspace typeOfFile:path error:nil]
142 conformsToType:@"public.audio"]) {
144 /* add a path to our temporary array */
145 p = [[myImageObject alloc] init];
147 [_importedImages addObject:p];
149 else if([sharedWorkspace type:[sharedWorkspace typeOfFile:path error:nil]
150 conformsToType:@"public.movie"] ||
151 [sharedWorkspace type:[sharedWorkspace typeOfFile:path error:nil]
152 conformsToType:@"com.apple.quartz-composer-composition"])
154 p = [[myImageObject alloc] init];
155 [p setMoviePath:path];
156 [_importedImages addObject:p];
160 - (void) addImagesWithPath:(NSString *) path recursive:(BOOL) recursive
165 [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&dir];
168 NSArray *content = [[NSFileManager defaultManager] directoryContentsAtPath:path];
172 /* parse the directory content*/
176 [self addImagesWithPath:[path stringByAppendingPathComponent:[content objectAtIndex:i]] recursive:YES];
178 [self addAnImageWithPath:[path stringByAppendingPathComponent:[content objectAtIndex:i]]];
182 [self addAnImageWithPath:path];
185 /* performed in an independant thread, parse all paths in "paths" and add these paths in our temporary array */
186 - (void) addImagesWithPaths:(NSArray *) paths
190 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
194 NSString *path = [paths objectAtIndex:i];
195 [self addImagesWithPath:path recursive:NO];
198 /* update the datasource in the main thread */
199 [self performSelectorOnMainThread:@selector(updateDatasource) withObject:nil waitUntilDone:YES];
201 _tempArray = [_images copy];
209 /* "add" button was clicked */
210 - (IBAction) addImageMenuClicked:(id) sender
212 NSArray *path = openFiles();
215 NSLog(@"No path selected, return...");
219 /* launch import in an independent thread */
220 [NSThread detachNewThreadSelector:@selector(addImagesWithPaths:) toTarget:self withObject:path];
223 /* action called when the zoom slider did change */
224 - (IBAction) zoomSliderDidChange:(id)sender
226 /* update the zoom value to scale images */
227 [_mediaBrowser setZoomValue:[sender floatValue]];
230 [_mediaBrowser setNeedsDisplay:YES];
234 #pragma mark IKImageBrowserDataSource
236 /* implement image-browser's datasource protocol
237 Our datasource representation is a simple mutable array
240 - (int) numberOfItemsInImageBrowser:(IKImageBrowserView *) view
242 /* item count to display is our datasource item count */
243 return [_images count];
246 - (id) imageBrowser:(IKImageBrowserView *) view itemAtIndex:(int) index
248 return [_images objectAtIndex:index];
251 /* implement some optional methods of the image-browser's datasource protocol to be able to remove and reoder items */
254 The user wants to delete images, so remove these entries from our datasource.
256 - (void) imageBrowser:(IKImageBrowserView *) view removeItemsAtIndexes: (NSIndexSet *) indexes
258 [_images removeObjectsAtIndexes:indexes];
262 The user wants to reorder images, update our datasource and the browser will reflect our changes
264 - (BOOL) imageBrowser:(IKImageBrowserView *) view moveItemsAtIndexes: (NSIndexSet *)indexes toIndex:(unsigned int)destinationIndex
267 NSMutableArray *temporaryArray;
269 temporaryArray = [[[NSMutableArray alloc] init] autorelease];
271 /* first remove items from the datasource and keep them in a temporary array */
272 for(index=[indexes lastIndex]; index != NSNotFound; index = [indexes indexLessThanIndex:index]){
273 if (index < destinationIndex)
276 id obj = [_images objectAtIndex:index];
277 [temporaryArray addObject:obj];
278 [_images removeObjectAtIndex:index];
281 /* then insert removed items at the good location */
282 int n = [temporaryArray count];
283 for(index=0; index < n; index++){
284 [_images insertObject:[temporaryArray objectAtIndex:index] atIndex:destinationIndex];
291 #pragma mark drag n drop
293 /* Drag'n drop support, accept any kind of drop */
294 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
296 return NSDragOperationCopy;
299 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
301 return NSDragOperationCopy;
304 - (BOOL) performDragOperation:(id <NSDraggingInfo>)sender
307 NSString *errorDescription;
309 NSPasteboard *pasteboard = [sender draggingPasteboard];
311 /* look for paths in pasteboard */
312 if ([[pasteboard types] containsObject:NSFilenamesPboardType])
313 data = [pasteboard dataForType:NSFilenamesPboardType];
316 /* retrieves paths */
317 NSArray *filenames = [NSPropertyListSerialization propertyListFromData:data
318 mutabilityOption:kCFPropertyListImmutable
320 errorDescription:&errorDescription];
323 /* add paths to our datasource */
325 int n = [filenames count];
327 [self addAnImageWithPath:[filenames objectAtIndex:i]];
330 /* make the image browser reload our datasource */
331 [self updateDatasource];
334 /* we accepted the drag operation */
338 - (IBAction)searchFieldUpdate:(id)sender
340 NSMutableArray* tempArray = [[NSMutableArray alloc] init];
341 NSString* searchString = [sender stringValue];
346 if([searchString length] == 0){
347 // _importedImages = _tempArray;
348 // [self updateDatasource];
349 _images = _tempArray;
350 [_mediaBrowser reloadData];
354 for(image in _tempArray){
355 r = [[image imageTitle] rangeOfString:searchString];
357 [_importedImages addObject:image];
360 [_images removeAllObjects];
361 _images = [_importedImages copy];
362 // [_importedImages removeAllObjects];
363 [_mediaBrowser reloadData];
364 // [self updateDatasource];