Index: trunk/Cocoa/Pester/Source/NJRQTMediaPopUpButton.m
===================================================================
--- trunk/Cocoa/Pester/Source/NJRQTMediaPopUpButton.m	(revision 355)
+++ trunk/Cocoa/Pester/Source/NJRQTMediaPopUpButton.m	(revision 533)
@@ -14,5 +14,4 @@
 #import <QTKit/QTKit.h>
 
-#include <QuickTime/Movies.h>
 #include <limits.h>
 
@@ -25,6 +24,7 @@
 - (NSMenuItem *)_itemForAlias:(BDAlias *)alias;
 - (BOOL)_validateWithPreview:(BOOL)doPreview;
-- (void)_updateOutputVolume;
 - (void)_startSoundPreview;
+- (void)_resetPreview;
+- (void)_resetOutputVolume;
 @end
 
@@ -304,6 +304,6 @@
     if ([preview movie] == nil) {
         [self _validateWithPreview: YES];
-    } else { // don't restart preview if already playing
-        [self _updateOutputVolume];
+    } else {
+        [self _startSoundPreview];
     }
 }
@@ -318,13 +318,33 @@
 }
 
-- (void)_updateOutputVolume;
-{
-    if ([preview movie] != nil && outputVolume != kNoVolume) {
-        if (!savedVolume && ![NJRSoundManager saveDefaultOutputVolume])
-            return;
+- (void)_startSoundPreview;
+{
+    if ([preview movie] == nil || outputVolume == kNoVolume)
+	return;
+
+    if (savedVolume || [NJRSoundManager saveDefaultOutputVolume]) {
         savedVolume = YES;
         [NJRSoundManager setDefaultOutputVolume: outputVolume];
-        if (![preview isPlaying]) [self _startSoundPreview];
-    }
+    }
+
+    if ([[preview movie] rate] != 0)
+	return; // don't restart preview if already playing
+    
+    [[NSNotificationCenter defaultCenter] addObserver: self
+					     selector: @selector(_soundPreviewDidEnd:)
+						 name: QTMovieDidEndNotification
+					       object: [preview movie]];
+    [preview play: self];
+}
+
+- (void)_soundPreviewDidEnd:(NSNotification *)notification;
+{
+    [self _resetPreview];
+}
+
+- (void)_resetPreview;
+{
+    [preview setMovie: nil];
+    [self _resetOutputVolume];
 }
 
@@ -335,38 +355,7 @@
 }
 
-- (void)_resetPreview;
-{
-    // if we donÕt do this after the runloop has finished, then we crash in MCIdle because itÕs expecting a movie and doesnÕt have one any more
-    [preview setMovie: nil]; // otherwise we get an extra runloop timer which uses a lot of CPU from +[NSMovieView _idleMovies]
-    // need to wait for runloop to stop movie, otherwise we're still playing at the time the volume changes
-    [self performSelector: @selector(_resetOutputVolume) withObject: nil afterDelay: 0];
-}
-
-void
-MovieStoppedCB(QTCallBack cb, long refCon)
-{
-    NJRQTMediaPopUpButton *self = (NJRQTMediaPopUpButton *)refCon;
-    // avoid multiple messages from multiple movie playback cycles in the same runloop
-    [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(_resetPreview) object: nil];
-    [self performSelector: @selector(_resetPreview) withObject: nil afterDelay: 0];
-    DisposeCallBack(cb);
-}
-
-- (void)_startSoundPreview;
-{
-    Movie qtMovie = [[preview movie] QTMovie];
-    QTCallBack cbStop = NewCallBack(GetMovieTimeBase(qtMovie), callBackAtExtremes);
-    QTCallBackUPP cbStopUPP = NewQTCallBackUPP(MovieStoppedCB);
-    OSErr err = CallMeWhen(cbStop, cbStopUPP, (long)self, triggerAtStop, 0, 0);
-    if (err != noErr) {
-        NSLog(@"Can't register QuickTime stop timebase callback for preview: %ld", err);
-        DisposeCallBack(cbStop);
-    }
-    [preview start: self];
-}
-
 - (BOOL)_validateWithPreview:(BOOL)doPreview;
 {
-    [preview stop: self];
+    [preview pause: self];
     if (selectedAlias == nil) {
         [preview setMovie: nil];
@@ -382,6 +371,5 @@
         movieCanRepeat = ![movie isStatic];
         if (movieHasAudio = [movie hasAudio]) {
-            [preview setMovie: doPreview ? movie : nil];
-            [self _updateOutputVolume];
+            [preview setMovie: doPreview ? [QTMovie movieWithURL: [NSURL fileURLWithPath: [selectedAlias fullPath]] error: NULL] : nil]; // XXX handle errors; fix
         } else {
             [self _resetPreview];
@@ -412,5 +400,5 @@
 - (IBAction)stopSoundPreview:(id)sender;
 {
-    [preview stop: self];
+    [preview pause: self];
     [self _resetPreview];
 }
