Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfManager/XspfMMainWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 358 - (hide annotations) (download)
Wed May 19 13:11:30 2010 UTC (13 years, 11 months ago) by masakih
File size: 17713 byte(s)
詳細表示部を刷新。
詳細表示の非表示に対応。
1 masaki 2 //
2     // XspfManager.m
3     // XspfManager
4     //
5     // Created by Hori,Masaki on 09/11/01.
6     //
7    
8 masakih 350 /*
9     Copyright (c) 2009-2010, masakih
10     All rights reserved.
11     ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満たす場合に限り、再頒布および使用が許可されます。
12    
13     1, ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項を含めること。
14     2, バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作権表示、本条件一覧、および下記免責条項を含めること。
15     3, 書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進に、コントリビューターの名前を使用してはならない。
16     本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供されており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありません。著作権者もコントリビューターも、事由のいかんを問わず、 損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生する可能性を知らされていたとしても、本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されない)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、一切責任を負わないものとします。
17     -------------------------------------------------------------------
18     Copyright (c) 2009-2010, masakih
19     All rights reserved.
20    
21     Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
22    
23     1, Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
24     2, Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
25     3, The names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29 masaki 182 #import "XspfMMainWindowController.h"
30 masaki 2
31 masaki 238 #import "XspfMXspfObject.h"
32 masaki 2
33 masaki 189 #import "XspfMViewController.h"
34 masaki 41 #import "XspfMLibraryViewController.h"
35 masaki 16 #import "XspfMCollectionViewController.h"
36 masaki 25 #import "XspfMListViewController.h"
37 masaki 47 #import "XspfMDetailViewController.h"
38 masaki 281 #import "XspfMCoverFlowViewController.h"
39 masaki 2
40 masaki 281
41 masaki 193 #import "XspfMDragControl.h"
42    
43 masaki 69
44 masaki 182 @interface XspfMMainWindowController(HMPrivate)
45 masaki 43 - (void)setupXspfLists;
46 masaki 47 - (void)setupDetailView;
47 masaki 82 - (void)setupAccessorylView;
48 masaki 25 - (void)changeViewType:(XspfMViewType)newType;
49     - (void)setCurrentListViewType:(XspfMViewType)newType;
50 masaki 189 - (void)recalculateKeyViewLoop;
51 masaki 199
52     - (void)removeSelectedItem;
53 masaki 16 @end
54    
55 masaki 317
56 masaki 182 @implementation XspfMMainWindowController
57 masaki 8 - (id)init
58     {
59 masaki 200 self = [super initWithWindowNibName:@"MainWindow"];
60     if(self) {
61     viewControllers = [[NSMutableDictionary alloc] init];
62     }
63 masaki 50
64 masaki 8 return self;
65 masaki 2 }
66 masaki 8 - (void)awakeFromNib
67     {
68 masaki 47 static BOOL didSetupOnMainMenu = NO;
69    
70     if(appDelegate && !didSetupOnMainMenu) {
71     didSetupOnMainMenu = YES;
72 masaki 98
73 masaki 185 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
74     [nc addObserver:self
75     selector:@selector(managerDidAddObjects:)
76     name:XspfManagerDidAddXspfObjectsNotification
77     object:appDelegate];
78 masaki 304
79 masaki 49 [self window];
80 masaki 99
81 masaki 47 }
82 masaki 8 }
83 masaki 49 - (void)windowDidLoad
84     {
85 masakih 358 [[self window] setContentBorderThickness:27 forEdge:NSMinYEdge];
86 masaki 82
87 masaki 294 [splitView setDelegate:self];
88 masaki 49 [self setupXspfLists];
89     [self setupDetailView];
90 masaki 82 [self setupAccessorylView];
91 masaki 49
92 masaki 316 [self setCurrentListViewType:[[NSUserDefaults standardUserDefaults] integerForKey:@"viewType"]];
93 masaki 315
94 masaki 316
95 masaki 315 [listController bind:NSManagedObjectContextBinding
96     toObject:appDelegate
97     withKeyPath:@"managedObjectContext"
98     options:nil];
99    
100     [allXspfController bind:NSManagedObjectContextBinding
101     toObject:appDelegate
102     withKeyPath:@"managedObjectContext"
103     options:nil];
104 masaki 332
105 masaki 50 [self showWindow:nil];
106 masaki 189 [self recalculateKeyViewLoop];
107 masaki 49 }
108 masaki 25 #pragma mark#### KVC ####
109 masaki 2
110 masaki 25 - (XspfMViewType)currentListViewType
111     {
112     return currentListViewType;
113     }
114     - (void)setCurrentListViewType:(XspfMViewType)newType
115     {
116     if(currentListViewType == newType) return;
117    
118 masaki 316 [[NSUserDefaults standardUserDefaults] setInteger:newType forKey:@"viewType"];
119    
120 masaki 25 [self changeViewType:newType];
121     }
122 masaki 16
123 masaki 13 #pragma mark#### Actions ####
124 masaki 10 - (IBAction)openXspf:(id)sender
125     {
126 masaki 115 BOOL isSelected = [[controller valueForKeyPath:@"selectedObjects.@count"] boolValue];
127     if(!isSelected) return;
128    
129 masaki 238 XspfMXspfObject *rep = [controller valueForKeyPath:@"selection.self"];
130 masaki 277 BOOL didOpen = [[NSWorkspace sharedWorkspace] openFile:rep.filePath withApplication:@"XspfQT"];
131     if(didOpen) {
132     rep.lastPlayDate = [NSDate dateWithTimeIntervalSinceNow:0.0];
133 masaki 101 return;
134     }
135 masaki 277
136     NSInteger result = NSRunCriticalAlertPanel(NSLocalizedString(@"Xspf is not found", @"Xspf is not found"),
137     NSLocalizedString(@"\"%@\" is not found.", @"\"%@\" is not found."),
138     nil, nil/*@"Search Original"*/, nil, rep.title);
139     if(result == NSAlertDefaultReturn) {
140     return;
141     } else if(result == NSAlertAlternateReturn) {
142     //
143 masakih 345 #warning should implement.
144 masaki 277 }
145    
146 masaki 10 }
147 masaki 190 - (IBAction)switchListView:(id)sender
148     {
149     [self setCurrentListViewType:typeTableView];
150     }
151     - (IBAction)switchRegularIconView:(id)sender
152     {
153     [self setCurrentListViewType:typeCollectionView];
154     [(XspfMCollectionViewController *)listViewController collectionViewItemViewRegular:sender];
155     }
156     - (IBAction)switchSmallIconView:(id)sender
157     {
158     [self setCurrentListViewType:typeCollectionView];
159     [(XspfMCollectionViewController *)listViewController collectionViewItemViewSmall:sender];
160     }
161 masaki 281 - (IBAction)switchCoverFlowView:(id)sender
162     {
163     [self setCurrentListViewType:typeCoverFlowView];
164     }
165    
166 masaki 191 - (void)sortByKey:(NSString *)key
167 masaki 190 {
168 masaki 216 NSMutableArray *sortDescs = [[[controller sortDescriptors] mutableCopy] autorelease];
169 masaki 190 NSSortDescriptor *sortDesc = nil;
170    
171     // key is descs first key.
172     if([sortDescs count] > 1) {
173     NSSortDescriptor *firstDesc = [sortDescs objectAtIndex:0];
174     if([key isEqualToString:[firstDesc key]]) {
175     sortDesc = [[[NSSortDescriptor alloc] initWithKey:key ascending:![firstDesc ascending]] autorelease];
176     [sortDescs removeObject:firstDesc];
177     }
178     }
179     // remove same key.
180     if(!sortDesc) {
181 masaki 191 BOOL newAscending = NO;
182 masaki 190 NSSortDescriptor *foundDesc = nil;
183     for(id desc in sortDescs) {
184     if([key isEqualToString:[desc key]]) {
185     foundDesc = desc;
186     break;
187     }
188     }
189     if(foundDesc) {
190 masaki 191 newAscending = [foundDesc ascending];
191 masaki 190 [sortDescs removeObject:foundDesc];
192     }
193    
194 masaki 191 sortDesc = [[[NSSortDescriptor alloc] initWithKey:key ascending:newAscending] autorelease];
195 masaki 190 }
196    
197     [sortDescs insertObject:sortDesc atIndex:0];
198    
199     NSArray *selectedObjects = [controller selectedObjects];
200     [controller setSortDescriptors:sortDescs];
201     [controller setSelectedObjects:selectedObjects];
202     }
203     - (IBAction)sortByTitle:(id)sender
204     {
205 masaki 191 [self sortByKey:@"title"];
206 masaki 190 }
207     - (IBAction)sortByLastPlayDate:(id)sender
208     {
209 masaki 191 [self sortByKey:@"lastPlayDate"];
210 masaki 190 }
211     - (IBAction)sortByModificationDate:(id)sender
212     {
213 masaki 191 [self sortByKey:@"modificationDate"];
214 masaki 190 }
215     - (IBAction)sortByCreationDate:(id)sender
216     {
217 masaki 191 [self sortByKey:@"creationDate"];
218 masaki 190 }
219     - (IBAction)sortByRegisterDate:(id)sender
220     {
221 masaki 191 [self sortByKey:@"registerDate"];
222 masaki 190 }
223     - (IBAction)sortByRate:(id)sender
224     {
225 masaki 191 [self sortByKey:@"rating"];
226 masaki 190 }
227     - (IBAction)sortByMovieNumber:(id)sender
228     {
229 masaki 191 [self sortByKey:@"movieNum"];
230 masaki 190 }
231     - (IBAction)sortByLabel:(id)sender
232     {
233 masaki 224 [self sortByKey:@"label"];
234 masaki 190 }
235    
236 masaki 2 - (IBAction)add:(id)sender
237     {
238     NSOpenPanel *panel = [NSOpenPanel openPanel];
239    
240     [panel setAllowedFileTypes:[NSArray arrayWithObjects:@"xspf", @"com.masakih.xspf", nil]];
241     [panel setAllowsMultipleSelection:YES];
242 masaki 9 [panel setDelegate:self];
243 masaki 2
244     [panel beginSheetForDirectory:nil
245     file:nil
246     types:[NSArray arrayWithObjects:@"xspf", @"com.masakih.xspf", nil]
247 masaki 8 modalForWindow:[self window]
248 masaki 2 modalDelegate:self
249     didEndSelector:@selector(endOpenPanel:::)
250     contextInfo:NULL];
251     }
252 masaki 106 - (void)endOpenPanel:(NSOpenPanel *)panel :(NSInteger)returnCode :(void *)context
253     {
254     [panel orderOut:nil];
255 masaki 2
256 masaki 106 if(returnCode == NSCancelButton) return;
257    
258     NSArray *URLs = [panel URLs];
259     if([URLs count] == 0) return;
260    
261 masaki 184 [appDelegate registerURLs:URLs];
262 masaki 106 }
263 masaki 190 - (IBAction)remove:(id)sender
264     {
265 masaki 199 [self removeSelectedItem];
266 masaki 190 }
267 masaki 182
268 masaki 194 - (IBAction)newPredicate:(id)sender
269     {
270     [libraryViewController newPredicate:sender];
271     }
272    
273 masakih 358 - (IBAction)showHideDetail:(id)sender
274     {
275     BOOL flag = YES;
276    
277     NSPoint origin = [detailView frame].origin;
278     NSSize size = NSZeroSize;
279     CGFloat windowRightEdge = [[detailView window] frame].size.width;
280     flag = (origin.x == windowRightEdge);
281    
282     CGFloat detailWidth = [detailView frame].size.width;
283     if(flag){ // show
284     origin.x -= detailWidth;
285     size = [splitView frame].size;
286     size.width -= detailWidth;
287     } else { // hide
288     origin.x += detailWidth;
289     size = [splitView frame].size;
290     size.width += detailWidth;
291     }
292     [[detailView animator] setFrameOrigin:origin];
293     [[splitView animator] setFrameSize:size];
294     }
295    
296 masaki 190 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
297     {
298     BOOL enabled = YES;
299     SEL action = [menuItem action];
300    
301     if(action == @selector(switchListView:)) {
302     if(currentListViewType == typeTableView) {
303     [menuItem setState:NSOnState];
304     } else {
305     [menuItem setState:NSOffState];
306     }
307     } else if(action == @selector(switchRegularIconView:)) {
308     if(currentListViewType == typeCollectionView
309     && [(XspfMCollectionViewController*)listViewController collectionItemType] == typeXspfMRegularItem) {
310     [menuItem setState:NSOnState];
311     } else {
312     [menuItem setState:NSOffState];
313     }
314     } else if(action == @selector(switchSmallIconView:)) {
315     if(currentListViewType == typeCollectionView
316     && [(XspfMCollectionViewController*)listViewController collectionItemType] == typeXSpfMSmallItem) {
317     [menuItem setState:NSOnState];
318     } else {
319     [menuItem setState:NSOffState];
320     }
321 masaki 281 } else if(action == @selector(switchCoverFlowView:)) {
322     if(currentListViewType == typeCoverFlowView) {
323     [menuItem setState:NSOnState];
324     } else {
325     [menuItem setState:NSOffState];
326     }
327 masaki 190 }
328    
329     return enabled;
330     }
331    
332 masaki 25 #pragma mark#### Other methods ####
333 masaki 199 - (void)removeSelectedItem
334     {
335 masaki 238 XspfMXspfObject *obj = [controller valueForKeyPath:@"selection.self"];
336 masaki 199
337     NSBeginInformationalAlertSheet(nil, nil, @"Cancel", nil, [self window],
338     self, @selector(didEndAskDelete:::), Nil, obj,
339     NSLocalizedString(@"Do you really delete item \"%@\" from list?", @"Do you really delete item \"%@\" from list?"),
340     obj.title);
341     }
342     - (void)didEndAskDelete:(NSWindow *)sheet :(NSInteger)returnCode :(void *)contextInfo
343     {
344     if(returnCode == NSCancelButton) return;
345    
346     [appDelegate removeObject:contextInfo];
347     }
348    
349 masaki 189 - (void)recalculateKeyViewLoop
350     {
351     [searchField setNextKeyView:[libraryViewController firstKeyView]];
352     [libraryViewController setNextKeyView:[listViewController firstKeyView]];
353     [listViewController setNextKeyView:[detailViewController firstKeyView]];
354     [detailViewController setNextKeyView:searchField];
355     }
356 masaki 25 - (void)changeViewType:(XspfMViewType)viewType
357     {
358     if(currentListViewType == viewType) return;
359     currentListViewType = viewType;
360    
361     NSString *className = nil;
362     switch(currentListViewType) {
363     case typeCollectionView:
364     className = @"XspfMCollectionViewController";
365     break;
366     case typeTableView:
367     className = @"XspfMListViewController";
368     break;
369 masaki 281 case typeCoverFlowView:
370     className = @"XspfMCoverFlowViewController";
371     break;
372 masaki 25 }
373     if(!className) return;
374    
375 masaki 189 XspfMViewController *targetContorller = [viewControllers objectForKey:className];
376 masaki 25 if(!targetContorller) {
377     targetContorller = [[[NSClassFromString(className) alloc] init] autorelease];
378     if(!targetContorller) return;
379 masaki 192
380     id selectionIndexes = [controller selectionIndexes];
381 masaki 25 [viewControllers setObject:targetContorller forKey:className];
382 masaki 180 [targetContorller view];
383 masaki 30 [targetContorller setRepresentedObject:controller];
384 masaki 189 [targetContorller recalculateKeyViewLoop];
385 masaki 192 [controller setSelectionIndexes:selectionIndexes];
386 masaki 25 }
387 masaki 109
388 masaki 25 [[listViewController view] removeFromSuperview];
389     listViewController = targetContorller;
390     [listView addSubview:[listViewController view]];
391 masakih 358 NSRect rect = [listView bounds];
392     rect.size.height += 1;
393     rect.origin.y -= 1;
394     [[listViewController view] setFrame:rect];
395 masaki 189 // [[self window] recalculateKeyViewLoop];
396     [self recalculateKeyViewLoop];
397 masaki 25 }
398 masaki 2
399 masaki 5
400 masaki 43 - (void)setupXspfLists
401 masaki 36 {
402 masaki 47 if(libraryViewController) return;
403    
404 masaki 41 libraryViewController = [[XspfMLibraryViewController alloc] init];
405 masaki 37 [libraryViewController setRepresentedObject:listController];
406     [libraryView addSubview:[libraryViewController view]];
407 masaki 193 NSRect rect = [libraryView bounds];
408     rect.size.width += 2;
409     rect.origin.x -= 1;
410 masakih 358 rect.size.height += 1;
411     rect.origin.y -= 1;
412 masaki 193 [[libraryViewController view] setFrame:rect];
413 masaki 189 [libraryViewController recalculateKeyViewLoop];
414 masaki 233 [[libraryViewController dragControl] setDelegate:self];
415 masaki 36 }
416 masaki 47 - (void)setupDetailView
417 masaki 6 {
418 masaki 47 if(detailViewController) return;
419 masaki 6
420 masaki 47 detailViewController = [[XspfMDetailViewController alloc] init];
421     [detailViewController setRepresentedObject:controller];
422     [detailView addSubview:[detailViewController view]];
423     [[detailViewController view] setFrame:[detailView bounds]];
424 masaki 189 [detailViewController recalculateKeyViewLoop];
425 masaki 6 }
426 masaki 82 - (void)setupAccessorylView
427     {
428     if(accessoryViewController) return;
429    
430     accessoryViewController = [[NSViewController alloc] initWithNibName:@"AccessoryView" bundle:nil];
431     [accessoryViewController setRepresentedObject:[appDelegate channel]];
432     [accessoryView addSubview:[accessoryViewController view]];
433     [[accessoryViewController view] setFrame:[accessoryView bounds]];
434 masaki 189 // [accessoryViewController recalculateKeyViewLoop];
435 masaki 82 }
436 masaki 8 #pragma mark#### NSWidnow Delegate ####
437     /**
438     Returns the NSUndoManager for the application. In this case, the manager
439     returned is that of the managed object context for the application.
440     */
441 masaki 6
442 masaki 8 - (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window {
443     return [[appDelegate managedObjectContext] undoManager];
444     }
445    
446 masaki 9 #pragma mark#### NSOpenPanel Delegate ####
447     - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
448     {
449 masaki 184 return ![appDelegate didRegisteredURL:[NSURL fileURLWithPath:filename]];
450 masaki 9 }
451 masaki 294 #pragma mark#### NSSplitView Delegate ####
452     - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex
453     {
454     return 130;
455     }
456 masaki 295 - (void)splitView:(NSSplitView *)aSplitView resizeSubviewsWithOldSize:(NSSize)oldSize
457     {
458     NSView *rightView = [[splitView subviews] objectAtIndex:1];
459     NSRect newFrame = [splitView frame];
460     NSRect libFrame = [libraryView frame];
461     NSRect listFrame = [rightView frame];
462     CGFloat dividerThickness = [splitView dividerThickness];
463    
464     libFrame.size.height = newFrame.size.height;
465     listFrame.size.height = newFrame.size.height;
466    
467     listFrame.size.width = newFrame.size.width - libFrame.size.width - dividerThickness;
468    
469     if(listFrame.size.width < 0) listFrame.size.width = 0;
470    
471     [libraryView setFrame:libFrame];
472     [rightView setFrame:listFrame];
473     }
474 masaki 193 #pragma mark#### XspfMDragControl Delegate ####
475     - (void)dragControl:(XspfMDragControl *)control dragDelta:(NSSize)delta
476     {
477     HMLog(HMLogLevelDebug, @"Enter %@", NSStringFromSelector(_cmd));
478     CGFloat libWidth = [libraryView frame].size.width;
479     [splitView setPosition:libWidth + delta.width ofDividerAtIndex:0];
480     }
481    
482 masaki 185 #pragma mark#### XspfManager Notifications ####
483     - (void)managerDidAddObjects:(NSNotification *)notification
484     {
485     id addedObjects = [[notification userInfo] objectForKey:@"XspfManagerAddedXspfObjects"];
486     if(!addedObjects || ![addedObjects isKindOfClass:[NSArray class]] || [addedObjects count] == 0) return;
487    
488     [controller performSelector:@selector(setSelectedObjects:)
489     withObject:addedObjects
490     afterDelay:0.01];
491     }
492    
493 masaki 184 #pragma mark#### Test ####
494     - (IBAction)test01:(id)sender
495     {
496 masakih 358 NSPoint origin = [detailView frame].origin;
497     origin.x = [[detailView window] frame].size.width;
498     [detailView setFrameOrigin:origin];
499 masaki 184 }
500     - (IBAction)test02:(id)sender
501     {
502     NSResponder *responder = [[self window] firstResponder];
503     while(responder) {
504 masaki 188 HMLog(HMLogLevelDebug, @"Responder -> %@", responder);
505 masaki 184 responder = [responder nextResponder];
506     }
507     }
508     - (IBAction)test03:(id)sender
509     {
510 masakih 358 id anime = [detailView animator];
511     NSPoint origin = [detailView frame].origin;
512     origin.x = [[detailView window] frame].size.width;
513     [anime setFrameOrigin:origin];
514 masaki 184
515 masakih 358 anime = [splitView animator];
516     NSSize size = [splitView frame].size;
517     size.width += [detailView frame].size.width;
518     [anime setFrameSize:size];
519 masaki 184 }
520     @end
521 masaki 297

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