Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTPlayListWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 94 - (hide annotations) (download)
Sun Sep 21 00:42:38 2008 UTC (15 years, 6 months ago) by masaki
File size: 7577 byte(s)
Undoのグループ化は自動に任せるようにした。
イベント内のundeは勝手にグループ化される。
1 masaki 2 //
2 masaki 72 // XspfQTPlayListWindowController.m
3 masaki 2 // XspfQT
4     //
5     // Created by Hori,Masaki on 08/08/31.
6     // Copyright 2008 masakih. All rights reserved.
7     //
8    
9 masaki 72 #import "XspfQTPlayListWindowController.h"
10     #import "XspfQTDocument.h"
11     #import "XspfQTComponent.h"
12 masaki 2
13    
14 masaki 72 @interface XspfQTPlayListWindowController(Private)
15 masaki 41 - (void)setObserveObject:(id)new;
16     @end
17    
18 masaki 72 @implementation XspfQTPlayListWindowController
19 masaki 2
20 masaki 53 static NSString *const XspfQTPlayListItemType = @"XspfQTPlayListItemType";
21    
22 masaki 2 - (id)init
23     {
24 masaki 73 return [super initWithWindowNibName:@"XspfQTPlayList"];
25 masaki 2 }
26    
27     - (void)awakeFromNib
28     {
29     [listView setDoubleAction:@selector(changeCurrentTrack:)];
30 masaki 41 [[self window] setReleasedWhenClosed:NO];
31    
32     [trackListTree addObserver:self
33     forKeyPath:@"selection"
34     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
35     context:NULL];
36     [self setObserveObject:[trackListTree valueForKeyPath:@"selection.self"]];
37 masaki 51
38     [listView expandItem:[listView itemAtRow:0]];
39 masaki 53
40 masaki 90 [listView registerForDraggedTypes:[NSArray arrayWithObjects:
41     XspfQTPlayListItemType,
42     NSFilenamesPboardType,
43     NSURLPboardType,
44     nil]];
45 masaki 2 }
46 masaki 41 - (void)dealloc
47     {
48     [trackListTree removeObserver:self forKeyPath:@"selection"];
49     [self setObserveObject:nil];
50    
51     [super dealloc];
52     }
53 masaki 2
54     - (IBAction)changeCurrentTrack:(id)sender
55     {
56     id selections = [trackListTree selectedObjects];
57     if([selections count] == 0) return;
58    
59     NSIndexPath *selectionIndexPath = [trackListTree selectionIndexPath];
60    
61     if([selectionIndexPath length] > 1) {
62     [[self document] setPlayTrackindex:[selectionIndexPath indexAtPosition:1]];
63     }
64     }
65 masaki 84 - (IBAction)delete:(id)sender
66     {
67     id selection = [trackListTree valueForKeyPath:@"selection.self"];
68 masaki 86 [[self document] removeComponent:selection];
69 masaki 84 }
70 masaki 34 - (void)keyDown:(NSEvent *)theEvent
71     {
72     if([theEvent isARepeat]) return;
73    
74     unsigned short code = [theEvent keyCode];
75     if(code == 49 /* space bar */) {
76     [[self document] togglePlayAndPause:self];
77     }
78 masaki 83 if(code == 51 /* delete key */) {
79 masaki 84 [self delete:self];
80 masaki 83 }
81 masaki 34 }
82    
83 masaki 84 #pragma mark ### NSMenu valivation ###
84     - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
85     {
86     if([menuItem action] == @selector(delete:)) {
87     if([[trackListTree selectedObjects] count] == 0) {
88     return NO;
89     }
90     if(![[trackListTree valueForKeyPath:@"selection.isLeaf"] boolValue]) {
91     return NO;
92     }
93     }
94    
95     return YES;
96     }
97    
98 masaki 2 - (BOOL)windowShouldClose:(id)sender
99     {
100     [sender orderOut:self];
101    
102     return NO;
103     }
104 masaki 41 - (void)setObserveObject:(id)new
105     {
106     if(obseveObject == new) return;
107    
108     [obseveObject removeObserver:self forKeyPath:@"title"];
109    
110     obseveObject = new;
111     [obseveObject addObserver:self
112     forKeyPath:@"title"
113     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
114     context:NULL];
115     }
116     - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
117     {
118 masaki 49 if([keyPath isEqualToString:@"selection"]) {
119 masaki 41 id new = [object valueForKeyPath:@"selection.self"];
120     [self setObserveObject:new];
121     }
122    
123 masaki 49 if([keyPath isEqualToString:@"title"]) {
124 masaki 41 id new = [change objectForKey:NSKeyValueChangeNewKey];
125     id old = [change objectForKey:NSKeyValueChangeOldKey];
126    
127     if(new == old) return;
128     if([new isEqualTo:old]) return;
129    
130     id um = [[self document] undoManager];
131     [um registerUndoWithTarget:obseveObject
132     selector:@selector(setTitle:)
133     object:old];
134     }
135     }
136 masaki 2
137 masaki 90 - (void)insertItemURL:(NSURL *)url atIndex:(NSUInteger)index
138     {
139     if(![QTMovie canInitWithURL:url]) {
140     @throw self;
141     }
142    
143     // NSLog(@"URL is %@", url);
144     @try {
145     [[self document] insertComponentFromURL:url atIndex:index];
146     }
147     @catch(XspfQTDocument *doc) {
148     @throw self;
149     }
150     }
151     - (BOOL)canInsertItemFromPasteboard:(NSPasteboard *)pb
152     {
153     if([[pb types] containsObject:NSFilenamesPboardType] ||
154     [[pb types] containsObject:NSURLPboardType]) {
155    
156     // ##### Check is playable. #####
157     if([QTMovie canInitWithPasteboard:pb]) {
158     return YES;
159     }
160     }
161    
162     return NO;
163     }
164     - (void)insertItemFromPasteboard:(NSPasteboard *)pb atIndex:(NSUInteger)index
165     {
166     // check filenames.
167     if([[pb types] containsObject:NSFilenamesPboardType]) {
168     BOOL hasSuccesItem = NO;
169    
170     id plist = [pb propertyListForType:NSFilenamesPboardType];
171     if(![plist isKindOfClass:[NSArray class]]) {
172     @throw self;
173     }
174     NSEnumerator *reverse = [plist reverseObjectEnumerator];
175     for(id obj in reverse) {
176     NSURL *fileURL = [NSURL fileURLWithPath:obj];
177     @try {
178     [self insertItemURL:fileURL atIndex:index];
179     }
180     @catch(XspfQTPlayListWindowController *me) {
181     continue;
182     }
183     hasSuccesItem = YES;
184     }
185    
186     if(!hasSuccesItem) {
187     @throw self;
188     }
189 masaki 94 // id undo = [[self document] undoManager];
190     // [undo setActionName:NSLocalizedString(@"Insert movie(s)", @"Undo Action Name Insert movie(s)")];
191 masaki 90 return;
192     }
193    
194     // check URL
195     if([[pb types] containsObject:NSURLPboardType]) {
196     id url = [NSURL URLFromPasteboard:pb];
197     if(url) {
198     [self insertItemURL:url atIndex:index];
199     return;
200     }
201     }
202    
203     @throw self;
204     }
205 masaki 53
206     - (BOOL)outlineView:(NSOutlineView *)outlineView
207     writeItems:(NSArray *)items
208     toPasteboard:(NSPasteboard *)pasteboard
209     {
210     if([items count] > 1) return NO;
211    
212     id item = [[items objectAtIndex:0] representedObject];
213    
214 masaki 72 if(![item isKindOfClass:[XspfQTComponent class]]) {
215 masaki 53 NSLog(@"Ouch! %@", NSStringFromClass([item class]));
216     return NO;
217     }
218     if(![item isLeaf]) return NO;
219    
220     NSData *data = [NSKeyedArchiver archivedDataWithRootObject:item];
221     if(!data) {
222     NSLog(@"Could not archive.");
223     return NO;
224     }
225    
226     [pasteboard declareTypes:[NSArray arrayWithObject:XspfQTPlayListItemType]
227     owner:self];
228     [pasteboard setData:data
229     forType:XspfQTPlayListItemType];
230     return YES;
231     }
232     - (NSDragOperation)outlineView:(NSOutlineView *)outlineView
233     validateDrop:(id <NSDraggingInfo>)info
234     proposedItem:(id)item
235     proposedChildIndex:(NSInteger)index
236     {
237     if([item isLeaf]) {
238     return NSDragOperationNone;
239     }
240    
241     id pb = [info draggingPasteboard];
242    
243     if(![[pb types] containsObject:XspfQTPlayListItemType]) {
244 masaki 88 // ##### insert files? #####
245 masaki 90 if([self canInsertItemFromPasteboard:pb]) {
246     return NSDragOperationCopy;
247     }
248 masaki 53 return NSDragOperationNone;
249     }
250    
251 masaki 80 if(index == -1) return NSDragOperationNone;
252    
253 masaki 53 return NSDragOperationMove;
254     }
255     - (BOOL)outlineView:(NSOutlineView *)outlineView
256     acceptDrop:(id <NSDraggingInfo>)info
257     item:(id)item
258     childIndex:(NSInteger)index
259     {
260     if([item isLeaf]) {
261     return NO;
262     }
263    
264     id pb = [info draggingPasteboard];
265    
266     NSData *data = [pb dataForType:XspfQTPlayListItemType];
267 masaki 88 if(!data) {
268 masaki 90 // ##### insert files? #####
269     @try {
270     [self insertItemFromPasteboard:pb atIndex:index];
271     }
272     @catch(XspfQTPlayListWindowController *me) {
273     return NO;
274     }
275     return YES;
276 masaki 88 }
277 masaki 53
278     id newItem = [NSKeyedUnarchiver unarchiveObjectWithData:data];
279     if(!newItem) return NO;
280    
281 masaki 80 id doc = [self document];
282     NSInteger oldIndex = [[doc trackList] indexOfChild:newItem];
283 masaki 53
284 masaki 88 if(oldIndex == NSNotFound) {
285     // from other list.
286     [doc insertComponent:newItem atIndex:index];
287     return YES;
288     }
289    
290 masaki 80 if(oldIndex == index) return YES;
291     if(oldIndex < index) {
292     index--;
293     }
294    
295     // change archive to original.
296     newItem = [[doc trackList] childAtIndex:oldIndex];
297    
298     BOOL mustSelectionChange = NO;
299     if([newItem isSelected]) {
300     mustSelectionChange = YES;
301     }
302    
303 masaki 94 [doc removeComponent:newItem];
304     [doc insertComponent:newItem atIndex:index];
305 masaki 80
306     if(mustSelectionChange) {
307     [doc setPlayTrackindex:index];
308     }
309    
310 masaki 59 return YES;
311 masaki 53 }
312    
313 masaki 2 @end
314 masaki 34
315 masaki 72 @implementation XspfQTThrowSpacebarKeyDownOutlineView
316 masaki 34 - (void)keyDown:(NSEvent *)theEvent
317     {
318 masaki 83 if(_delegate && [_delegate respondsToSelector:@selector(keyDown:)]) {
319     [_delegate keyDown:theEvent];
320 masaki 34 }
321    
322     [super keyDown:theEvent];
323     }
324     @end

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26