OSDN Git Service

dvdnav: fix crash when poorly masterd disc has no menus
[handbrake-jp/handbrake-jp-git.git] / macosx / InstantHandBrake / ExpressController.m
index 393ab9d..37ab8b0 100644 (file)
@@ -1,3 +1,7 @@
+/* This file is part of the HandBrake source code.
+   Homepage: <http://handbrake.fr/>.
+   It may be used under the terms of the GNU General Public License. */
+
 #import "ExpressController.h"
 
 #define INSERT_STRING       @"Insert a DVD"
@@ -8,6 +12,8 @@
 
 #define p fState->param
 
+#import "Device.h"
+
 @interface ExpressController (Private)
 
 - (void) openUpdateDrives: (NSDictionary *) drives;
@@ -15,6 +21,7 @@
     returnCode contextInfo: (void *) contextInfo;
 - (void) openEnable: (BOOL) b;
 
+- (id) updatePopUpIcon: (id) value;
 - (void) convertShow;
 - (void) convertEnable: (BOOL) b;
 
     /* NSToolbar initializations */
     fToolbar = [[NSToolbar alloc] initWithIdentifier: @"InstantHandBrake Toolbar"];
     [fToolbar setDelegate: self];
-    [fToolbar setAllowsUserCustomization: YES];
+    [fToolbar setAllowsUserCustomization: NO];
     [fToolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
     [fToolbar setVisible:NO];
+    [fWindow setShowsToolbarButton:NO];
     [fWindow setToolbar: fToolbar];
         
     /* Show the "Open DVD" interface */
@@ -62,7 +70,7 @@
     [tableColumn setDataCell: buttonCell];
 
     /* Preferences */
-    fConvertFolderString = [NSString stringWithFormat:@"%@/Desktop", NSHomeDirectory()];
+    fConvertFolderString = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"];
     [fConvertFolderString retain];
 }
 
@@ -74,6 +82,8 @@
     fState = [fCore hb_state];
     fList   = hb_get_titles( fHandle );
     
+    fDevice = [[DeviceController alloc] init];
+    
     [[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(scanningSource:)
     name:@"HBCoreScanningNotification" object:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(workDone:)
     name:@"HBCoreWorkDoneNotification" object:nil];
+    
+    [GrowlApplicationBridge setGrowlDelegate: self];
 }
 
 - (void) applicationWillTerminate: (NSNotification *) n
     [fCore close];
 }
 
+- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
+{
+    if( !flag ) {
+        [fWindow  makeKeyAndOrderFront:nil];
+        return YES;
+    }
+    return NO;
+}
+
 - (NSToolbarItem *) toolbar: (NSToolbar *) toolbar itemForItemIdentifier: (NSString *) ident
                     willBeInsertedIntoToolbar: (BOOL) flag
 {
 
     if ([ident isEqualToString: TOOLBAR_START])
     {
-        [item setLabel: NSLocalizedString(@"Start", "Start")];
+        [item setLabel: NSLocalizedString(@"Convert", "Convert")];
+        [item setPaletteLabel: NSLocalizedString(@"Convert/Cancel", @"Convert/Cancel")];
         [item setImage: [NSImage imageNamed: @"Play"]];
         [item setTarget: self];
         [item setAction: @selector(convertGo:)];
     else if ([ident isEqualToString: TOOLBAR_PAUSE])
     {
         [item setLabel: NSLocalizedString(@"Pause", "Pause")];
+        [item setPaletteLabel: NSLocalizedString(@"Pause/Resume", @"Pause/Resume")];
         [item setImage: [NSImage imageNamed: @"Pause"]];
         [item setTarget: self];
         [item setAction: @selector(pauseGo:)];
     }
     else if ([ident isEqualToString: TOOLBAR_OPEN])
     {
-        [item setLabel: NSLocalizedString(@"Open", "Open")];
-        [item setImage: [NSImage imageNamed: @"pref-audio"]];
+        [item setLabel: NSLocalizedString(@"Open...", "Open...")];
+        [item setPaletteLabel: NSLocalizedString(@"Open Another Source", "Open Another Source")];
+        [item setImage: [NSImage imageNamed: @"Open"]];
         [item setTarget: self];
         [item setAction: @selector(openShow:)];
     }
-    else if ([ident isEqualToString: TOOLBAR_ADVANCED])
-    {
-        [item setLabel: NSLocalizedString(@"Advanced", "Advanced")];
-        [item setImage: [NSImage imageNamed: @"pref-advanced"]];
-        [item setTarget: self];
-        [item setAction: @selector(setPrefView:)];
-        [item setAutovalidates: NO];
-    }
     else
     {
         [item release];
 - (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
 {
     return [NSArray arrayWithObjects: TOOLBAR_START, TOOLBAR_PAUSE,
-                                        TOOLBAR_OPEN, NSToolbarFlexibleSpaceItemIdentifier, TOOLBAR_ADVANCED, nil];
+                                    NSToolbarFlexibleSpaceItemIdentifier, TOOLBAR_OPEN, nil];
 }
 
 - (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
 {
     return [NSArray arrayWithObjects: TOOLBAR_START, TOOLBAR_PAUSE,
-                                        TOOLBAR_OPEN, TOOLBAR_ADVANCED, nil];
+                                        TOOLBAR_OPEN, NSToolbarFlexibleSpaceItemIdentifier, nil];
 }
 
 /***********************************************************************
                         title->seconds];
             }
         }
+        else if( [[col identifier] isEqualToString: @"Size"] )
+        {
+            return [NSString stringWithFormat:@"-"];
+        }
     }
     return nil;
 }
 - (void) openShow: (id) sender
 {
     NSRect frame  = [fWindow frame];
-    float  offset = [fConvertView frame].size.height -
-                    [fOpenView frame].size.height;
+    float  offset = [fConvertView frame].size.height -
+                    [fOpenView frame].size.height ) * [fWindow userSpaceScaleFactor];
 
     frame.origin.y    += offset;
     frame.size.height -= offset;
     [fWindow setContentView: fEmptyView];
     [fWindow setFrame: frame display: YES animate: YES];
     [fToolbar setVisible:NO];
+    [fOpenProgressField setStringValue: @""];
     [fWindow setContentView: fOpenView];
 
     [fDriveDetector run];
     [self openEnable: NO];
     [fOpenIndicator setIndeterminate: YES];
     [fOpenIndicator startAnimation: nil];
-    [fOpenProgressField setStringValue: @"Opening..."];
+    [fOpenProgressField setStringValue: NSLocalizedString( @"Opening...", @"Opening...") ];
     [fDriveDetector stop];
 
     if( [fOpenMatrix selectedRow] )
     }
 }
 
+- (void) selectFolderSheetShow: (id) sender
+{
+    NSOpenPanel * panel = [NSOpenPanel openPanel];
+
+    [panel setPrompt: NSLocalizedString(@"Select", @"Convert -> Save panel prompt")];
+    [panel setAllowsMultipleSelection: NO];
+    [panel setCanChooseFiles: NO];
+    [panel setCanChooseDirectories: YES];
+    [panel setCanCreateDirectories: YES];
+
+    [panel beginSheetForDirectory: nil file: nil types: nil
+        modalForWindow: fWindow modalDelegate: self didEndSelector:
+        @selector(selectFolderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
+}
+
+- (void) selectFolderSheetClosed: (NSOpenPanel *) sheet returnCode: (int)
+    returnCode contextInfo: (void *) contextInfo
+{
+    if( returnCode != NSOKButton )
+        return;
+
+    if( fConvertFolderString )
+        [fConvertFolderString release];
+    fConvertFolderString = [[[sheet filenames] objectAtIndex: 0] retain];
+    [[fConvertFolderPopUp itemAtIndex: 0] setTitle: [fConvertFolderString lastPathComponent]];
+    [fConvertFolderPopUp selectItemAtIndex:0];
+    
+    NSMenuItem * item = [fConvertFolderPopUp itemAtIndex: 0];
+    [item setImage: [self updatePopUpIcon:fConvertFolderString]];
+    
+}
+
 - (void) convertGo: (id) sender
 {
     int i, j;
+    Preset * currentPreset = [[[fDevice devicesList] objectAtIndex:[fConvertFormatPopUp indexOfSelectedItem]] firstPreset];
 
     for( i = 0; i < hb_list_count( fList ); i++ )
     {
         hb_title_t * title = hb_list_item( fList, i );
         hb_job_t   * job   = title->job;
 
-        int pixels = 307200;
+               int maxwidth = [currentPreset maxWidth];
+        int maxheight = [currentPreset maxHeight];
+        int pixels = maxwidth * maxheight;
                int aspect = title->aspect;
-               if( [fConvertAspectPopUp indexOfSelectedItem] == 1)
+        
+               if( [fConvertAspectPopUp indexOfSelectedItem] == 1 )
                {
             aspect = 4 * HB_ASPECT_BASE / 3;
                }
+        else if ( [fConvertAspectPopUp indexOfSelectedItem] == 2 )
+        {
+            aspect = 16 * HB_ASPECT_BASE / 9;
+        }
 
-               int maxwidth = 640;
-               job->vbitrate = 1000;
-               if( [fConvertMaxWidthPopUp indexOfSelectedItem] == 1)
-               {
-            maxwidth = 320;
-                       job->vbitrate = 500;
-               }
-               //job->deinterlace = 1;
+               job->vbitrate = [currentPreset videoBitRate];
                
-               do
+        if( [fConvertMaxWidthPopUp indexOfSelectedItem] == 2 )
                {
-                       hb_set_size( job, aspect, pixels );
-                       pixels -= 10;
-               } while(job->width > maxwidth);
-               
-        if( [fConvertFormatPopUp indexOfSelectedItem] == 0 )
+            maxwidth = 480;
+                       job->vbitrate /= 1.5;
+        }
+        else if ( [fConvertMaxWidthPopUp indexOfSelectedItem] == 3 )
         {
-            /* iPod / H.264 */
-            job->mux      = HB_MUX_IPOD;
-            job->vcodec   = HB_VCODEC_X264;
-                       job->h264_level = 30;
+            maxwidth = 320;
+                       job->vbitrate /= 2;
         }
-        else if( [fConvertFormatPopUp indexOfSelectedItem] == 1 )
+        
+        if ( [fConvertAspectPopUp indexOfSelectedItem] > 0 )
         {
-            /* iPod / MPEG-4 */
-            job->mux      = HB_MUX_MP4;
-            job->vcodec   = HB_VCODEC_FFMPEG;
+            do
+            {
+                hb_set_size( job, aspect, pixels );
+                pixels -= 10;
+            } while(job->width > maxwidth || job->height > maxheight);
         }
         else
         {
-            /* PSP / MPEG-4 */
-            job->mux        = HB_MUX_PSP;
-            job->vrate      = 27000000;
-            job->vrate_base = 900900;   /* 29.97 fps */
-            job->vcodec     = HB_VCODEC_FFMPEG;
-            job->vbitrate   = 600;
-            pixels          = 76800;
-            job->arate      = 24000;
-            job->abitrate   = 96;
-            aspect          = 16 * HB_ASPECT_BASE / 9;
-
-                       if( [fConvertAspectPopUp indexOfSelectedItem] )
-                       {
-                               aspect = -1;
-                       }
-
-                       hb_set_size( job, aspect, pixels );
+            /* Reset job->crop values */
+            memcpy( job->crop, job->title->crop, 4 * sizeof( int ) );
+            job->width = maxwidth;
+            hb_fix_aspect( job, HB_KEEP_WIDTH );
         }
-
+               
+        job->mux        = [currentPreset muxer];
+        job->vcodec     = [currentPreset videoCodec];
+        job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */  
+        strcpy(job->x264opts, [[currentPreset videoCodecOptions] UTF8String]);
+        job->chapter_markers = 1;
         job->vquality = -1.0;
 
         const char * lang;
     [fOpenPopUp        setEnabled: b];
     [fOpenFolderField  setEnabled: b];
     [fOpenBrowseButton setEnabled: b];
+    [fOpenGoButton     setEnabled: b]; 
 
     if( b )
     {
             if( [[fOpenPopUp titleOfSelectedItem]
                     isEqualToString: INSERT_STRING] )
             {
+                [fOpenGoButton setEnabled: NO];
             }
         }
     }
     else
     {
         [fDriveDetector run];
+        [fOpenProgressField setStringValue: NSLocalizedString(@"No Title Found...",@"No Title Found...")];
     }
 }
 
                [fConvertAudioPopUp selectItemWithTitle: @"English"];
         
         if ( [fConvertAudioPopUp selectedItem] == nil )
