PageRenderTime 57ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 2ms

/macosx/Controller.m

https://github.com/griff/HandBrake
Objective C | 6731 lines | 4636 code | 972 blank | 1123 comment | 908 complexity | d7b57d2e706aa732da110d208559e42e MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, BSD-2-Clause, MIT

Large files files are truncated, but you can click here to view the full file

  1. /* $Id: Controller.mm,v 1.79 2005/11/04 19:41:32 titer Exp $
  2. This file is part of the HandBrake source code.
  3. Homepage: <http://handbrake.fr/>.
  4. It may be used under the terms of the GNU General Public License. */
  5. #include <dlfcn.h>
  6. #import "Controller.h"
  7. #import "HBOutputPanelController.h"
  8. #import "HBPreferencesController.h"
  9. #import "HBDVDDetector.h"
  10. #import "HBPresets.h"
  11. #import "HBPreviewController.h"
  12. unsigned int maximumNumberOfAllowedAudioTracks = 24;
  13. NSString *HBContainerChangedNotification = @"HBContainerChangedNotification";
  14. NSString *keyContainerTag = @"keyContainerTag";
  15. NSString *HBTitleChangedNotification = @"HBTitleChangedNotification";
  16. NSString *keyTitleTag = @"keyTitleTag";
  17. #define DragDropSimplePboardType @"MyCustomOutlineViewPboardType"
  18. /* We setup the toolbar values here ShowPreviewIdentifier */
  19. static NSString * ToggleDrawerIdentifier = @"Toggle Drawer Item Identifier";
  20. static NSString * StartEncodingIdentifier = @"Start Encoding Item Identifier";
  21. static NSString * PauseEncodingIdentifier = @"Pause Encoding Item Identifier";
  22. static NSString * ShowQueueIdentifier = @"Show Queue Item Identifier";
  23. static NSString * AddToQueueIdentifier = @"Add to Queue Item Identifier";
  24. static NSString * ShowPictureIdentifier = @"Show Picture Window Item Identifier";
  25. static NSString * ShowPreviewIdentifier = @"Show Preview Window Item Identifier";
  26. static NSString * ShowActivityIdentifier = @"Debug Output Item Identifier";
  27. static NSString * ChooseSourceIdentifier = @"Choose Source Item Identifier";
  28. /*******************************
  29. * HBController implementation *
  30. *******************************/
  31. @implementation HBController
  32. + (unsigned int) maximumNumberOfAllowedAudioTracks { return maximumNumberOfAllowedAudioTracks; }
  33. - (id)init
  34. {
  35. self = [super init];
  36. if( !self )
  37. {
  38. return nil;
  39. }
  40. /* replace bundled app icon with one which is 32/64-bit savvy */
  41. #if defined( __LP64__ )
  42. fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake-64.icns"]];
  43. #else
  44. fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake.icns"]];
  45. #endif
  46. if( fApplicationIcon != nil )
  47. [NSApp setApplicationIconImage:fApplicationIcon];
  48. [HBPreferencesController registerUserDefaults];
  49. fHandle = NULL;
  50. fQueueEncodeLibhb = NULL;
  51. /* Check for check for the app support directory here as
  52. * outputPanel needs it right away, as may other future methods
  53. */
  54. NSString *libraryDir = [NSSearchPathForDirectoriesInDomains( NSLibraryDirectory,
  55. NSUserDomainMask,
  56. YES ) objectAtIndex:0];
  57. AppSupportDirectory = [[libraryDir stringByAppendingPathComponent:@"Application Support"]
  58. stringByAppendingPathComponent:@"HandBrake"];
  59. if( ![[NSFileManager defaultManager] fileExistsAtPath:AppSupportDirectory] )
  60. {
  61. [[NSFileManager defaultManager] createDirectoryAtPath:AppSupportDirectory
  62. attributes:nil];
  63. }
  64. /* Check for and create the App Support Preview directory if necessary */
  65. NSString *PreviewDirectory = [AppSupportDirectory stringByAppendingPathComponent:@"Previews"];
  66. if( ![[NSFileManager defaultManager] fileExistsAtPath:PreviewDirectory] )
  67. {
  68. [[NSFileManager defaultManager] createDirectoryAtPath:PreviewDirectory
  69. attributes:nil];
  70. }
  71. outputPanel = [[HBOutputPanelController alloc] init];
  72. fPictureController = [[PictureController alloc] init];
  73. fQueueController = [[HBQueueController alloc] init];
  74. fAdvancedOptions = [[HBAdvancedController alloc] init];
  75. /* we init the HBPresets class which currently is only used
  76. * for updating built in presets, may move more functionality
  77. * there in the future
  78. */
  79. fPresetsBuiltin = [[HBPresets alloc] init];
  80. fPreferencesController = [[HBPreferencesController alloc] init];
  81. /* Lets report the HandBrake version number here to the activity log and text log file */
  82. NSString *versionStringFull = [[NSString stringWithFormat: @"Handbrake Version: %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
  83. [self writeToActivityLog: "%s", [versionStringFull UTF8String]];
  84. return self;
  85. }
  86. - (void) applicationDidFinishLaunching: (NSNotification *) notification
  87. {
  88. /* Init libhb with check for updates libhb style set to "0" so its ignored and lets sparkle take care of it */
  89. int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue];
  90. fHandle = hb_init(loggingLevel, 0);
  91. /* Optional dvd nav UseDvdNav*/
  92. hb_dvd_set_dvdnav([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]);
  93. /* Init a separate instance of libhb for user scanning and setting up jobs */
  94. fQueueEncodeLibhb = hb_init(loggingLevel, 0);
  95. // Set the Growl Delegate
  96. [GrowlApplicationBridge setGrowlDelegate: self];
  97. /* Init others controllers */
  98. [fPictureController SetHandle: fHandle];
  99. [fPictureController setHBController: self];
  100. [fQueueController setHandle: fQueueEncodeLibhb];
  101. [fQueueController setHBController: self];
  102. fChapterTitlesDelegate = [[ChapterTitles alloc] init];
  103. [fChapterTable setDataSource:fChapterTitlesDelegate];
  104. [fChapterTable setDelegate:fChapterTitlesDelegate];
  105. /* setup the subtitles delegate and connections to table */
  106. fSubtitlesDelegate = [[HBSubtitles alloc] init];
  107. [fSubtitlesTable setDataSource:fSubtitlesDelegate];
  108. [fSubtitlesTable setDelegate:fSubtitlesDelegate];
  109. [fSubtitlesTable setRowHeight:25.0];
  110. /* setup the audio controller */
  111. [fAudioDelegate setHBController: self];
  112. [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(autoSetM4vExtension:) name: HBMixdownChangedNotification object: nil];
  113. [fPresetsOutlineView setAutosaveName:@"Presets View"];
  114. [fPresetsOutlineView setAutosaveExpandedItems:YES];
  115. dockIconProgress = 0;
  116. /* Init QueueFile .plist */
  117. [self loadQueueFile];
  118. /* Run hbInstances to get any info on other instances as well as set the
  119. * pid number for this instance in the case of multi-instance encoding. */
  120. hbInstanceNum = [self hbInstances];
  121. /* If we are a single instance it is safe to clean up the previews if there are any
  122. * left over. This is a bit of a kludge but will prevent a build up of old instance
  123. * live preview cruft. No danger of removing an active preview directory since they
  124. * are created later in HBPreviewController if they don't exist at the moment a live
  125. * preview encode is initiated. */
  126. if (hbInstanceNum == 1)
  127. {
  128. NSString *PreviewDirectory = [NSString stringWithFormat:@"~/Library/Application Support/HandBrake/Previews"];
  129. PreviewDirectory = [PreviewDirectory stringByExpandingTildeInPath];
  130. NSError *error;
  131. NSArray *files = [ [NSFileManager defaultManager] contentsOfDirectoryAtPath: PreviewDirectory error: &error ];
  132. for( NSString *file in files )
  133. {
  134. if( file != @"." && file != @".." )
  135. {
  136. [ [NSFileManager defaultManager] removeItemAtPath: [ PreviewDirectory stringByAppendingPathComponent: file ] error: &error ];
  137. if( error )
  138. {
  139. //an error occurred...
  140. [self writeToActivityLog: "Could not remove existing preview at : %s",[file UTF8String] ];
  141. }
  142. }
  143. }
  144. }
  145. /* Call UpdateUI every 1/2 sec */
  146. [[NSRunLoop currentRunLoop] addTimer:[NSTimer
  147. scheduledTimerWithTimeInterval:0.5
  148. target:self
  149. selector:@selector(updateUI:)
  150. userInfo:nil repeats:YES]
  151. forMode:NSDefaultRunLoopMode];
  152. // Open debug output window now if it was visible when HB was closed
  153. if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"])
  154. [self showDebugOutputPanel:nil];
  155. // Open queue window now if it was visible when HB was closed
  156. if ([[NSUserDefaults standardUserDefaults] boolForKey:@"QueueWindowIsOpen"])
  157. [self showQueueWindow:nil];
  158. [self openMainWindow:nil];
  159. /* We have to set the bool to tell hb what to do after a scan
  160. * Initially we set it to NO until we start processing the queue
  161. */
  162. applyQueueToScan = NO;
  163. /* Now we re-check the queue array to see if there are
  164. * any remaining encodes to be done in it and ask the
  165. * user if they want to reload the queue */
  166. if ([QueueFileArray count] > 0)
  167. {
  168. /* run getQueueStats to see whats in the queue file */
  169. [self getQueueStats];
  170. /* this results in these values
  171. * fEncodingQueueItem = 0;
  172. * fPendingCount = 0;
  173. * fCompletedCount = 0;
  174. * fCanceledCount = 0;
  175. * fWorkingCount = 0;
  176. */
  177. /*On Screen Notification*/
  178. NSString * alertTitle;
  179. /* We check to see if there is already another instance of hb running.
  180. * Note: hbInstances == 1 means we are the only instance of HandBrake.app
  181. */
  182. if (hbInstanceNum > 1)
  183. {
  184. alertTitle = [NSString stringWithFormat:
  185. NSLocalizedString(@"There is already an instance of HandBrake running.", @"")];
  186. NSBeginCriticalAlertSheet(
  187. alertTitle,
  188. NSLocalizedString(@"Reload Queue", nil),
  189. nil,
  190. nil,
  191. fWindow, self,
  192. nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
  193. NSLocalizedString(@" HandBrake will now load up the existing queue.", nil));
  194. }
  195. else
  196. {
  197. if (fWorkingCount > 0 || fPendingCount > 0)
  198. {
  199. if (fWorkingCount > 0)
  200. {
  201. alertTitle = [NSString stringWithFormat:
  202. NSLocalizedString(@"HandBrake Has Detected %d Previously Encoding Item(s) and %d Pending Item(s) In Your Queue.", @""),
  203. fWorkingCount,fPendingCount];
  204. }
  205. else
  206. {
  207. alertTitle = [NSString stringWithFormat:
  208. NSLocalizedString(@"HandBrake Has Detected %d Pending Item(s) In Your Queue.", @""),
  209. fPendingCount];
  210. }
  211. NSBeginCriticalAlertSheet(
  212. alertTitle,
  213. NSLocalizedString(@"Reload Queue", nil),
  214. nil,
  215. NSLocalizedString(@"Empty Queue", nil),
  216. fWindow, self,
  217. nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
  218. NSLocalizedString(@" Do you want to reload them ?", nil));
  219. }
  220. else
  221. {
  222. /* Since we addressed any pending or previously encoding items above, we go ahead and make sure the queue
  223. * is empty of any finished items or cancelled items */
  224. [self clearQueueAllItems];
  225. /* We show whichever open source window specified in LaunchSourceBehavior preference key */
  226. if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
  227. {
  228. [self browseSources:nil];
  229. }
  230. if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
  231. {
  232. [self browseSources:(id)fOpenSourceTitleMMenu];
  233. }
  234. }
  235. }
  236. }
  237. else
  238. {
  239. /* We show whichever open source window specified in LaunchSourceBehavior preference key */
  240. if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
  241. {
  242. [self browseSources:nil];
  243. }
  244. if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
  245. {
  246. [self browseSources:(id)fOpenSourceTitleMMenu];
  247. }
  248. }
  249. currentQueueEncodeNameString = @"";
  250. }
  251. #pragma mark -
  252. #pragma mark Multiple Instances
  253. /* hbInstances checks to see if other instances of HB are running and also sets the pid for this instance for multi-instance queue encoding */
  254. /* Note for now since we are in early phases of multi-instance I have put in quite a bit of logging. Can be removed as we see fit. */
  255. - (int) hbInstances
  256. {
  257. /* check to see if another instance of HandBrake.app is running */
  258. NSArray *runningAppDictionaries = [[NSWorkspace sharedWorkspace] launchedApplications];
  259. NSDictionary *runningAppsDictionary;
  260. int hbInstances = 0;
  261. NSString * thisInstanceAppPath = [[NSBundle mainBundle] bundlePath];
  262. NSString * runningInstanceAppPath;
  263. int runningInstancePidNum;
  264. [self writeToActivityLog: "hbInstances path to this instance: %s", [thisInstanceAppPath UTF8String]];
  265. for (runningAppsDictionary in runningAppDictionaries)
  266. {
  267. if ([[runningAppsDictionary valueForKey:@"NSApplicationName"] isEqualToString:@"HandBrake"])
  268. {
  269. /*Report the path to each active instances app path */
  270. runningInstancePidNum = [[runningAppsDictionary valueForKey:@"NSApplicationProcessIdentifier"] intValue];
  271. runningInstanceAppPath = [runningAppsDictionary valueForKey:@"NSApplicationPath"];
  272. [self writeToActivityLog: "hbInstance found instance pidnum:%d at path: %s", runningInstancePidNum, [runningInstanceAppPath UTF8String]];
  273. /* see if this is us by comparing the app path */
  274. if ([runningInstanceAppPath isEqualToString: thisInstanceAppPath])
  275. {
  276. /* If so this is our pidnum */
  277. [self writeToActivityLog: "hbInstance MATCH FOUND, our pidnum is:%d", runningInstancePidNum];
  278. /* Get the PID number for this hb instance, used in multi instance encoding */
  279. pidNum = runningInstancePidNum;
  280. /* Report this pid to the activity log */
  281. [self writeToActivityLog: "Pid for this instance:%d", pidNum];
  282. /* Tell fQueueController what our pidNum is */
  283. [fQueueController setPidNum:pidNum];
  284. }
  285. hbInstances++;
  286. }
  287. }
  288. return hbInstances;
  289. }
  290. - (int) getPidnum
  291. {
  292. return pidNum;
  293. }
  294. #pragma mark -
  295. - (void) didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
  296. {
  297. [self writeToActivityLog: "didDimissReloadQueue number of hb instances:%d", hbInstanceNum];
  298. if (returnCode == NSAlertOtherReturn)
  299. {
  300. [self writeToActivityLog: "didDimissReloadQueue NSAlertOtherReturn Chosen"];
  301. [self clearQueueAllItems];
  302. /* We show whichever open source window specified in LaunchSourceBehavior preference key */
  303. if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
  304. {
  305. [self browseSources:nil];
  306. }
  307. if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
  308. {
  309. [self browseSources:(id)fOpenSourceTitleMMenu];
  310. }
  311. }
  312. else
  313. {
  314. [self writeToActivityLog: "didDimissReloadQueue First Button Chosen"];
  315. if (hbInstanceNum == 1)
  316. {
  317. [self setQueueEncodingItemsAsPending];
  318. }
  319. [self showQueueWindow:NULL];
  320. }
  321. }
  322. - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
  323. {
  324. hb_state_t s;
  325. hb_get_state( fQueueEncodeLibhb, &s );
  326. if ( s.state != HB_STATE_IDLE )
  327. {
  328. int result = NSRunCriticalAlertPanel(
  329. NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
  330. NSLocalizedString(@"If you quit HandBrake your current encode will be reloaded into your queue at next launch. Do you want to quit anyway?", nil),
  331. NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil, @"A movie" );
  332. if (result == NSAlertDefaultReturn)
  333. {
  334. return NSTerminateNow;
  335. }
  336. else
  337. return NSTerminateCancel;
  338. }
  339. // Warn if items still in the queue
  340. else if ( fPendingCount > 0 )
  341. {
  342. int result = NSRunCriticalAlertPanel(
  343. NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
  344. NSLocalizedString(@"There are pending encodes in your queue. Do you want to quit anyway?",nil),
  345. NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil);
  346. if ( result == NSAlertDefaultReturn )
  347. return NSTerminateNow;
  348. else
  349. return NSTerminateCancel;
  350. }
  351. return NSTerminateNow;
  352. }
  353. - (void)applicationWillTerminate:(NSNotification *)aNotification
  354. {
  355. [currentQueueEncodeNameString release];
  356. [browsedSourceDisplayName release];
  357. [outputPanel release];
  358. [fQueueController release];
  359. [fPreviewController release];
  360. [fPictureController release];
  361. [fApplicationIcon release];
  362. hb_close(&fHandle);
  363. hb_close(&fQueueEncodeLibhb);
  364. hb_global_close();
  365. }
  366. - (void) awakeFromNib
  367. {
  368. [fWindow center];
  369. [fWindow setExcludedFromWindowsMenu:NO];
  370. [fAdvancedOptions setView:fAdvancedView];
  371. /* lets setup our presets drawer for drag and drop here */
  372. [fPresetsOutlineView registerForDraggedTypes: [NSArray arrayWithObject:DragDropSimplePboardType] ];
  373. [fPresetsOutlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
  374. [fPresetsOutlineView setVerticalMotionCanBeginDrag: YES];
  375. /* Initialize currentScanCount so HB can use it to
  376. evaluate successive scans */
  377. currentScanCount = 0;
  378. /* Init UserPresets .plist */
  379. [self loadPresets];
  380. fRipIndicatorShown = NO; // initially out of view in the nib
  381. /* For 64 bit builds, the threaded animation in the progress
  382. * indicators conflicts with the animation in the advanced tab
  383. * for reasons not completely clear. jbrjake found a note in the
  384. * 10.5 dev notes regarding this possiblility. It was also noted
  385. * that unless specified, setUsesThreadedAnimation defaults to true.
  386. * So, at least for now we set the indicator animation to NO for
  387. * both the scan and regular progress indicators for both 32 and 64 bit
  388. * as it test out fine on both and there is no reason our progress indicators
  389. * should require their own thread.
  390. */
  391. [fScanIndicator setUsesThreadedAnimation:NO];
  392. [fRipIndicator setUsesThreadedAnimation:NO];
  393. /* Show/Dont Show Presets drawer upon launch based
  394. on user preference DefaultPresetsDrawerShow*/
  395. if( [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0 )
  396. {
  397. [fPresetDrawer setDelegate:self];
  398. NSSize drawerSize = NSSizeFromString( [[NSUserDefaults standardUserDefaults]
  399. stringForKey:@"Drawer Size"] );
  400. if( drawerSize.width )
  401. [fPresetDrawer setContentSize: drawerSize];
  402. [fPresetDrawer open];
  403. }
  404. /* Initially set the dvd angle widgets to hidden (dvdnav only) */
  405. [fSrcAngleLabel setHidden:YES];
  406. [fSrcAnglePopUp setHidden:YES];
  407. /* Setup the start / stop popup */
  408. [fEncodeStartStopPopUp removeAllItems];
  409. [fEncodeStartStopPopUp addItemWithTitle: @"Chapters"];
  410. [fEncodeStartStopPopUp addItemWithTitle: @"Seconds"];
  411. [fEncodeStartStopPopUp addItemWithTitle: @"Frames"];
  412. /* Align the start / stop widgets with the chapter popups */
  413. [fSrcTimeStartEncodingField setFrameOrigin:[fSrcChapterStartPopUp frame].origin];
  414. [fSrcTimeEndEncodingField setFrameOrigin:[fSrcChapterEndPopUp frame].origin];
  415. [fSrcFrameStartEncodingField setFrameOrigin:[fSrcChapterStartPopUp frame].origin];
  416. [fSrcFrameEndEncodingField setFrameOrigin:[fSrcChapterEndPopUp frame].origin];
  417. /* Destination box*/
  418. NSMenuItem *menuItem;
  419. [fDstFormatPopUp removeAllItems];
  420. // MP4 file
  421. menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"MP4 file" action: NULL keyEquivalent: @""];
  422. [menuItem setTag: HB_MUX_MP4];
  423. // MKV file
  424. menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"MKV file" action: NULL keyEquivalent: @""];
  425. [menuItem setTag: HB_MUX_MKV];
  426. [fDstFormatPopUp selectItemAtIndex: 0];
  427. [self formatPopUpChanged:nil];
  428. /* We enable the create chapters checkbox here since we are .mp4 */
  429. [fCreateChapterMarkers setEnabled: YES];
  430. if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultChapterMarkers"] > 0)
  431. {
  432. [fCreateChapterMarkers setState: NSOnState];
  433. }
  434. [fDstFile2Field setStringValue: [NSString stringWithFormat:
  435. @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
  436. /* Video encoder */
  437. [fVidEncoderPopUp removeAllItems];
  438. [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
  439. /* Video quality */
  440. [fVidTargetSizeField setIntValue: 700];
  441. [fVidBitrateField setIntValue: 1000];
  442. [fVidQualityMatrix selectCell: fVidBitrateCell];
  443. [self videoMatrixChanged:nil];
  444. /* Video framerate */
  445. [fVidRatePopUp removeAllItems];
  446. [fVidRatePopUp addItemWithTitle: NSLocalizedString( @"Same as source", @"" )];
  447. for( int i = 0; i < hb_video_rates_count; i++ )
  448. {
  449. if ([[NSString stringWithUTF8String: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.3f",23.976]])
  450. {
  451. [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
  452. [NSString stringWithUTF8String: hb_video_rates[i].string], @" (NTSC Film)"]];
  453. }
  454. else if ([[NSString stringWithUTF8String: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%d",25]])
  455. {
  456. [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
  457. [NSString stringWithUTF8String: hb_video_rates[i].string], @" (PAL Film/Video)"]];
  458. }
  459. else if ([[NSString stringWithUTF8String: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.2f",29.97]])
  460. {
  461. [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
  462. [NSString stringWithUTF8String: hb_video_rates[i].string], @" (NTSC Video)"]];
  463. }
  464. else
  465. {
  466. [fVidRatePopUp addItemWithTitle:
  467. [NSString stringWithUTF8String: hb_video_rates[i].string]];
  468. }
  469. }
  470. [fVidRatePopUp selectItemAtIndex: 0];
  471. /* Set Auto Crop to On at launch */
  472. [fPictureController setAutoCrop:YES];
  473. /* Bottom */
  474. [fStatusField setStringValue: @""];
  475. [self enableUI: NO];
  476. [self setupToolbar];
  477. /* We disable the Turbo 1st pass checkbox since we are not x264 */
  478. [fVidTurboPassCheck setEnabled: NO];
  479. [fVidTurboPassCheck setState: NSOffState];
  480. /* lets get our default prefs here */
  481. [self getDefaultPresets:nil];
  482. /* lets initialize the current successful scancount here to 0 */
  483. currentSuccessfulScanCount = 0;
  484. }
  485. - (void) enableUI: (bool) b
  486. {
  487. NSControl * controls[] =
  488. { fSrcTitleField, fSrcTitlePopUp,
  489. fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField,
  490. fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field,
  491. fDstFormatField, fDstFormatPopUp, fDstFile1Field, fDstFile2Field,
  492. fDstBrowseButton, fVidRateField, fVidRatePopUp,fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
  493. fPictureSizeField,fPictureCroppingField, fVideoFiltersField,fVidQualityMatrix, fSubField, fSubPopUp,
  494. fQueueStatus,fPresetsAdd,fPresetsDelete,fSrcAngleLabel,fSrcAnglePopUp,
  495. fCreateChapterMarkers,fVidTurboPassCheck,fDstMp4LargeFileCheck,fSubForcedCheck,fPresetsOutlineView,
  496. fDstMp4HttpOptFileCheck,fDstMp4iPodFileCheck,fVidQualityRFField,fVidQualityRFLabel,
  497. fEncodeStartStopPopUp,fSrcTimeStartEncodingField,fSrcTimeEndEncodingField,fSrcFrameStartEncodingField,
  498. fSrcFrameEndEncodingField, fLoadChaptersButton, fSaveChaptersButton, fFrameratePfrCheck};
  499. for( unsigned i = 0;
  500. i < sizeof( controls ) / sizeof( NSControl * ); i++ )
  501. {
  502. if( [[controls[i] className] isEqualToString: @"NSTextField"] )
  503. {
  504. NSTextField * tf = (NSTextField *) controls[i];
  505. if( ![tf isBezeled] )
  506. {
  507. [tf setTextColor: b ? [NSColor controlTextColor] :
  508. [NSColor disabledControlTextColor]];
  509. continue;
  510. }
  511. }
  512. [controls[i] setEnabled: b];
  513. }
  514. if (b)
  515. {
  516. /* we also call calculatePictureSizing here to sense check if we already have vfr selected */
  517. [self calculatePictureSizing:nil];
  518. /* Also enable the preview window hud controls */
  519. [fPictureController enablePreviewHudControls];
  520. }
  521. else
  522. {
  523. [fPresetsOutlineView setEnabled: NO];
  524. [fPictureController disablePreviewHudControls];
  525. }
  526. [self videoMatrixChanged:nil];
  527. [fAdvancedOptions enableUI:b];
  528. }
  529. /***********************************************************************
  530. * UpdateDockIcon
  531. ***********************************************************************
  532. * Shows a progression bar on the dock icon, filled according to
  533. * 'progress' (0.0 <= progress <= 1.0).
  534. * Called with progress < 0.0 or progress > 1.0, restores the original
  535. * icon.
  536. **********************************************************************/
  537. - (void) UpdateDockIcon: (float) progress
  538. {
  539. NSData * tiff;
  540. NSBitmapImageRep * bmp;
  541. uint32_t * pen;
  542. uint32_t black = htonl( 0x000000FF );
  543. uint32_t red = htonl( 0xFF0000FF );
  544. uint32_t white = htonl( 0xFFFFFFFF );
  545. int row_start, row_end;
  546. int i, j;
  547. if( progress < 0.0 || progress > 1.0 )
  548. {
  549. [NSApp setApplicationIconImage: fApplicationIcon];
  550. return;
  551. }
  552. /* Get it in a raw bitmap form */
  553. tiff = [fApplicationIcon TIFFRepresentationUsingCompression:
  554. NSTIFFCompressionNone factor: 1.0];
  555. bmp = [NSBitmapImageRep imageRepWithData: tiff];
  556. /* Draw the progression bar */
  557. /* It's pretty simple (ugly?) now, but I'm no designer */
  558. row_start = 3 * (int) [bmp size].height / 4;
  559. row_end = 7 * (int) [bmp size].height / 8;
  560. for( i = row_start; i < row_start + 2; i++ )
  561. {
  562. pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
  563. for( j = 0; j < (int) [bmp size].width; j++ )
  564. {
  565. pen[j] = black;
  566. }
  567. }
  568. for( i = row_start + 2; i < row_end - 2; i++ )
  569. {
  570. pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
  571. pen[0] = black;
  572. pen[1] = black;
  573. for( j = 2; j < (int) [bmp size].width - 2; j++ )
  574. {
  575. if( j < 2 + (int) ( ( [bmp size].width - 4.0 ) * progress ) )
  576. {
  577. pen[j] = red;
  578. }
  579. else
  580. {
  581. pen[j] = white;
  582. }
  583. }
  584. pen[j] = black;
  585. pen[j+1] = black;
  586. }
  587. for( i = row_end - 2; i < row_end; i++ )
  588. {
  589. pen = (uint32_t *) ( [bmp bitmapData] + i * [bmp bytesPerRow] );
  590. for( j = 0; j < (int) [bmp size].width; j++ )
  591. {
  592. pen[j] = black;
  593. }
  594. }
  595. /* Now update the dock icon */
  596. tiff = [bmp TIFFRepresentationUsingCompression:
  597. NSTIFFCompressionNone factor: 1.0];
  598. NSImage* icon = [[NSImage alloc] initWithData: tiff];
  599. [NSApp setApplicationIconImage: icon];
  600. [icon release];
  601. }
  602. - (void) updateUI: (NSTimer *) timer
  603. {
  604. /* Update UI for fHandle (user scanning instance of libhb ) */
  605. hb_list_t * list;
  606. list = hb_get_titles( fHandle );
  607. /* check to see if there has been a new scan done
  608. this bypasses the constraints of HB_STATE_WORKING
  609. not allowing setting a newly scanned source */
  610. int checkScanCount = hb_get_scancount( fHandle );
  611. if( checkScanCount > currentScanCount )
  612. {
  613. currentScanCount = checkScanCount;
  614. [fScanIndicator setIndeterminate: NO];
  615. [fScanIndicator setDoubleValue: 0.0];
  616. [fScanIndicator setHidden: YES];
  617. [self showNewScan:nil];
  618. }
  619. hb_state_t s;
  620. hb_get_state( fHandle, &s );
  621. switch( s.state )
  622. {
  623. case HB_STATE_IDLE:
  624. break;
  625. #define p s.param.scanning
  626. case HB_STATE_SCANNING:
  627. {
  628. [fSrcDVD2Field setStringValue: [NSString stringWithFormat:
  629. NSLocalizedString( @"Scanning title %d of %d...", @"" ),
  630. p.title_cur, p.title_count]];
  631. [fScanIndicator setHidden: NO];
  632. [fScanIndicator setDoubleValue: 100.0 * ((double)( p.title_cur - 1 ) / p.title_count)];
  633. break;
  634. }
  635. #undef p
  636. #define p s.param.scandone
  637. case HB_STATE_SCANDONE:
  638. {
  639. [fScanIndicator setIndeterminate: NO];
  640. [fScanIndicator setDoubleValue: 0.0];
  641. [fScanIndicator setHidden: YES];
  642. [self writeToActivityLog:"ScanDone state received from fHandle"];
  643. [self showNewScan:nil];
  644. [[fWindow toolbar] validateVisibleItems];
  645. break;
  646. }
  647. #undef p
  648. #define p s.param.working
  649. case HB_STATE_WORKING:
  650. {
  651. break;
  652. }
  653. #undef p
  654. #define p s.param.muxing
  655. case HB_STATE_MUXING:
  656. {
  657. break;
  658. }
  659. #undef p
  660. case HB_STATE_PAUSED:
  661. break;
  662. case HB_STATE_WORKDONE:
  663. {
  664. break;
  665. }
  666. }
  667. /* Update UI for fQueueEncodeLibhb */
  668. // hb_list_t * list;
  669. // list = hb_get_titles( fQueueEncodeLibhb ); //fQueueEncodeLibhb
  670. /* check to see if there has been a new scan done
  671. this bypasses the constraints of HB_STATE_WORKING
  672. not allowing setting a newly scanned source */
  673. checkScanCount = hb_get_scancount( fQueueEncodeLibhb );
  674. if( checkScanCount > currentScanCount )
  675. {
  676. currentScanCount = checkScanCount;
  677. }
  678. //hb_state_t s;
  679. hb_get_state( fQueueEncodeLibhb, &s );
  680. switch( s.state )
  681. {
  682. case HB_STATE_IDLE:
  683. break;
  684. #define p s.param.scanning
  685. case HB_STATE_SCANNING:
  686. {
  687. [fStatusField setStringValue: [NSString stringWithFormat:
  688. NSLocalizedString( @"Queue Scanning title %d of %d...", @"" ),
  689. p.title_cur, p.title_count]];
  690. /* Set the status string in fQueueController as well */
  691. [fQueueController setQueueStatusString: [NSString stringWithFormat:
  692. NSLocalizedString( @"Queue Scanning title %d of %d...", @"" ),
  693. p.title_cur, p.title_count]];
  694. break;
  695. }
  696. #undef p
  697. #define p s.param.scandone
  698. case HB_STATE_SCANDONE:
  699. {
  700. [self writeToActivityLog:"ScanDone state received from fQueueEncodeLibhb"];
  701. [self processNewQueueEncode];
  702. [[fWindow toolbar] validateVisibleItems];
  703. break;
  704. }
  705. #undef p
  706. #define p s.param.working
  707. case HB_STATE_SEARCHING:
  708. {
  709. NSMutableString * string;
  710. NSString * pass_desc;
  711. /* Update text field */
  712. pass_desc = @"";
  713. //string = [NSMutableString stringWithFormat: NSLocalizedString( @"Searching for start point: pass %d %@ of %d, %.2f %%", @"" ), p.job_cur, pass_desc, p.job_count, 100.0 * p.progress];
  714. /* For now, do not announce "pass x of x for the search phase ... */
  715. string = [NSMutableString stringWithFormat: NSLocalizedString( @"Searching for start point ... : %.2f %%", @"" ), 100.0 * p.progress];
  716. if( p.seconds > -1 )
  717. {
  718. [string appendFormat:
  719. NSLocalizedString( @" (ETA %02dh%02dm%02ds)", @"" ), p.hours, p.minutes, p.seconds];
  720. }
  721. [fStatusField setStringValue: string];
  722. /* Set the status string in fQueueController as well */
  723. [fQueueController setQueueStatusString: string];
  724. /* Update slider */
  725. CGFloat progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
  726. [fRipIndicator setIndeterminate: NO];
  727. [fRipIndicator setDoubleValue:100.0 * progress_total];
  728. // If progress bar hasn't been revealed at the bottom of the window, do
  729. // that now. This code used to be in doRip. I moved it to here to handle
  730. // the case where hb_start is called by HBQueueController and not from
  731. // HBController.
  732. if( !fRipIndicatorShown )
  733. {
  734. NSRect frame = [fWindow frame];
  735. if( frame.size.width <= 591 )
  736. frame.size.width = 591;
  737. frame.size.height += 36;
  738. frame.origin.y -= 36;
  739. [fWindow setFrame:frame display:YES animate:YES];
  740. fRipIndicatorShown = YES;
  741. }
  742. /* Update dock icon */
  743. /* Note not done yet */
  744. break;
  745. }
  746. case HB_STATE_WORKING:
  747. {
  748. NSMutableString * string;
  749. NSString * pass_desc;
  750. /* Update text field */
  751. if (p.job_cur == 1 && p.job_count > 1)
  752. {
  753. if ([[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SubtitleList"] && [[[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex]objectForKey:@"SubtitleList"] objectAtIndex:0] objectForKey:@"subtitleSourceTrackNum"] intValue] == 1)
  754. {
  755. pass_desc = @"(subtitle scan)";
  756. }
  757. else
  758. {
  759. pass_desc = @"";
  760. }
  761. }
  762. else
  763. {
  764. pass_desc = @"";
  765. }
  766. string = [NSMutableString stringWithFormat: NSLocalizedString( @"Encoding: %@ \nPass %d %@ of %d, %.2f %%", @"" ), currentQueueEncodeNameString, p.job_cur, pass_desc, p.job_count, 100.0 * p.progress];
  767. if( p.seconds > -1 )
  768. {
  769. [string appendFormat:
  770. NSLocalizedString( @" (%.2f fps, avg %.2f fps, ETA %02dh%02dm%02ds)", @"" ),
  771. p.rate_cur, p.rate_avg, p.hours, p.minutes, p.seconds];
  772. }
  773. [fStatusField setStringValue: string];
  774. [fQueueController setQueueStatusString:string];
  775. /* Update slider */
  776. CGFloat progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
  777. [fRipIndicator setIndeterminate: NO];
  778. [fRipIndicator setDoubleValue:100.0 * progress_total];
  779. // If progress bar hasn't been revealed at the bottom of the window, do
  780. // that now. This code used to be in doRip. I moved it to here to handle
  781. // the case where hb_start is called by HBQueueController and not from
  782. // HBController.
  783. if( !fRipIndicatorShown )
  784. {
  785. NSRect frame = [fWindow frame];
  786. if( frame.size.width <= 591 )
  787. frame.size.width = 591;
  788. frame.size.height += 36;
  789. frame.origin.y -= 36;
  790. [fWindow setFrame:frame display:YES animate:YES];
  791. fRipIndicatorShown = YES;
  792. }
  793. /* Update dock icon */
  794. if( dockIconProgress < 100.0 * progress_total )
  795. {
  796. [self UpdateDockIcon: progress_total];
  797. dockIconProgress += 5;
  798. }
  799. break;
  800. }
  801. #undef p
  802. #define p s.param.muxing
  803. case HB_STATE_MUXING:
  804. {
  805. /* Update text field */
  806. [fStatusField setStringValue: NSLocalizedString( @"Muxing...", @"" )];
  807. /* Set the status string in fQueueController as well */
  808. [fQueueController setQueueStatusString: NSLocalizedString( @"Muxing...", @"" )];
  809. /* Update slider */
  810. [fRipIndicator setIndeterminate: YES];
  811. [fRipIndicator startAnimation: nil];
  812. /* Update dock icon */
  813. [self UpdateDockIcon: 1.0];
  814. break;
  815. }
  816. #undef p
  817. case HB_STATE_PAUSED:
  818. [fStatusField setStringValue: NSLocalizedString( @"Paused", @"" )];
  819. [fQueueController setQueueStatusString: NSLocalizedString( @"Paused", @"" )];
  820. break;
  821. case HB_STATE_WORKDONE:
  822. {
  823. // HB_STATE_WORKDONE happpens as a result of libhb finishing all its jobs
  824. // or someone calling hb_stop. In the latter case, hb_stop does not clear
  825. // out the remaining passes/jobs in the queue. We'll do that here.
  826. // Delete all remaining jobs of this encode.
  827. [fStatusField setStringValue: NSLocalizedString( @"Encode Finished.", @"" )];
  828. /* Set the status string in fQueueController as well */
  829. [fQueueController setQueueStatusString: NSLocalizedString( @"Encode Finished.", @"" )];
  830. [fRipIndicator setIndeterminate: NO];
  831. [fRipIndicator stopAnimation: nil];
  832. [fRipIndicator setDoubleValue: 0.0];
  833. [[fWindow toolbar] validateVisibleItems];
  834. /* Restore dock icon */
  835. [self UpdateDockIcon: -1.0];
  836. dockIconProgress = 0;
  837. if( fRipIndicatorShown )
  838. {
  839. NSRect frame = [fWindow frame];
  840. if( frame.size.width <= 591 )
  841. frame.size.width = 591;
  842. frame.size.height += -36;
  843. frame.origin.y -= -36;
  844. [fWindow setFrame:frame display:YES animate:YES];
  845. fRipIndicatorShown = NO;
  846. }
  847. /* Since we are done with this encode, tell output to stop writing to the
  848. * individual encode log
  849. */
  850. [outputPanel endEncodeLog];
  851. /* Check to see if the encode state has not been cancelled
  852. to determine if we should check for encode done notifications */
  853. if( fEncodeState != 2 )
  854. {
  855. NSString *pathOfFinishedEncode;
  856. /* Get the output file name for the finished encode */
  857. pathOfFinishedEncode = [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"];
  858. /* Both the Growl Alert and Sending to MetaX can be done as encodes roll off the queue */
  859. if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Growl Notification"] ||
  860. [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"])
  861. {
  862. /* If Play System Alert has been selected in Preferences */
  863. if( [[NSUserDefaults standardUserDefaults] boolForKey:@"AlertWhenDoneSound"] == YES )
  864. {
  865. NSBeep();
  866. }
  867. [self showGrowlDoneNotification:pathOfFinishedEncode];
  868. }
  869. /* Send to MetaX */
  870. [self sendToMetaX:pathOfFinishedEncode];
  871. /* since we have successfully completed an encode, we increment the queue counter */
  872. [self incrementQueueItemDone:currentQueueEncodeIndex];
  873. }
  874. break;
  875. }
  876. }
  877. /* Since we can use multiple instance off of the same queue file it is imperative that we keep the QueueFileArray updated off of the QueueFile.plist
  878. * so we go ahead and do it in this existing timer as opposed to using a new one */
  879. NSMutableArray * tempQueueArray = [[NSMutableArray alloc] initWithContentsOfFile:QueueFile];
  880. [QueueFileArray setArray:tempQueueArray];
  881. [tempQueueArray release];
  882. /* Send Fresh QueueFileArray to fQueueController to update queue window */
  883. [fQueueController setQueueArray: QueueFileArray];
  884. [self getQueueStats];
  885. }
  886. /* We use this to write messages to stderr from the macgui which show up in the activity window and log*/
  887. - (void) writeToActivityLog:(const char *) format, ...
  888. {
  889. va_list args;
  890. va_start(args, format);
  891. if (format != nil)
  892. {
  893. char str[1024];
  894. vsnprintf( str, 1024, format, args );
  895. time_t _now = time( NULL );
  896. struct tm * now = localtime( &_now );
  897. fprintf(stderr, "[%02d:%02d:%02d] macgui: %s\n", now->tm_hour, now->tm_min, now->tm_sec, str );
  898. }
  899. va_end(args);
  900. }
  901. #pragma mark -
  902. #pragma mark Toolbar
  903. // ============================================================
  904. // NSToolbar Related Methods
  905. // ============================================================
  906. - (void) setupToolbar {
  907. NSToolbar *toolbar = [[[NSToolbar alloc] initWithIdentifier: @"HandBrake Toolbar"] autorelease];
  908. [toolbar setAllowsUserCustomization: YES];
  909. [toolbar setAutosavesConfiguration: YES];
  910. [toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
  911. [toolbar setDelegate: self];
  912. [fWindow setToolbar: toolbar];
  913. }
  914. - (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier:
  915. (NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted {
  916. NSToolbarItem * item = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease];
  917. if ([itemIdent isEqualToString: ToggleDrawerIdentifier])
  918. {
  919. [item setLabel: @"Toggle Presets"];
  920. [item setPaletteLabel: @"Toggler Presets"];
  921. [item setToolTip: @"Open/Close Preset Drawer"];
  922. [item setImage: [NSImage imageNamed: @"Drawer"]];
  923. [item setTarget: self];
  924. [item setAction: @selector(toggleDrawer:)];
  925. [item setAutovalidates: NO];
  926. }
  927. else if ([itemIdent isEqualToString: StartEncodingIdentifier])
  928. {
  929. [item setLabel: @"Start"];
  930. [item setPaletteLabel: @"Start Encoding"];
  931. [item setToolTip: @"Start Encoding"];
  932. [item setImage: [NSImage imageNamed: @"Play"]];
  933. [item setTarget: self];
  934. [item setAction: @selector(Rip:)];
  935. }
  936. else if ([itemIdent isEqualToString: ShowQueueIdentifier])
  937. {
  938. [item setLabel: @"Show Queue"];
  939. [item setPaletteLabel: @"Show Queue"];
  940. [item setToolTip: @"Show Queue"];
  941. [item setImage: [NSImage imageNamed: @"Queue"]];
  942. [item setTarget: self];
  943. [item setAction: @selector(showQueueWindow:)];
  944. [item setAutovalidates: NO];
  945. }
  946. else if ([itemIdent isEqualToString: AddToQueueIdentifier])
  947. {
  948. [item setLabel: @"Add to Queue"];
  949. [item setPaletteLabel: @"Add to Queue"];
  950. [item setToolTip: @"Add to Queue"];
  951. [item setImage: [NSImage imageNamed: @"AddToQueue"]];
  952. [item setTarget: self];
  953. [item setAction: @selector(addToQueue:)];
  954. }
  955. else if ([itemIdent isEqualToString: PauseEncodingIdentifier])
  956. {
  957. [item setLabel: @"Pause"];
  958. [item setPaletteLabel: @"Pause Encoding"];
  959. [item setToolTip: @"Pause Encoding"];
  960. [item setImage: [NSImage imageNamed: @"Pause"]];
  961. [item setTarget: self];
  962. [item setAction: @selector(Pause:)];
  963. }
  964. else if ([itemIdent isEqualToString: ShowPictureIdentifier])
  965. {
  966. [item setLabel: @"Picture Settings"];
  967. [item setPaletteLabel: @"Show Picture Settings"];
  968. [item setToolTip: @"Show Picture Settings"];
  969. [item setImage: [NSImage imageNamed: @"pref-picture"]];
  970. [item setTarget: self];
  971. [item setAction: @selector(showPicturePanel:)];
  972. }
  973. else if ([itemIdent isEqualToString: ShowPreviewIdentifier])
  974. {
  975. [item setLabel: @"Preview Window"];
  976. [item setPaletteLabel: @"Show Preview"];
  977. [item setToolTip: @"Show Preview"];
  978. //[item setImage: [NSImage imageNamed: @"pref-picture"]];
  979. [item setImage: [NSImage imageNamed: @"Brushed_Window"]];
  980. [item setTarget: self];
  981. [item setAction: @selector(showPreviewWindow:)];
  982. }
  983. else if ([itemIdent isEqualToString: ShowActivityIdentifier])
  984. {
  985. [item setLabel: @"Activity Window"];
  986. [item setPaletteLabel: @"Show Activity Window"];
  987. [item setToolTip: @"Show Activity Window"];
  988. [item setImage: [NSImage imageNamed: @"ActivityWindow"]];
  989. [item setTarget: self];
  990. [item setAction: @selector(showDebugOutputPanel:)];
  991. [item setAutovalidates: NO];
  992. }
  993. else if ([itemIdent isEqualToString: ChooseSourceIdentifier])
  994. {
  995. [item setLabel: @"Source"];
  996. [item setPaletteLabel: @"Source"];
  997. [item setToolTip: @"Choose Video Source"];
  998. [item setImage: [NSImage imageNamed: @"Source"]];
  999. [item setTarget: self];
  1000. [item setAction: @selector(browseSources:)];
  1001. }
  1002. else
  1003. {
  1004. return nil;
  1005. }
  1006. return item;
  1007. }
  1008. - (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
  1009. {
  1010. return [NSArray arrayWithObjects: ChooseSourceIdentifier, NSToolbarSeparatorItemIdentifier, StartEncodingIdentifier,
  1011. PauseEncodingIdentifier, AddToQueueIdentifier, ShowQueueIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
  1012. NSToolbarSpaceItemIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
  1013. }
  1014. - (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
  1015. {
  1016. return [NSArray arrayWithObjects: StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier,
  1017. ChooseSourceIdentifier, ShowQueueIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
  1018. NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
  1019. NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
  1020. }
  1021. - (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem
  1022. {
  1023. NSString * ident = [toolbarItem itemIdentifier];
  1024. if (fHandle)
  1025. {
  1026. hb_state_t s;
  1027. hb_get_state( fHandle, &s );
  1028. if (s.state == HB_STATE_SCANNING)
  1029. {
  1030. if ([ident isEqualToString: ChooseSourceIdentifier])
  1031. {
  1032. [toolbarItem setImage: [NSImage imageNamed: @"Stop"]];
  1033. [toolbarItem setLabel: @"Cancel Scan"];
  1034. [toolbarItem setPaletteLabel: @"Cancel Scanning"];
  1035. [toolbarItem setToolTip: @"Cancel Scanning Source"];
  1036. return YES;
  1037. }
  1038. if ([ident isEqualToString: StartEncodingIdentifier] || [ident isEqualToString: AddToQueueIdentifier])
  1039. return NO;
  1040. }
  1041. else
  1042. {
  1043. if ([ident isEqualToString: ChooseSourceIdentifier])
  1044. {
  1045. [toolbarItem setImage: [NSImage imageNamed: @"Source"]];
  1046. [toolbarItem setLabel: @"Source"];
  1047. [toolbarItem setPaletteLabel: @"Source"];
  1048. [toolbarItem setToolTip: @"Choose Video Source"];
  1049. return YES;
  1050. }
  1051. }
  1052. hb_get_state2( fQueueEncodeLibhb, &s );
  1053. if (s.state == HB_STATE_WORKING || s.state == HB_STATE_SEARCHING || s.state == HB_STATE_MUXING)
  1054. {
  1055. if ([ident isEqualToString: StartEncodingIdentifier])
  1056. {
  1057. [toolbarItem setImage: [NSImage imageNamed: @"Stop"]];
  1058. [toolbarItem setLabel: @"Stop"];
  1059. [toolbarItem setPaletteLabel: @"Stop"];
  1060. [toolbarItem setToolTip: @"Stop Encoding"];
  1061. return YES;
  1062. }
  1063. if ([ident isEqualToString: PauseEncodingIdentifie

Large files files are truncated, but you can click here to view the full file