OSDN Git Service

first commit
[eliscolors/main.git] / ElisMediaBrowserController.m
1 //
2 //  ElisMediaBrowserController.m
3 //  Elis Colors
4 //
5 //  Created by 柳 on 09/09/17.
6 //  Copyright 2009 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "ElisMediaBrowserController.h"
10
11 /* openFiles is a simple C function that open an NSOpenPanel and return an array of selected filepath */
12 static NSArray *openFiles()
13
14     NSOpenPanel *panel;
15     
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];
22         if(i == NSOKButton){
23                 return [panel filenames];
24     }
25     
26     return nil;
27 }    
28
29
30 @implementation myImageObject
31
32 //- (void) dealloc
33 //{
34 //    [_path release];
35 //    [super dealloc];
36 //}
37
38 /* our datasource object is just a filepath representation */
39 - (void) setPath:(NSString *) path
40 {
41     _path = path;
42     flag = NO;
43 }
44
45 - (void)setMoviePath:(NSString*)path
46 {
47     _path = path;
48     flag = YES;
49 }
50
51
52 /* required methods of the IKImageBrowserItem protocol */
53 #pragma mark -
54 #pragma mark item data source protocol
55
56 /* let the image browser knows we use a path representation */
57 - (NSString *)  imageRepresentationType
58 {
59     if(flag)
60         return IKImageBrowserQTMoviePathRepresentationType;
61     else
62         return IKImageBrowserQuickLookPathRepresentationType;
63     //    return IKImageBrowserPathRepresentationType;
64 }
65
66 /* give our representation to the image browser */
67 - (id)  imageRepresentation
68 {
69         return _path;
70 }
71
72 /* use the absolute filepath as identifier */
73 - (NSString *) imageUID
74 {
75     return _path;
76 }
77
78 - (NSString *)imageTitle
79 {
80     return [_path lastPathComponent];
81 }
82
83 @end
84
85
86
87 /* the controller */
88 @implementation ElisMediaBrowserController
89
90 - (void) dealloc
91 {
92     [_images release];
93     [_importedImages release];
94     [super dealloc];
95 }
96
97 - (void) awakeFromNib
98 {
99         /* create two arrays : the first one is our datasource representation, the second one are temporary imported images (for thread safeness ) 
100      */
101     _images = [[NSMutableArray alloc] init];
102     _importedImages = [[NSMutableArray alloc] init];
103     _tempArray = [[NSMutableArray alloc] init];
104     
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]];
110 }
111
112 /* entry point for reloading image-browser's data and setNeedsDisplay */
113 - (void) updateDatasource
114 {
115     //-- update our datasource, add recently imported items
116     [_images addObjectsFromArray:_importedImages];
117         
118         //-- empty our temporary array
119     [_importedImages removeAllObjects];
120     
121     //-- reload the image browser and set needs display
122     [_mediaBrowser reloadData];
123 }
124
125 #pragma mark -
126 #pragma mark import images from file system
127
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.
131  */
132
133 - (void) addAnImageWithPath:(NSString *) path
134 {   
135     myImageObject *p;
136     NSWorkspace* sharedWorkspace = [NSWorkspace sharedWorkspace];
137     
138     // 読めるメディアかチェック
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"]) {
143            
144            /* add a path to our temporary array */
145            p = [[myImageObject alloc] init];
146            [p setPath:path];
147            [_importedImages addObject:p];
148     }
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"])
153     {
154         p = [[myImageObject alloc] init];
155         [p setMoviePath:path];
156         [_importedImages addObject:p];
157     }
158 }
159
160 - (void) addImagesWithPath:(NSString *) path recursive:(BOOL) recursive
161 {
162     int i, n;
163     BOOL dir;
164     
165     [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&dir];
166     
167     if(dir){
168         NSArray *content = [[NSFileManager defaultManager] directoryContentsAtPath:path];
169         
170         n = [content count];
171         
172                 /* parse the directory content*/
173         for(i=0; i<n; i++){
174             //            NSLog(@"%d", i);
175             if(recursive)
176                 [self addImagesWithPath:[path stringByAppendingPathComponent:[content objectAtIndex:i]] recursive:YES];
177             else
178                 [self addAnImageWithPath:[path stringByAppendingPathComponent:[content objectAtIndex:i]]];
179         }
180     }
181     else
182         [self addAnImageWithPath:path];
183 }
184
185 /* performed in an independant thread, parse all paths in "paths" and add these paths in our temporary array */
186 - (void) addImagesWithPaths:(NSArray *) paths
187 {   
188     int i, n;
189     
190     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
191     
192     n = [paths count];
193     for(i=0; i<n; i++){
194         NSString *path = [paths objectAtIndex:i];
195         [self addImagesWithPath:path recursive:NO];
196     }
197     
198         /* update the datasource in the main thread */
199     [self performSelectorOnMainThread:@selector(updateDatasource) withObject:nil waitUntilDone:YES];
200     
201     _tempArray = [_images copy];
202     
203     [pool release];
204 }
205
206 #pragma mark -
207 #pragma mark actions
208
209 /* "add" button was clicked */
210 - (IBAction) addImageMenuClicked:(id) sender
211 {   
212     NSArray *path = openFiles();
213     
214     if(!path){ 
215         NSLog(@"No path selected, return..."); 
216         return; 
217     }
218         
219         /* launch import in an independent thread */
220     [NSThread detachNewThreadSelector:@selector(addImagesWithPaths:) toTarget:self withObject:path];
221 }
222
223 /* action called when the zoom slider did change */
224 - (IBAction) zoomSliderDidChange:(id)sender
225 {
226         /* update the zoom value to scale images */
227     [_mediaBrowser setZoomValue:[sender floatValue]];
228         
229         /* redisplay */
230     [_mediaBrowser setNeedsDisplay:YES];
231 }
232
233 #pragma mark -
234 #pragma mark IKImageBrowserDataSource
235
236 /* implement image-browser's datasource protocol 
237  Our datasource representation is a simple mutable array
238  */
239
240 - (int) numberOfItemsInImageBrowser:(IKImageBrowserView *) view
241 {
242         /* item count to display is our datasource item count */
243     return [_images count];
244 }
245
246 - (id) imageBrowser:(IKImageBrowserView *) view itemAtIndex:(int) index
247 {
248     return [_images objectAtIndex:index];
249 }
250
251 /* implement some optional methods of the image-browser's datasource protocol to be able to remove and reoder items */
252
253 /*      remove
254  The user wants to delete images, so remove these entries from our datasource.  
255  */
256 - (void) imageBrowser:(IKImageBrowserView *) view removeItemsAtIndexes: (NSIndexSet *) indexes
257 {
258         [_images removeObjectsAtIndexes:indexes];
259 }
260
261 /* reordering 
262  The user wants to reorder images, update our datasource and the browser will reflect our changes
263  */
264 - (BOOL) imageBrowser:(IKImageBrowserView *) view  moveItemsAtIndexes: (NSIndexSet *)indexes toIndex:(unsigned int)destinationIndex
265 {
266     int index;
267     NSMutableArray *temporaryArray;
268     
269     temporaryArray = [[[NSMutableArray alloc] init] autorelease];
270     
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)
274             destinationIndex --;
275         
276         id obj = [_images objectAtIndex:index];
277         [temporaryArray addObject:obj];
278         [_images removeObjectAtIndex:index];
279     }
280     
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];
285     }
286         
287     return YES;
288 }
289
290 #pragma mark -
291 #pragma mark drag n drop 
292
293 /* Drag'n drop support, accept any kind of drop */
294 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
295 {
296     return NSDragOperationCopy;
297 }
298
299 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
300 {
301     return NSDragOperationCopy;
302 }
303
304 - (BOOL) performDragOperation:(id <NSDraggingInfo>)sender
305 {
306     NSData *data = nil;
307     NSString *errorDescription;
308         
309     NSPasteboard *pasteboard = [sender draggingPasteboard];
310     
311         /* look for paths in pasteboard */
312     if ([[pasteboard types] containsObject:NSFilenamesPboardType]) 
313         data = [pasteboard dataForType:NSFilenamesPboardType];
314     
315     if(data){
316                 /* retrieves paths */
317         NSArray *filenames = [NSPropertyListSerialization propertyListFromData:data 
318                                                               mutabilityOption:kCFPropertyListImmutable 
319                                                                         format:nil 
320                                                               errorDescription:&errorDescription];
321         
322         
323                 /* add paths to our datasource */
324         int i;
325         int n = [filenames count];
326         for(i=0; i<n; i++){
327             [self addAnImageWithPath:[filenames objectAtIndex:i]];
328         }
329                 
330                 /* make the image browser reload our datasource */
331         [self updateDatasource];
332     }
333     
334         /* we accepted the drag operation */
335         return YES;
336 }
337
338 - (IBAction)searchFieldUpdate:(id)sender
339 {
340     NSMutableArray* tempArray = [[NSMutableArray alloc] init];
341     NSString* searchString = [sender stringValue];
342         
343     NSRange r;
344     id image;
345     
346     if([searchString length] == 0){
347 //        _importedImages = _tempArray;
348 //        [self updateDatasource];
349         _images = _tempArray;
350         [_mediaBrowser reloadData];
351         return;
352     }
353     
354     for(image in _tempArray){
355         r = [[image imageTitle] rangeOfString:searchString];
356         if(r.length != 0)
357             [_importedImages addObject:image];
358     }
359     
360     [_images removeAllObjects];
361     _images = [_importedImages copy];
362 //    [_importedImages removeAllObjects];
363     [_mediaBrowser reloadData];
364 //    [self updateDatasource];
365     
366 }
367
368 @end
369