summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
authorRodeo <[email protected]>2012-09-21 20:25:24 +0000
committerRodeo <[email protected]>2012-09-21 20:25:24 +0000
commita128ed16e74d4afaf135d4fff7e41688930f53cb (patch)
treeec600e17a40fc7e36e6392f33a2e9fe66d6adfa2 /macosx
parent9b3ab50a16042a2be298d15549cf30cbbc28f1c5 (diff)
MacGui: Add the drag & drop features on both DockIcon and Handbrake Main Window
- Patch courtesy of Jerome Lacube. Thanks Jerome! - It handles dragging & dropping one file, and folders. -- Please note that when dropping a folder, the files inside will be treated as titles. - Specifics can be found here https://reviews.handbrake.fr/r/345/ git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4973 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'macosx')
-rw-r--r--macosx/Controller.h9
-rw-r--r--macosx/Controller.m192
-rw-r--r--macosx/Info.plist.m413
3 files changed, 202 insertions, 12 deletions
diff --git a/macosx/Controller.h b/macosx/Controller.h
index c8eb322bb..ddc52880f 100644
--- a/macosx/Controller.h
+++ b/macosx/Controller.h
@@ -259,6 +259,8 @@ BOOL fIsDragging;
/* Dock progress variables */
double dockIconProgress;
+
+ BOOL fWillScan;
NSDockTile *dockTile;
DockTextField *percentField;
DockTextField *timeField;
@@ -446,7 +448,12 @@ BOOL fIsDragging;
+ (unsigned int) maximumNumberOfAllowedAudioTracks;
- (IBAction) addAllAudioTracks: (id) sender;
-- (void) updateDockIcon:(double)progress withETA:(NSString*)etaStr;
+// Drag & Drop methods
+- (void)openFiles:(NSArray*)filenames;
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
+- (void) updateDockIcon:(double)progress withETA:(NSString*)etaStr;
@end
diff --git a/macosx/Controller.m b/macosx/Controller.m
index 324d9ae4a..6b500ab19 100644
--- a/macosx/Controller.m
+++ b/macosx/Controller.m
@@ -19,6 +19,8 @@ NSString *keyContainerTag = @"keyContainerTag";
NSString *HBTitleChangedNotification = @"HBTitleChangedNotification";
NSString *keyTitleTag = @"keyTitleTag";
+NSString *dragDropFiles= @"dragDropFiles";
+
#define DragDropSimplePboardType @"MyCustomOutlineViewPboardType"
NSString *dockTilePercentFormat = @"%2.1f%%";
@@ -119,6 +121,63 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
return self;
}
+// This method is triggered at launch (and every launch) whether or not
+// files have been dragged on to the dockTile. As a consequence, [self openFiles]
+// contains the logic to detect the case when no files has been drop on the dock
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
+{
+ [self openFiles:filenames];
+
+ [NSApp replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
+}
+
+- (void)openFiles:(NSArray*)filenames
+{
+ if (filenames.count == 1 && [[filenames objectAtIndex:0] isEqual:@"YES"])
+ return;
+
+ NSMutableArray* filesList = [[NSMutableArray alloc] initWithArray:filenames];
+ [filesList removeObject:@"YES"];
+
+ // For now, we just want to accept one file at a time
+ // If for any reason, more than one file is submitted, we will take the first one
+ if (filesList.count > 1) {
+ filesList = [NSMutableArray arrayWithObject:[filesList objectAtIndex:0]];
+ }
+
+ // The goal of this check is to know if the application was running before the drag & drop
+ // if fSubtitlesDelegate is set, then applicationDidFinishLaunching was called
+ if (fSubtitlesDelegate)
+ {
+ // Handbrake was already running when the user dropped the file(s)
+ // So we get unstack the first one and launch the scan
+ // The other ones remain in the UserDefaults, and will be handled in the updateUI method
+ // when Handbrake is idle
+ id firstItem = [filesList objectAtIndex:0];
+ [filesList removeObjectAtIndex:0];
+
+ // This variable has only one goal, let the updateUI knows that even if idling
+ // maybe a scan is in preparation
+ fWillScan = YES;
+
+ if (filesList.count > 0)
+ {
+ [[NSUserDefaults standardUserDefaults] setObject:filesList forKey:dragDropFiles];
+ } else {
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles];
+ }
+
+ [browsedSourceDisplayName release];
+ browsedSourceDisplayName = [[firstItem lastPathComponent] retain];
+ [self performScan:firstItem scanTitleNum:0];
+ } else {
+ // Handbrake was not running before the user dropped the file(s)
+ // So we save the file(s) list in the UserDefaults and we will read them
+ // in the applicationDidFinishLaunching method
+ [[NSUserDefaults standardUserDefaults] setObject:filesList forKey:dragDropFiles];
+ }
+}
+
- (void) applicationDidFinishLaunching: (NSNotification *) notification
{
/* Init libhb with check for updates libhb style set to "0" so its ignored and lets sparkle take care of it */
@@ -216,6 +275,9 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
*/
applyQueueToScan = NO;
+ // We try to get the list of filenames that may have been drag & drop before the application was running
+ id dragDropFilesId = [[NSUserDefaults standardUserDefaults] objectForKey:dragDropFiles];
+
/* Now we re-check the queue array to see if there are
* any remaining encodes to be done in it and ask the
* user if they want to reload the queue */
@@ -275,26 +337,47 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
fWindow, self,
nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
NSLocalizedString(@" Do you want to reload them ?", nil));
+
+ // After handling the previous queue (reload or empty), if there is files waiting for scanning
+ // we will process them
+ if (dragDropFilesId)
+ {
+ NSArray *dragDropFiles = (NSArray *)dragDropFilesId;
+ [self openFiles:dragDropFiles];
+ }
}
else
{
- /* Since we addressed any pending or previously encoding items above, we go ahead and make sure the queue
- * is empty of any finished items or cancelled items */
- [self clearQueueAllItems];
- /* We show whichever open source window specified in LaunchSourceBehavior preference key */
- if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
+ // We will open the source window only if there is no dropped files waiting to be scanned
+ if (dragDropFilesId)
{
- [self browseSources:nil];
- }
+ NSArray *dragDropFiles = (NSArray *)dragDropFilesId;
+ [self openFiles:dragDropFiles];
+ } else {
+ /* Since we addressed any pending or previously encoding items above, we go ahead and make sure
+ * the queue is empty of any finished items or cancelled items */
+ [self clearQueueAllItems];
+ /* We show whichever open source window specified in LaunchSourceBehavior preference key */
+ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
+ {
+ [self browseSources:nil];
+ }
- if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
- {
- [self browseSources:(id)fOpenSourceTitleMMenu];
+ if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
+ {
+ [self browseSources:(id)fOpenSourceTitleMMenu];
+ }
}
}
}
}
+ // We will open the source window only if there is no dropped files waiting to be scanned
+ else if (dragDropFilesId)
+ {
+ NSArray *dragDropFiles = (NSArray *)dragDropFilesId;
+ [self openFiles:dragDropFiles];
+ }
else
{
/* We show whichever open source window specified in LaunchSourceBehavior preference key */
@@ -359,6 +442,45 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
}
#pragma mark -
+#pragma mark Drag & drop handling
+
+// This method is used by OSX to know what kind of files can be drag & drop on the NSWindow
+// We only want filenames (and so folders too)
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
+ NSPasteboard *pboard = [sender draggingPasteboard];
+
+ if ([[pboard types] containsObject:NSFilenamesPboardType]) {
+ NSArray *paths = [pboard propertyListForType:NSFilenamesPboardType];
+
+ return paths.count == 1 ? NSDragOperationGeneric : NSDragOperationNone;
+ }
+
+ return NSDragOperationNone;
+}
+
+// This method is doing the job after the drag & drop operation has been validated by [self draggingEntered] and OSX
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
+ NSPasteboard *pboard;
+
+ pboard = [sender draggingPasteboard];
+
+ if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
+ NSArray *paths = [pboard propertyListForType:NSFilenamesPboardType];
+
+ if (paths.count > 0) {
+ // For now, we just want to accept one file at a time
+ // If for any reason, more than one file is submitted, we will take the first one
+ NSArray *reducedPaths = [NSArray arrayWithObject:[paths objectAtIndex:0]];
+ paths = reducedPaths;
+ }
+
+ [self openFiles:paths];
+ }
+
+ return YES;
+}
+
+#pragma mark -
- (void) didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
{
@@ -433,6 +555,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
+ // When the application is closed and we still have some files in the dragDropFiles array
+ // it's highly probable that the user throw a lot of files and just want to reset this
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles];
+
[currentQueueEncodeNameString release];
[browsedSourceDisplayName release];
[outputPanel release];
@@ -600,6 +726,9 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
[self getDefaultPresets:nil];
/* lets initialize the current successful scancount here to 0 */
currentSuccessfulScanCount = 0;
+
+ /* Register HBController's Window as a receiver for files/folders drag & drop operations */
+ [fWindow registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
}
- (void) enableUI: (bool) b
@@ -1049,7 +1178,45 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
{
[fAudioAutoPassthruBox setHidden:YES];
}
+
+ // Finally after all UI updates, we look for a next dragDropItem to scan
+ // fWillScan will signal that a scan will be launched, so we need to wait
+ // the next idle cycle after the scan
+ hb_get_state( fHandle, &s );
+ if (s.state == HB_STATE_IDLE && !fWillScan)
+ {
+ // Continue to loop on the other drag & drop files if any
+ if ([[NSUserDefaults standardUserDefaults] objectForKey:dragDropFiles])
+ {
+ NSMutableArray *filesList = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:dragDropFiles]];
+
+ if (filesList.count > 0)
+ {
+ // We need to add the previous scan file into the queue (without doing the usual checks)
+ // Before scanning the new one
+ [self doAddToQueue];
+
+ id nextItem = [filesList objectAtIndex:0];
+ [filesList removeObjectAtIndex:0];
+
+ [browsedSourceDisplayName release];
+ browsedSourceDisplayName = [[((NSString*)nextItem) lastPathComponent] retain];
+ [self performScan:nextItem scanTitleNum:0];
+
+ if (filesList.count > 0)
+ {
+ // Updating the list in the user defaults
+ [[NSUserDefaults standardUserDefaults] setObject:filesList forKey:dragDropFiles];
+ } else {
+ // Cleaning if last one was treated
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles];
+ }
+ } else {
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey:dragDropFiles];
+ }
+ }
+ }
}
/* We use this to write messages to stderr from the macgui which show up in the activity window and log*/
@@ -1690,7 +1857,6 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
/* Here we actually tell hb_scan to perform the source scan, using the path to source and title number*/
- (void) performScan:(NSString *) scanPath scanTitleNum: (int) scanTitleNum
{
-
/* use a bool to determine whether or not we can decrypt using vlc */
BOOL cancelScanDecrypt = 0;
BOOL vlcFound = 0;
@@ -1789,6 +1955,10 @@ static NSString * ChooseSourceIdentifier = @"Choose Source It
}
hb_scan( fHandle, [path UTF8String], scanTitleNum, hb_num_previews, 1 , min_title_duration_ticks );
[fSrcDVD2Field setStringValue:@"Scanning new sourceā€¦"];
+
+ // After the scan process, we signal to enableUI loop that this scan process is now finished
+ // If remaining drag & drop files are in the UserDefaults array, they will then be processed
+ fWillScan = NO;
}
}
diff --git a/macosx/Info.plist.m4 b/macosx/Info.plist.m4
index 28d37c6d3..c7bb3eeef 100644
--- a/macosx/Info.plist.m4
+++ b/macosx/Info.plist.m4
@@ -14,6 +14,19 @@ dnl
<string>en</string>
<key>CFBundleDisplayName</key>
<string>__HB_name</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>*</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>All files</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ </dict>
+ </array>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>