-            [fConvertAudioPopUp selectItemWithTitle: @"Unknown"];
+            [fConvertAudioPopUp selectItemAtIndex:0];
 
         /* Update subtitle popup */
         hb_subtitle_t * subtitle;
         }
     }
     [fConvertTableView reloadData];
+    
+    NSEnumerator * enumerator;
+    Device * device;
+    enumerator = [[fDevice devicesList] objectEnumerator];
+    
+    while( ( device = [enumerator nextObject] ) )
+        [fConvertFormatPopUp addItemWithTitle:[device name]];
 
     NSRect frame  = [fWindow frame];
-    float  offset = [fConvertView frame].size.height -
-                    [fOpenView frame].size.height;
-    float hoffset = [fConvertView frame].size.width -
-                    [fOpenView frame].size.width;
+    float  offset = ( [fConvertView frame].size.height -
+                    [fOpenView frame].size.height ) * [fWindow userSpaceScaleFactor];;
     frame.origin.y    -= offset;
     frame.size.height += offset;
-    frame.size.width += hoffset;
     [fWindow setContentView: fEmptyView];
     [fWindow setFrame: frame display: YES animate: YES];
     [fToolbar setVisible:YES];
     [fWindow setContentView: fConvertView];
 
-    /* Folder popup */
     NSMenuItem * item = [fConvertFolderPopUp itemAtIndex: 0];
     [item setTitle: [fConvertFolderString lastPathComponent]];
