Tagging the 1.0 (3) release of XspfQT project.
@@ -0,0 +1,56 @@ | ||
1 | + | |
2 | +PRODUCT_NAME=XspfQT | |
3 | +PRODUCT_EXTENSION=app | |
4 | +BUILD_PATH=./build | |
5 | +DEPLOYMENT=Release | |
6 | +APP_BUNDLE=$(PRODUCT_NAME).$(PRODUCT_EXTENSION) | |
7 | +APP=$(BUILD_PATH)/$(DEPLOYMENT)/$(APP_BUNDLE) | |
8 | +APP_NAME=$(BUILD_PATH)/$(DEPLOYMENT)/$(PRODUCT_NAME) | |
9 | +INFO_PLIST=Info.plist | |
10 | + | |
11 | +URL_XspfQT = svn+ssh://macmini/usr/local/svnrepos/XspfQT | |
12 | +HEAD = $(URL_XspfQT)/XspfQT | |
13 | +TAGS_DIR = $(URL_XspfQT)/tags | |
14 | + | |
15 | +VER_CMD=grep -A1 'CFBundleShortVersionString' $(INFO_PLIST) | tail -1 | tr -d "'\t</string>" | |
16 | +VERSION=$(shell $(VER_CMD)) | |
17 | + | |
18 | +all: | |
19 | + @echo do nothig. | |
20 | + @echo use target tagging | |
21 | + | |
22 | +tagging: | |
23 | + @echo "Tagging the $(VERSION) (x) release of XspfQT project." | |
24 | + REV=`LC_ALL=C svn info | awk '/Last Changed Rev/ {print $$4}'` ; \ | |
25 | + echo svn copy $(HEAD) $(TAGS_DIR)/release-$(VERSION).$${REV} | |
26 | + | |
27 | +Localizable: BSTRADocument.m | |
28 | + genstrings -o English.lproj $< | |
29 | + (cd English.lproj; ${MAKE} $@;) | |
30 | + genstrings -o Japanese.lproj $< | |
31 | + (cd Japanese.lproj; ${MAKE} $@;) | |
32 | + | |
33 | +checkLocalizable: | |
34 | + (cd English.lproj; ${MAKE} $@;) | |
35 | + (cd Japanese.lproj; ${MAKE} $@;) | |
36 | + | |
37 | +release: updateRevision | |
38 | + xcodebuild -configuration $(DEPLOYMENT) | |
39 | + $(MAKE) restorInfoPlist | |
40 | + | |
41 | +package: release | |
42 | + REV=`LC_ALL=C svn info | awk '/Last Changed Rev/ {print $$4}'`; \ | |
43 | + ditto -ck -rsrc --keepParent $(APP) $(APP_NAME)-$(VERSION)-$${REV}.zip | |
44 | + | |
45 | +updateRevision: update_svn | |
46 | + if [ ! -f $(INFO_PLIST).bak ] ; then cp $(INFO_PLIST) $(INFO_PLIST).bak ; fi ; \ | |
47 | + REV=`LC_ALL=C svn info | awk '/Last Changed Rev/ {print $$4}'` ; \ | |
48 | + sed -e "s/%%%%REVISION%%%%/$${REV}/" $(INFO_PLIST) > $(INFO_PLIST).r ; \ | |
49 | + mv -f $(INFO_PLIST).r $(INFO_PLIST) ; \ | |
50 | + | |
51 | +restorInfoPlist: | |
52 | + if [ -f $(INFO_PLIST).bak ] ; then cp -f $(INFO_PLIST).bak $(INFO_PLIST) ; fi | |
53 | + | |
54 | +update_svn: | |
55 | + svn up | |
56 | + |
@@ -0,0 +1,36 @@ | ||
1 | +// | |
2 | +// XspfMovieWindowController.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | +#import <QTKit/QTKit.h> | |
11 | + | |
12 | + | |
13 | +@interface XspfMovieWindowController : NSWindowController | |
14 | +{ | |
15 | + IBOutlet QTMovieView *qtView; | |
16 | + | |
17 | + NSWindow *fullscreenWindow; | |
18 | + NSRect nomalModeSavedFrame; | |
19 | + BOOL fullscreenMode; | |
20 | + | |
21 | + QTMovie *qtMovie; | |
22 | + NSTimer *updateTime; | |
23 | + | |
24 | + NSPoint prevMouse; | |
25 | + NSDate *prevMouseMovedDate; | |
26 | +} | |
27 | + | |
28 | +- (IBAction)toggleFullScreenMode:(id)sender; | |
29 | +- (IBAction)forwardTagValueSecends:(id)sender; | |
30 | +- (IBAction)backwardTagValueSecends:(id)sender; | |
31 | + | |
32 | +- (void)play; | |
33 | + | |
34 | +- (void)setQtMovie:(QTMovie *)qt; | |
35 | +- (QTMovie *)qtMovie; | |
36 | +@end |
@@ -0,0 +1,334 @@ | ||
1 | +// | |
2 | +// XspfMovieWindowController.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfMovieWindowController.h" | |
10 | +#import "XspfDocument.h" | |
11 | +#import "XspfTrackList.h" | |
12 | +#import "XspfFullScreenWindow.h" | |
13 | + | |
14 | + | |
15 | +@interface XspfMovieWindowController (Private) | |
16 | +- (NSSize)fitSizeToSize:(NSSize)toSize; | |
17 | +- (NSWindow *)fullscreenWindow; | |
18 | +@end | |
19 | + | |
20 | +@implementation XspfMovieWindowController | |
21 | + | |
22 | +static const float sVolumeDelta = 0.2; | |
23 | +static NSString *const kCurrentIndexKeyPath = @"trackList.currentIndex"; | |
24 | + | |
25 | +- (id)initWithWindowNibName:(NSString *)windowNibName | |
26 | +{ | |
27 | + if(self = [super initWithWindowNibName:@"XspfDocument"]) { | |
28 | + // | |
29 | + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; | |
30 | + [nc addObserver:self | |
31 | + selector:@selector(applicationWillTerminate:) | |
32 | + name:NSApplicationWillTerminateNotification | |
33 | + object:NSApp]; | |
34 | + | |
35 | + updateTime = [NSTimer scheduledTimerWithTimeInterval:0.3 | |
36 | + target:self | |
37 | + selector:@selector(updateTimeIfNeeded:) | |
38 | + userInfo:NULL | |
39 | + repeats:YES]; | |
40 | + } | |
41 | + | |
42 | + return self; | |
43 | +} | |
44 | + | |
45 | +- (void)dealloc | |
46 | +{ | |
47 | + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; | |
48 | + [nc removeObserver:self]; | |
49 | + | |
50 | + [fullscreenWindow release]; | |
51 | + | |
52 | + [qtMovie release]; | |
53 | + | |
54 | + [super dealloc]; | |
55 | +} | |
56 | + | |
57 | +- (void)awakeFromNib | |
58 | +{ | |
59 | + prevMouseMovedDate = [[NSDate dateWithTimeIntervalSinceNow:0.0] retain]; | |
60 | + | |
61 | + id d = [self document]; | |
62 | +// NSLog(@"Add Observed! %@", d); | |
63 | + [d addObserver:self | |
64 | + forKeyPath:kCurrentIndexKeyPath | |
65 | + options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld | |
66 | + context:NULL]; | |
67 | + | |
68 | + | |
69 | + id window = [self window]; | |
70 | + NSRect frame = [window frame]; | |
71 | + NSSize newSize = [self fitSizeToSize:frame.size]; | |
72 | + frame.size = newSize; | |
73 | + frame.origin.y -= frame.size.height - newSize.height; | |
74 | + | |
75 | + [window setFrame:frame display:YES]; | |
76 | + | |
77 | + [self play]; | |
78 | +} | |
79 | +- (void)observeValueForKeyPath:(NSString *)keyPath | |
80 | + ofObject:(id)object | |
81 | + change:(NSDictionary *)change | |
82 | + context:(void *)context | |
83 | +{ | |
84 | +// NSLog(@"Observed!"); | |
85 | + if([keyPath isEqual:kCurrentIndexKeyPath]) { | |
86 | + id old = [change objectForKey:NSKeyValueChangeOldKey]; | |
87 | + id new = [change objectForKey:NSKeyValueChangeNewKey]; | |
88 | + if([old isEqual:new]) return; | |
89 | + [self setQtMovie:[self valueForKeyPath:@"document.trackList.qtMovie"]]; | |
90 | + return; | |
91 | + } | |
92 | + | |
93 | + [super observeValueForKeyPath:keyPath | |
94 | + ofObject:object | |
95 | + change:change | |
96 | + context:context]; | |
97 | +} | |
98 | + | |
99 | +- (void)setQtMovie:(QTMovie *)qt | |
100 | +{ | |
101 | + if(qtMovie == qt) return; | |
102 | + if([qtMovie isEqual:qt]) return; | |
103 | + | |
104 | + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; | |
105 | + | |
106 | + if(qtMovie) { | |
107 | + [nc removeObserver:self name:nil object:qtMovie]; | |
108 | + } | |
109 | + if(qt) { | |
110 | + [nc addObserver:self selector:@selector(didEndMovie:) name:QTMovieDidEndNotification object:qt]; | |
111 | + } | |
112 | + | |
113 | + if(qtMovie) { | |
114 | + [qt setVolume:[qtMovie volume]]; | |
115 | + [qt setMuted:[qtMovie muted]]; | |
116 | + } | |
117 | + [qtMovie autorelease]; | |
118 | + qtMovie = [qt retain]; | |
119 | + [self synchronizeWindowTitleWithDocumentName]; | |
120 | + | |
121 | + [self play]; | |
122 | +} | |
123 | +- (QTMovie *)qtMovie | |
124 | +{ | |
125 | + return qtMovie; | |
126 | +} | |
127 | + | |
128 | + | |
129 | +- (NSSize)fitSizeToSize:(NSSize)toSize | |
130 | +{ | |
131 | + QTMovie *curMovie = [self qtMovie]; | |
132 | + if(!curMovie) return toSize; | |
133 | + | |
134 | + NSSize qtViewSize = [qtView frame].size; | |
135 | + NSSize currentWindowSize = [[self window] frame].size; | |
136 | + | |
137 | + NSSize delta = NSMakeSize(currentWindowSize.width - qtViewSize.width, | |
138 | + currentWindowSize.height - qtViewSize.height); | |
139 | + | |
140 | + NSSize movieSize = [[curMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]; | |
141 | + | |
142 | + float targetViewWidth = toSize.width - delta.width; | |
143 | + float targetViewHeight = targetViewWidth * (movieSize.height / movieSize.width); | |
144 | + | |
145 | + targetViewWidth += delta.width; | |
146 | + targetViewHeight += delta.height; | |
147 | + | |
148 | + NSSize newSize = NSMakeSize(targetViewWidth, targetViewHeight); | |
149 | + | |
150 | + return newSize; | |
151 | +} | |
152 | + | |
153 | +- (void)play | |
154 | +{ | |
155 | + [qtView performSelectorOnMainThread:@selector(play:) withObject:self waitUntilDone:NO]; | |
156 | +} | |
157 | + | |
158 | +- (void)enterFullScreen | |
159 | +{ | |
160 | +// if([qtView respondsToSelector:@selector(isInFullScreenMode)]) { | |
161 | +// // System is 10.5 or later. | |
162 | +// id op = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] | |
163 | +// forKey:@"NSFullScreenModeAllScreens"]; | |
164 | +// [qtView enterFullScreenMode:[NSScreen mainScreen] | |
165 | +// withOptions:op]; | |
166 | +// NSLog(@"Use enterFullScreen:withOptions:"); | |
167 | +// } else { | |
168 | + NSWindow *w = [self fullscreenWindow]; | |
169 | + | |
170 | + nomalModeSavedFrame = [qtView frame]; | |
171 | + | |
172 | + [[self window] orderOut:self]; | |
173 | + [w setContentView:qtView]; | |
174 | + | |
175 | +// [NSMenu setMenuBarVisible:NO]; | |
176 | + SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar); | |
177 | + | |
178 | + [w makeKeyAndOrderFront:self]; | |
179 | + [w makeFirstResponder:qtView]; | |
180 | +// } | |
181 | + | |
182 | +} | |
183 | +- (void)exitFullScreen | |
184 | +{ | |
185 | +// if([qtView respondsToSelector:@selector(isInFullScreenMode)]) { | |
186 | +// // System is 10.5 or later. | |
187 | +// [qtView exitFullScreenModeWithOptions:nil]; | |
188 | +// } else { | |
189 | + NSWindow *w = [self fullscreenWindow]; | |
190 | + | |
191 | + [qtView retain]; | |
192 | + { | |
193 | + [qtView removeFromSuperview]; | |
194 | + [qtView setFrame:nomalModeSavedFrame]; | |
195 | + [[[self window] contentView] addSubview:qtView]; | |
196 | + } | |
197 | + [qtView release]; | |
198 | + | |
199 | + [NSMenu setMenuBarVisible:YES]; | |
200 | + [w orderOut:self]; | |
201 | + [[self window] makeKeyAndOrderFront:self]; | |
202 | + [w makeFirstResponder:qtView]; | |
203 | +// } | |
204 | +} | |
205 | +- (IBAction)turnUpVolume:(id)sender | |
206 | +{ | |
207 | + NSNumber *cv = [self valueForKeyPath:@"qtMovie.volume"]; | |
208 | + cv = [NSNumber numberWithFloat:[cv floatValue] + sVolumeDelta]; | |
209 | + [self setValue:cv forKeyPath:@"qtMovie.volume"]; | |
210 | +} | |
211 | +- (IBAction)turnDownVolume:(id)sender | |
212 | +{ | |
213 | + NSNumber *cv = [self valueForKeyPath:@"qtMovie.volume"]; | |
214 | + cv = [NSNumber numberWithFloat:[cv floatValue] - sVolumeDelta]; | |
215 | + [self setValue:cv forKeyPath:@"qtMovie.volume"]; | |
216 | +} | |
217 | +- (IBAction)toggleFullScreenMode:(id)sender | |
218 | +{ | |
219 | + if(fullscreenMode) { | |
220 | + [self exitFullScreen]; | |
221 | + fullscreenMode = NO; | |
222 | + } else { | |
223 | + [self enterFullScreen]; | |
224 | + fullscreenMode = YES; | |
225 | + } | |
226 | +} | |
227 | + | |
228 | +- (IBAction)forwardTagValueSecends:(id)sender | |
229 | +{ | |
230 | + if(![sender respondsToSelector:@selector(tag)]) return; | |
231 | + | |
232 | + int tag = [sender tag]; | |
233 | + if(tag == 0) return; | |
234 | + | |
235 | + QTTime current = [[self qtMovie] currentTime]; | |
236 | + NSTimeInterval cur; | |
237 | + if(!QTGetTimeInterval(current, &cur)) return; | |
238 | + | |
239 | + QTTime new = QTMakeTimeWithTimeInterval(cur + tag); | |
240 | + id newValue = [NSValue valueWithQTTime:new]; | |
241 | + [[self qtMovie] setValue:newValue forKey:@"currentTime"]; | |
242 | +} | |
243 | +- (IBAction)backwardTagValueSecends:(id)sender | |
244 | +{ | |
245 | + if(![sender respondsToSelector:@selector(tag)]) return; | |
246 | + | |
247 | + int tag = [sender tag]; | |
248 | + if(tag == 0) return; | |
249 | + | |
250 | + QTTime current = [[self qtMovie] currentTime]; | |
251 | + NSTimeInterval cur; | |
252 | + if(!QTGetTimeInterval(current, &cur)) return; | |
253 | + | |
254 | + QTTime new = QTMakeTimeWithTimeInterval(cur - tag); | |
255 | + id newValue = [NSValue valueWithQTTime:new]; | |
256 | + [[self qtMovie] setValue:newValue forKey:@"currentTime"]; | |
257 | +} | |
258 | + | |
259 | +- (NSWindow *)fullscreenWindow | |
260 | +{ | |
261 | + if(fullscreenWindow) return fullscreenWindow; | |
262 | + | |
263 | + NSRect mainScreenRect = [[NSScreen mainScreen] frame]; | |
264 | + fullscreenWindow = [[XspfFullScreenWindow alloc] initWithContentRect:mainScreenRect | |
265 | + styleMask:NSBorderlessWindowMask | |
266 | + backing:NSBackingStoreBuffered | |
267 | + defer:YES]; | |
268 | + [fullscreenWindow setReleasedWhenClosed:NO]; | |
269 | + [fullscreenWindow setBackgroundColor:[NSColor blackColor]]; | |
270 | + [fullscreenWindow setDelegate:self]; | |
271 | + | |
272 | + return fullscreenWindow; | |
273 | +} | |
274 | + | |
275 | +- (void)didEndMovie:(id)notification | |
276 | +{ | |
277 | + [[[self document] trackList] next]; | |
278 | +// [self setQtMovie:[[[self document] trackList] qtMovie]]; | |
279 | +} | |
280 | +- (void)updateTimeIfNeeded:(id)timer | |
281 | +{ | |
282 | + QTMovie *qt = [self qtMovie]; | |
283 | + if(qt) { | |
284 | + [qt willChangeValueForKey:@"currentTime"]; | |
285 | + [qt didChangeValueForKey:@"currentTime"]; | |
286 | + } | |
287 | + | |
288 | + // Hide cursor and controller, if mouse didn't move for 3 seconds. | |
289 | + NSPoint mouse = [NSEvent mouseLocation]; | |
290 | + if(!NSEqualPoints(prevMouse, mouse)) { | |
291 | + prevMouse = mouse; | |
292 | + [prevMouseMovedDate autorelease]; | |
293 | + prevMouseMovedDate = [[NSDate dateWithTimeIntervalSinceNow:0.0] retain]; | |
294 | + } else if(fullscreenMode && [prevMouseMovedDate timeIntervalSinceNow] < -3.0 ) { | |
295 | + [NSCursor setHiddenUntilMouseMoves:YES]; | |
296 | + // | |
297 | + // hide controller. | |
298 | + } | |
299 | +} | |
300 | + | |
301 | +- (void)cancelOperation:(id)sender | |
302 | +{ | |
303 | + if(fullscreenMode) { | |
304 | + [self toggleFullScreenMode:self]; | |
305 | + } | |
306 | +} | |
307 | + | |
308 | +- (void)applicationWillTerminate:(NSNotification *)notification | |
309 | +{ | |
310 | + if(fullscreenMode) { | |
311 | + [self toggleFullScreenMode:self]; | |
312 | + } | |
313 | + [[self document] removeObserver:self forKeyPath:kCurrentIndexKeyPath]; | |
314 | +} | |
315 | + | |
316 | + | |
317 | +- (BOOL)windowShouldClose:(id)sender | |
318 | +{ | |
319 | + [qtView pause:self]; | |
320 | + [self setQtMovie:nil]; | |
321 | + | |
322 | + [[self document] removeObserver:self forKeyPath:kCurrentIndexKeyPath]; | |
323 | + [self setShouldCloseDocument:YES]; | |
324 | + | |
325 | + [updateTime release]; | |
326 | + updateTime = nil; | |
327 | + | |
328 | + return YES; | |
329 | +} | |
330 | +- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize | |
331 | +{ | |
332 | + return [self fitSizeToSize:frameSize]; | |
333 | +} | |
334 | +@end |
@@ -0,0 +1,14 @@ | ||
1 | +// | |
2 | +// main.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright masakih 2008 . All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | + | |
11 | +int main(int argc, char *argv[]) | |
12 | +{ | |
13 | + return NSApplicationMain(argc, (const char **) argv); | |
14 | +} |
@@ -0,0 +1,17 @@ | ||
1 | +// | |
2 | +// XspfFullScreenWindow.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | + | |
11 | + | |
12 | +@interface XspfFullScreenWindow : NSWindow | |
13 | +{ | |
14 | + | |
15 | +} | |
16 | + | |
17 | +@end |
@@ -0,0 +1,18 @@ | ||
1 | +// | |
2 | +// XspfPlayListWindowController.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | + | |
11 | +@class XspfTrackList; | |
12 | +@interface XspfPlayListWindowController : NSWindowController | |
13 | +{ | |
14 | + IBOutlet NSOutlineView *listView; | |
15 | + IBOutlet NSTreeController *trackListTree; | |
16 | +} | |
17 | + | |
18 | +@end |
@@ -0,0 +1,51 @@ | ||
1 | +<?xml version="1.0" encoding="UTF-8"?> | |
2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
3 | +<plist version="1.0"> | |
4 | +<dict> | |
5 | + <key>CFBundleDevelopmentRegion</key> | |
6 | + <string>English</string> | |
7 | + <key>CFBundleDocumentTypes</key> | |
8 | + <array> | |
9 | + <dict> | |
10 | + <key>CFBundleTypeExtensions</key> | |
11 | + <array> | |
12 | + <string>xspf</string> | |
13 | + </array> | |
14 | + <key>CFBundleTypeIconFile</key> | |
15 | + <string></string> | |
16 | + <key>CFBundleTypeName</key> | |
17 | + <string>DocumentType</string> | |
18 | + <key>CFBundleTypeOSTypes</key> | |
19 | + <array> | |
20 | + <string>????</string> | |
21 | + </array> | |
22 | + <key>CFBundleTypeRole</key> | |
23 | + <string>Viewer</string> | |
24 | + <key>NSDocumentClass</key> | |
25 | + <string>XspfDocument</string> | |
26 | + </dict> | |
27 | + </array> | |
28 | + <key>CFBundleExecutable</key> | |
29 | + <string>${EXECUTABLE_NAME}</string> | |
30 | + <key>CFBundleIconFile</key> | |
31 | + <string></string> | |
32 | + <key>CFBundleIdentifier</key> | |
33 | + <string>com.masakih.XspfQT</string> | |
34 | + <key>CFBundleInfoDictionaryVersion</key> | |
35 | + <string>6.0</string> | |
36 | + <key>CFBundleName</key> | |
37 | + <string>${PRODUCT_NAME}</string> | |
38 | + <key>CFBundlePackageType</key> | |
39 | + <string>APPL</string> | |
40 | + <key>CFBundleShortVersionString</key> | |
41 | + <string>1.0</string> | |
42 | + <key>CFBundleSignature</key> | |
43 | + <string>????</string> | |
44 | + <key>CFBundleVersion</key> | |
45 | + <string>1.0</string> | |
46 | + <key>NSMainNibFile</key> | |
47 | + <string>MainMenu</string> | |
48 | + <key>NSPrincipalClass</key> | |
49 | + <string>NSApplication</string> | |
50 | +</dict> | |
51 | +</plist> |
@@ -0,0 +1,26 @@ | ||
1 | +// | |
2 | +// XspfFullScreenWindow.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfFullScreenWindow.h" | |
10 | + | |
11 | + | |
12 | +@implementation XspfFullScreenWindow | |
13 | +- (BOOL)canBecomeKeyWindow | |
14 | +{ | |
15 | + return YES; | |
16 | +} | |
17 | +- (void)cancelOperation:(id)sender | |
18 | +{ | |
19 | + id d = [self delegate]; | |
20 | + if(d && [d respondsToSelector:_cmd]) { | |
21 | + [d performSelector:_cmd withObject:sender]; | |
22 | + } | |
23 | + | |
24 | + [super cancelOperation:sender]; | |
25 | +} | |
26 | +@end |
@@ -0,0 +1,28 @@ | ||
1 | +// | |
2 | +// XspfTrackList.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | +#import "XspfComponent.h" | |
11 | + | |
12 | + | |
13 | +@interface XspfTrackList : XspfComponent | |
14 | +{ | |
15 | + NSString *title; | |
16 | + NSMutableArray *tracks; | |
17 | + | |
18 | + unsigned currentIndex; | |
19 | + | |
20 | +} | |
21 | + | |
22 | +- (void)setCurrentIndex:(unsigned)index; | |
23 | +- (unsigned)currentIndex; | |
24 | +- (XspfComponent *)currentTrack; | |
25 | +- (void)next; | |
26 | +- (void)previous; | |
27 | + | |
28 | +@end |
@@ -0,0 +1,27 @@ | ||
1 | +// | |
2 | +// XspfComponent.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | +#import <QTKit/QTKit.h> | |
11 | + | |
12 | +@interface XspfComponent : NSObject | |
13 | +{ | |
14 | + BOOL isSelected; | |
15 | +} | |
16 | + | |
17 | ++ (id)xspfComponemtWithXMLElement:(NSXMLElement *)element; | |
18 | +- (id)initWithXMLElement:(NSXMLElement *)element; | |
19 | + | |
20 | +- (QTMovie *)qtMovie; | |
21 | + | |
22 | +- (void)setTitle:(NSString *)title; | |
23 | +- (NSString *)title; | |
24 | +- (BOOL)isSelected; | |
25 | +- (void)select; | |
26 | +- (void)deselect; | |
27 | +@end |
@@ -0,0 +1,47 @@ | ||
1 | +// | |
2 | +// XspfPlayListWindowController.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfPlayListWindowController.h" | |
10 | +#import "XspfDocument.h" | |
11 | + | |
12 | + | |
13 | +@implementation XspfPlayListWindowController | |
14 | + | |
15 | +- (id)init | |
16 | +{ | |
17 | + return [super initWithWindowNibName:@"XspfPlayList"]; | |
18 | +} | |
19 | + | |
20 | +- (void)awakeFromNib | |
21 | +{ | |
22 | + [listView setDoubleAction:@selector(changeCurrentTrack:)]; | |
23 | +// [[self window] setReleasedWhenClosed:NO]; | |
24 | +} | |
25 | + | |
26 | +- (IBAction)changeCurrentTrack:(id)sender | |
27 | +{ | |
28 | + id selections = [trackListTree selectedObjects]; | |
29 | + if([selections count] == 0) return; | |
30 | + | |
31 | + NSIndexPath *selectionIndexPath = [trackListTree selectionIndexPath]; | |
32 | +// NSLog(@"Selection %@", selectionIndexPath); | |
33 | +// NSLog(@"Selection index %d", [selectionIndexPath indexAtPosition:1]); | |
34 | + | |
35 | + if([selectionIndexPath length] > 1) { | |
36 | + [[self document] setPlayTrackindex:[selectionIndexPath indexAtPosition:1]]; | |
37 | + } | |
38 | +} | |
39 | + | |
40 | +- (BOOL)windowShouldClose:(id)sender | |
41 | +{ | |
42 | + [sender orderOut:self]; | |
43 | + | |
44 | + return NO; | |
45 | +} | |
46 | + | |
47 | +@end |
@@ -0,0 +1,31 @@ | ||
1 | +// | |
2 | +// XspfTrack.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | +#import <QTKit/QTKit.h> | |
11 | +#import "XspfComponent.h" | |
12 | + | |
13 | + | |
14 | +@interface XspfTrack : XspfComponent | |
15 | +{ | |
16 | + NSURL *location; | |
17 | + NSString *title; | |
18 | + | |
19 | + QTMovie *movie; | |
20 | + | |
21 | + NSDate *savedDate; | |
22 | +} | |
23 | + | |
24 | +- (void)setLocation:(NSURL *)location; | |
25 | +- (void)setLocationString:(NSString *)location; | |
26 | +- (NSURL *)location; | |
27 | +- (NSString *)locationString; | |
28 | + | |
29 | +- (void)purgeQTMovie; | |
30 | + | |
31 | +@end |
@@ -0,0 +1,120 @@ | ||
1 | +// | |
2 | +// XspfTrackList.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfTrackList.h" | |
10 | +#import "XspfTrack.h" | |
11 | + | |
12 | + | |
13 | +@implementation XspfTrackList | |
14 | +- (id)initWithXMLElement:(NSXMLElement *)element | |
15 | +{ | |
16 | + self = [super init]; | |
17 | + | |
18 | + NSArray *elems = [element elementsForName:@"track"]; | |
19 | + if(!elems) { | |
20 | + [self release]; | |
21 | + return nil; | |
22 | + } | |
23 | + | |
24 | + tracks = [[NSMutableArray alloc] init]; | |
25 | + | |
26 | + unsigned i, count; | |
27 | + for(i = 0, count = [elems count]; i < count; i++) { | |
28 | + NSXMLElement *trackElem = [elems objectAtIndex:i]; | |
29 | + XspfTrack *track = [XspfTrack xspfComponemtWithXMLElement:trackElem]; | |
30 | + if(track) { | |
31 | + [tracks addObject:track]; | |
32 | + } | |
33 | + } | |
34 | + [self setCurrentIndex:0]; | |
35 | + | |
36 | + return self; | |
37 | +} | |
38 | +- (void)dealloc | |
39 | +{ | |
40 | + [tracks release]; | |
41 | + | |
42 | + [super dealloc]; | |
43 | +} | |
44 | +- (void)setCurrentIndex:(unsigned)index | |
45 | +{ | |
46 | + unsigned prev; | |
47 | + | |
48 | + if(index < 0) return; | |
49 | + if([tracks count] <= index) return; | |
50 | + | |
51 | + [self willChangeValueForKey:@"qtMovie"]; | |
52 | + prev = currentIndex; | |
53 | + currentIndex = index; | |
54 | + [self didChangeValueForKey:@"qtMovie"]; | |
55 | + | |
56 | + @try { | |
57 | + XspfTrack *t = [tracks objectAtIndex:prev]; | |
58 | + [t purgeQTMovie]; | |
59 | + [t willChangeValueForKey:@"isSelected"]; | |
60 | + [t deselect]; | |
61 | + [t didChangeValueForKey:@"isSelected"]; | |
62 | + | |
63 | + XspfComponent *t2 = [self currentTrack]; | |
64 | + [t2 willChangeValueForKey:@"isSelected"]; | |
65 | + [t2 select]; | |
66 | + [t2 didChangeValueForKey:@"isSelected"]; | |
67 | + } | |
68 | + @catch (id ex) { | |
69 | + if(![[ex name] isEqualTo:NSRangeException]) { | |
70 | + @throw; | |
71 | + } | |
72 | + } | |
73 | +} | |
74 | +- (unsigned)currentIndex | |
75 | +{ | |
76 | + return currentIndex; | |
77 | +} | |
78 | +- (NSArray *)children | |
79 | +{ | |
80 | + return tracks; | |
81 | +} | |
82 | + | |
83 | +- (void)next | |
84 | +{ | |
85 | + [self setCurrentIndex:[self currentIndex] + 1]; | |
86 | +} | |
87 | +- (void)previous | |
88 | +{ | |
89 | + [self setCurrentIndex:[self currentIndex] - 1]; | |
90 | +} | |
91 | +- (NSString *)description | |
92 | +{ | |
93 | + return [tracks description]; | |
94 | +} | |
95 | + | |
96 | +- (XspfComponent *)currentTrack | |
97 | +{ | |
98 | + if([tracks count] > currentIndex) { | |
99 | + return [tracks objectAtIndex:currentIndex]; | |
100 | + } | |
101 | + return nil; | |
102 | +} | |
103 | + | |
104 | +- (QTMovie *)qtMovie | |
105 | +{ | |
106 | + return [[self currentTrack] qtMovie]; | |
107 | +} | |
108 | + | |
109 | +- (void)setTitle:(NSString *)t | |
110 | +{ | |
111 | + if(title == t) return; | |
112 | + [title autorelease]; | |
113 | + title = [t copy]; | |
114 | +} | |
115 | +- (NSString *)title | |
116 | +{ | |
117 | + return title; | |
118 | +} | |
119 | + | |
120 | +@end |
@@ -0,0 +1,63 @@ | ||
1 | +// | |
2 | +// XspfComponent.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfComponent.h" | |
10 | + | |
11 | + | |
12 | +@implementation XspfComponent | |
13 | + | |
14 | ++ (id)xspfComponemtWithXMLElement:(NSXMLElement *)element | |
15 | +{ | |
16 | + return [[[self alloc] initWithXMLElement:element] autorelease]; | |
17 | +} | |
18 | +- (id)initWithXMLElement:(NSXMLElement *)element | |
19 | +{ | |
20 | + [super init]; | |
21 | + [self doesNotRecognizeSelector:_cmd]; | |
22 | + | |
23 | + [self release]; | |
24 | + | |
25 | + return nil; | |
26 | +} | |
27 | + | |
28 | +- (QTMovie *)qtMovie | |
29 | +{ | |
30 | + return nil; | |
31 | +} | |
32 | +- (NSDate *)duration | |
33 | +{ | |
34 | + return nil; | |
35 | +} | |
36 | + | |
37 | +- (NSArray *)children | |
38 | +{ | |
39 | + return nil; | |
40 | +} | |
41 | + | |
42 | +- (void)setTitle:(NSString *)title | |
43 | +{ | |
44 | + [self doesNotRecognizeSelector:_cmd]; | |
45 | +} | |
46 | +- (NSString *)title | |
47 | +{ | |
48 | + [self doesNotRecognizeSelector:_cmd]; | |
49 | + return nil; | |
50 | +} | |
51 | +- (BOOL)isSelected | |
52 | +{ | |
53 | + return isSelected; | |
54 | +} | |
55 | +- (void)select | |
56 | +{ | |
57 | + isSelected = YES; | |
58 | +} | |
59 | +- (void)deselect | |
60 | +{ | |
61 | + isSelected = NO; | |
62 | +} | |
63 | +@end |
@@ -0,0 +1,115 @@ | ||
1 | +// | |
2 | +// XspfTrack.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfTrack.h" | |
10 | + | |
11 | + | |
12 | +@implementation XspfTrack | |
13 | +- (id)initWithXMLElement:(NSXMLElement *)element | |
14 | +{ | |
15 | + self = [super init]; | |
16 | + | |
17 | + NSArray *elems = [element elementsForName:@"location"]; | |
18 | + if(!elems || [elems count] == 0) { | |
19 | + [self release]; | |
20 | + return nil; | |
21 | + } | |
22 | + | |
23 | + NSString *loc = [[elems objectAtIndex:0] stringValue];; | |
24 | + [self setLocationString:loc]; | |
25 | + | |
26 | + NSString *t; | |
27 | + elems = [element elementsForName:@"title"]; | |
28 | + if(!elems || [elems count] == 0) { | |
29 | + t = [[self locationString] lastPathComponent]; | |
30 | + } else { | |
31 | + t = [[elems objectAtIndex:0] stringValue]; | |
32 | + } | |
33 | + [self setTitle:t]; | |
34 | + | |
35 | + return self; | |
36 | +} | |
37 | +- (void)dealloc | |
38 | +{ | |
39 | + [location release]; | |
40 | + [title release]; | |
41 | + [movie release]; | |
42 | + [savedDate release]; | |
43 | + | |
44 | + [super dealloc]; | |
45 | +} | |
46 | +- (void)setLocation:(NSURL *)loc | |
47 | +{ | |
48 | + if(location && ![location isKindOfClass:[NSURL class]]) return; | |
49 | + if(location == loc) return; | |
50 | + if([location isEqualTo:loc]) return; | |
51 | + | |
52 | + [location autorelease]; | |
53 | + location = [loc retain]; | |
54 | +} | |
55 | +- (NSURL *)location | |
56 | +{ | |
57 | + return location; | |
58 | +} | |
59 | +- (void)setLocationString:(NSString *)loc | |
60 | +{ | |
61 | + [self setLocation:[NSURL URLWithString:loc]]; | |
62 | +} | |
63 | +- (NSString *)locationString | |
64 | +{ | |
65 | + return [[self location] absoluteString]; | |
66 | +} | |
67 | + | |
68 | +- (void)setTitle:(NSString *)t | |
69 | +{ | |
70 | + if(title == t) return; | |
71 | + if([title isEqualToString:t]) return; | |
72 | + | |
73 | + [title autorelease]; | |
74 | + title = [t retain]; | |
75 | +} | |
76 | +- (NSString *)title | |
77 | +{ | |
78 | + return title; | |
79 | +} | |
80 | +- (NSDate *)duration | |
81 | +{ | |
82 | + if(savedDate) return savedDate; | |
83 | + | |
84 | + if(!movie) return nil; | |
85 | + | |
86 | + id t = [NSValueTransformer valueTransformerForName:@"XspfQTTimeDateTransformer"]; | |
87 | + savedDate = [[t transformedValue:[NSValue valueWithQTTime:[movie duration]]] retain]; | |
88 | + return savedDate; | |
89 | +} | |
90 | +- (QTMovie *)qtMovie | |
91 | +{ | |
92 | + if(![QTMovie canInitWithURL:[self location]]) return nil; | |
93 | + | |
94 | + NSError *error = nil; | |
95 | + | |
96 | + movie = [[QTMovie alloc] initWithURL:[self location] | |
97 | + error:&error]; | |
98 | + | |
99 | + [self willChangeValueForKey:@"duration"]; | |
100 | + [self didChangeValueForKey:@"duration"]; | |
101 | + | |
102 | + return movie; | |
103 | +} | |
104 | +- (void)purgeQTMovie | |
105 | +{ | |
106 | + [movie release]; | |
107 | + movie = nil; | |
108 | +} | |
109 | + | |
110 | +- (NSString *)description | |
111 | +{ | |
112 | + return [NSString stringWithFormat:@"Title:(%@)\nLocation:(%@)", | |
113 | + [self title], [self location]]; | |
114 | +} | |
115 | +@end |
@@ -0,0 +1,17 @@ | ||
1 | +// | |
2 | +// XspfAppDelegate.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | + | |
11 | + | |
12 | +@interface XspfAppDelegate : NSObject | |
13 | +{ | |
14 | + | |
15 | +} | |
16 | + | |
17 | +@end |
@@ -0,0 +1,30 @@ | ||
1 | +// | |
2 | +// MyDocument.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright masakih 2008 . All rights reserved. | |
7 | +// | |
8 | + | |
9 | + | |
10 | +#import <Cocoa/Cocoa.h> | |
11 | +#import <QTKit/QTKit.h> | |
12 | + | |
13 | +@class XspfTrackList; | |
14 | +@class XspfMovieWindowController; | |
15 | + | |
16 | +@interface XspfDocument : NSDocument | |
17 | +{ | |
18 | + XspfTrackList* trackList; | |
19 | + XspfMovieWindowController *movieWindowController; | |
20 | + NSWindowController *playListWindowController; | |
21 | +} | |
22 | + | |
23 | +- (IBAction)showPlayList:(id)sender; | |
24 | + | |
25 | +- (void)setTrackList:(XspfTrackList *)newList; | |
26 | +- (XspfTrackList *)trackList; | |
27 | + | |
28 | +- (void)setPlayTrackindex:(unsigned)index; | |
29 | + | |
30 | +@end |
@@ -0,0 +1,27 @@ | ||
1 | +// | |
2 | +// XspfAppDelegate.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfAppDelegate.h" | |
10 | +#import "XspfValueTransformers.h" | |
11 | + | |
12 | +@implementation XspfAppDelegate | |
13 | + | |
14 | ++ (void)initialize | |
15 | +{ | |
16 | + [NSValueTransformer setValueTransformer:[[[XspfQTTimeTransformer alloc] init] autorelease] | |
17 | + forName:@"XspfQTTimeTransformer"]; | |
18 | + [NSValueTransformer setValueTransformer:[[[XspfQTTimeDateTransformer alloc] init] autorelease] | |
19 | + forName:@"XspfQTTimeDateTransformer"]; | |
20 | +} | |
21 | + | |
22 | +- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender | |
23 | +{ | |
24 | + return NO; | |
25 | +} | |
26 | + | |
27 | +@end |
@@ -0,0 +1,15 @@ | ||
1 | +// | |
2 | +// XspfValueTransformers.h | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <Cocoa/Cocoa.h> | |
10 | + | |
11 | + | |
12 | +@interface XspfQTTimeTransformer : NSValueTransformer | |
13 | +@end | |
14 | +@interface XspfQTTimeDateTransformer : NSValueTransformer | |
15 | +@end |
@@ -0,0 +1,145 @@ | ||
1 | +// | |
2 | +// MyDocument.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/29. | |
6 | +// Copyright masakih 2008 . All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import "XspfDocument.h" | |
10 | +#import "XspfTrackList.h" | |
11 | +#import "XspfMovieWindowController.h" | |
12 | +#import "XspfPlayListWindowController.h" | |
13 | + | |
14 | +@interface XspfDocument (Private) | |
15 | +- (void)setTrackList:(XspfTrackList *)newList; | |
16 | +- (XspfTrackList *)trackList; | |
17 | +@end | |
18 | + | |
19 | +@implementation XspfDocument | |
20 | + | |
21 | +- (id)init | |
22 | +{ | |
23 | + self = [super init]; | |
24 | + if (self) { | |
25 | + | |
26 | + // Add your subclass-specific initialization here. | |
27 | + // If an error occurs here, send a [self release] message and return nil. | |
28 | + | |
29 | + } | |
30 | + return self; | |
31 | +} | |
32 | + | |
33 | +- (void)makeWindowControllers | |
34 | +{ | |
35 | + playListWindowController = [[XspfPlayListWindowController alloc] init]; | |
36 | + [self addWindowController:playListWindowController]; | |
37 | + | |
38 | + movieWindowController = [[[XspfMovieWindowController alloc] initWithWindowNibName:@""] autorelease]; | |
39 | + [self addWindowController:movieWindowController]; | |
40 | + [movieWindowController setQtMovie:[[self trackList] qtMovie]]; | |
41 | +} | |
42 | +//- (NSString *)windowNibName | |
43 | +//{ | |
44 | +// // Override returning the nib file name of the document | |
45 | +// // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead. | |
46 | +// return @"MyDocument"; | |
47 | +//} | |
48 | + | |
49 | +- (void)windowControllerDidLoadNib:(NSWindowController *)windowController | |
50 | +{ | |
51 | + [super windowControllerDidLoadNib:windowController]; | |
52 | + // Add any code here that needs to be executed once the windowController has loaded the document's window. | |
53 | +// [self setQtMovie:[[self trackList] qtMovie]]; | |
54 | +} | |
55 | + | |
56 | +- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError | |
57 | +{ | |
58 | + // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil. | |
59 | + | |
60 | + // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead. | |
61 | + | |
62 | + // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead. | |
63 | + | |
64 | + if ( outError != NULL ) { | |
65 | + *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; | |
66 | + } | |
67 | + return nil; | |
68 | +} | |
69 | + | |
70 | +- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError | |
71 | +{ | |
72 | + // Insert code here to read your document from the given data of the specified type. If the given outError != NULL, ensure that you set *outError when returning NO. | |
73 | + | |
74 | + // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead. | |
75 | + | |
76 | + // For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead. | |
77 | + | |
78 | + NSError *error = nil; | |
79 | + NSXMLDocument *d = [[NSXMLDocument alloc] initWithData:data | |
80 | + options:0 | |
81 | + error:&error]; | |
82 | + NSXMLElement *root = [d rootElement]; | |
83 | + | |
84 | + NSArray *trackListElems; | |
85 | + trackListElems = [root elementsForName:@"trackList"]; | |
86 | + // NSLog(@"trackList -> %@", trackListElems); | |
87 | + | |
88 | + if([trackListElems count] < 1) { | |
89 | + if ( outError != NULL ) { | |
90 | + *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; | |
91 | + } | |
92 | + return NO; | |
93 | + } | |
94 | + | |
95 | + id t = [XspfTrackList xspfComponemtWithXMLElement:[trackListElems objectAtIndex:0]]; | |
96 | + [t setTitle:[[[self fileURL] path] lastPathComponent]]; | |
97 | + [self setTrackList:t]; | |
98 | +// NSLog(@"trackList -> %@", trackList); | |
99 | + | |
100 | +// [self setQtMovie:[[self trackList] qtMovie]]; | |
101 | + | |
102 | + return YES; | |
103 | +} | |
104 | + | |
105 | +- (void)dealloc | |
106 | +{ | |
107 | + [trackList release]; | |
108 | + [playListWindowController release]; | |
109 | + | |
110 | + [super dealloc]; | |
111 | +} | |
112 | +- (NSString *)displayName | |
113 | +{ | |
114 | + NSString *trackTitle = [[[self trackList] currentTrack] title]; | |
115 | + if(trackTitle) { | |
116 | + return [NSString stringWithFormat:@"%@ - %@", | |
117 | + [super displayName], trackTitle]; | |
118 | + } | |
119 | + | |
120 | + return [super displayName]; | |
121 | +} | |
122 | + | |
123 | +- (IBAction)showPlayList:(id)sender | |
124 | +{ | |
125 | + [playListWindowController showWindow:self]; | |
126 | +} | |
127 | + | |
128 | +- (void)setTrackList:(XspfTrackList *)newList | |
129 | +{ | |
130 | + if(trackList == newList) return; | |
131 | + | |
132 | + [trackList autorelease]; | |
133 | + trackList = [newList retain]; | |
134 | +} | |
135 | +- (XspfTrackList *)trackList | |
136 | +{ | |
137 | + return trackList; | |
138 | +} | |
139 | + | |
140 | +- (void)setPlayTrackindex:(unsigned)index | |
141 | +{ | |
142 | + [[self trackList] setCurrentIndex:index]; | |
143 | +} | |
144 | +@end | |
145 | + |
@@ -0,0 +1,103 @@ | ||
1 | +// | |
2 | +// XspfValueTransformers.m | |
3 | +// XspfQT | |
4 | +// | |
5 | +// Created by Hori,Masaki on 08/08/31. | |
6 | +// Copyright 2008 masakih. All rights reserved. | |
7 | +// | |
8 | + | |
9 | +#import <QTKit/QTKit.h> | |
10 | + | |
11 | +#import "XspfValueTransformers.h" | |
12 | + | |
13 | + | |
14 | +@implementation XspfQTTimeTransformer | |
15 | ++ (Class)transformedValueClass | |
16 | +{ | |
17 | + return [NSNumber class]; | |
18 | +} | |
19 | ++ (BOOL)allowsReverseTransformation | |
20 | +{ | |
21 | + return YES; | |
22 | +} | |
23 | +- (id)transformedValue:(id)value | |
24 | +{ | |
25 | + if(!value) return nil; | |
26 | + | |
27 | +// static first = YES; | |
28 | +// if(first) { | |
29 | +// first = NO; | |
30 | +// NSLog(@"%@ in value class -> %@", NSStringFromSelector(_cmd), NSStringFromClass([value class])); | |
31 | +// NSLog(@"value -> %@", value); | |
32 | +// } | |
33 | + | |
34 | + QTTime t = [value QTTimeValue]; | |
35 | + NSTimeInterval res; | |
36 | + | |
37 | + if(!QTGetTimeInterval(t, &res)) {return nil;} | |
38 | + | |
39 | + return [NSNumber numberWithDouble:res]; | |
40 | +} | |
41 | +- (id)reverseTransformedValue:(id)value | |
42 | +{ | |
43 | + if(!value) return nil; | |
44 | + | |
45 | +// static first = YES; | |
46 | +// if(first) { | |
47 | +// first = NO; | |
48 | +// NSLog(@"%@ in value class -> %@", NSStringFromSelector(_cmd), NSStringFromClass([value class])); | |
49 | +// NSLog(@"value -> %@", value); | |
50 | +// } | |
51 | + | |
52 | + QTTime t = QTMakeTimeWithTimeInterval([value doubleValue]); | |
53 | + | |
54 | + return [NSValue valueWithQTTime:t]; | |
55 | +} | |
56 | +@end | |
57 | + | |
58 | +@implementation XspfQTTimeDateTransformer | |
59 | ++ (Class)transformedValueClass | |
60 | +{ | |
61 | + return [NSDate class]; | |
62 | +} | |
63 | ++ (BOOL)allowsReverseTransformation | |
64 | +{ | |
65 | + return NO; | |
66 | +} | |
67 | +- (id)transformedValue:(id)value | |
68 | +{ | |
69 | + if(!value) return nil; | |
70 | + | |
71 | +// static first = YES; | |
72 | +// if(first) { | |
73 | +// first = NO; | |
74 | +// NSLog(@"%@ in value class -> %@", NSStringFromSelector(_cmd), NSStringFromClass([value class])); | |
75 | +// NSLog(@"value -> %@", value); | |
76 | +// } | |
77 | + | |
78 | + QTTime t = [value QTTimeValue]; | |
79 | + NSTimeInterval res; | |
80 | + | |
81 | + if(!QTGetTimeInterval(t, &res)) {return nil;} | |
82 | + | |
83 | + res -= [[NSTimeZone systemTimeZone] secondsFromGMT]; | |
84 | + | |
85 | + return [NSDate dateWithTimeIntervalSince1970:res]; | |
86 | +} | |
87 | +//- (id)reverseTransformedValue:(id)value | |
88 | +//{ | |
89 | +// if(!value) return nil; | |
90 | +// | |
91 | +// static first = YES; | |
92 | +// if(first) { | |
93 | +// first = NO; | |
94 | +// NSLog(@"%@ in value class -> %@", NSStringFromSelector(_cmd), NSStringFromClass([value class])); | |
95 | +// NSLog(@"value -> %@", value); | |
96 | +// } | |
97 | +// NSTimeInterval val = [value timeIntervalSinceReferenceDate]; | |
98 | +// val += [[NSTimeZone systemTimeZone] secondsFromGMT]; | |
99 | +// QTTime t = QTMakeTimeWithTimeInterval(val); | |
100 | +// | |
101 | +// return [NSValue valueWithQTTime:t]; | |
102 | +//} | |
103 | +@end | |
\ No newline at end of file |