-    NSImage * image32 = [[NSWorkspace sharedWorkspace] iconForFile:
-        fConvertFolderString];
-    NSImage * image16 = [[NSImage alloc] initWithSize:
-        NSMakeSize(16,16)];
-    [image16 lockFocus];
-    [[NSGraphicsContext currentContext]
-        setImageInterpolation: NSImageInterpolationHigh];
-    [image32 drawInRect: NSMakeRect(0,0,16,16)
-        fromRect: NSMakeRect(0,0,32,32) operation: NSCompositeCopy
-        fraction: 1.0];
-    [image16 unlockFocus];                                                      
-    [item setImage: image16];
-    [image16 release];
-
+    [item setImage: [self updatePopUpIcon:fConvertFolderString]];
+    
     [self convertEnable: YES];
 }
 
     [fConvertMaxWidthPopUp setEnabled: b];
     [fConvertAudioPopUp setEnabled: b];
     [fConvertSubtitlePopUp setEnabled: b];
-    [fConvertOpenButton setEnabled: b];
 }
 
 /***********************************************************************
     [icon release];
 }
 
+- (id) updatePopUpIcon: (id) value
+{
+    if (!value)
+        return nil;
+    
+    NSImage * icon;
+    
+    icon = [[NSWorkspace sharedWorkspace] iconForFile: value];
+    
+    [icon setScalesWhenResized: YES];
+    [icon setSize: NSMakeSize(16.0 , 16.0)];
+    
+    return icon;
+}
+
 - (void) working: (NSNotification *) n
 {
    float progress_total = ( p.working.progress + p.working.job_cur - 1 ) / p.working.job_count;
-            NSMutableString * string = [NSMutableString
-                stringWithFormat: @"Converting: %.1f %%",
-                100.0 * progress_total];
-            if( p.working.seconds > -1 )
-            {
-                [string appendFormat: @" (%.1f fps, ", p.working.rate_avg];
-                if( p.working.hours > 0 )
-                {
-                    [string appendFormat: @"%d hour%s %d min%s",
-                        p.working.hours, p.working.hours == 1 ? "" : "s",
-                        p.working.minutes, p.working.minutes == 1 ? "" : "s"];
-                }
-                else if( p.working.minutes > 0 )
-                {
-                    [string appendFormat: @"%d min%s %d sec%s",
-                        p.working.minutes, p.working.minutes == 1 ? "" : "s",
-                        p.working.seconds, p.working.seconds == 1 ? "" : "s"];
-                }
-                else
-                {
-                    [string appendFormat: @"%d second%s",
-                        p.working.seconds, p.working.seconds == 1 ? "" : "s"];
-                }
-                [string appendString: @" left)"];
-            }
-            [fConvertInfoString setStringValue: string];
-            [fConvertIndicator setIndeterminate: NO];
-            [fConvertIndicator setDoubleValue: 100.0 * progress_total];
-            [self UpdateDockIcon: progress_total];
-
+    NSMutableString * string = [NSMutableString stringWithFormat: @"Converting: %.1f %%", 100.0 * progress_total];
+    
+    if( p.working.seconds > -1 )
+    {
+        [string appendFormat: @" (%.1f fps, ", p.working.rate_avg];
+        if( p.working.hours > 0 )
+        {
+        [string appendFormat: @"%d hour%s %d min%s",
+            p.working.hours, p.working.hours == 1 ? "" : "s",
+            p.working.minutes, p.working.minutes == 1 ? "" : "s"];
+        }
+        else if( p.working.minutes > 0 )
+        {
+            [string appendFormat: @"%d min%s %d sec%s",
+                p.working.minutes, p.working.minutes == 1 ? "" : "s",
+                p.working.seconds, p.working.seconds == 1 ? "" : "s"];
+        }
+        else
+        {
+            [string appendFormat: @"%d second%s",
+                p.working.seconds, p.working.seconds == 1 ? "" : "s"];
+        }
+            [string appendString: @" left)"];
+    }
+    
+    [fConvertInfoString setStringValue: string];
+    [fConvertIndicator setIndeterminate: NO];
+    [fConvertIndicator setDoubleValue: 100.0 * progress_total];
+    [self UpdateDockIcon: progress_total];
 }
 
 - (void) muxing: (NSNotification *) n
         
     [fConvertInfoString setStringValue: NSLocalizedString(@"Done.",@"Done.")];
 
-    hb_job_t * job;
-    while( ( job = hb_job( fHandle, 0 ) ) )
-    {
-        hb_rem( fHandle, job );
-    }
+    [fCore removeAllJobs];
 }
 
 @end