/src/PluginPDFViewMenu.mm
Objective C++ | 190 lines | 114 code | 33 blank | 43 comment | 21 complexity | 7c278c4b112fd4dde798f509efa5ed3d MD5 | raw file
1/* 2 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * Modified by Sam Gross <colesbury@gmail.com> for use with Firefox PDF Plugin for Mac OS X. 31 */ 32#import "PluginPDFView.h" 33#import "PluginInstance.h" 34 35// This is the implementation of the menu. 36// This includes source code from the WebPDFView.mm in the WebKit project 37 38static void _applicationInfoForMIMEType(NSString *type, NSString **name, NSImage **image) 39{ 40 NSURL *appURL = nil; 41 42 OSStatus error = LSCopyApplicationForMIMEType((CFStringRef)type, kLSRolesAll, (CFURLRef *)&appURL); 43 if (error != noErr) 44 return; 45 46 NSString *appPath = [appURL path]; 47 CFRelease (appURL); 48 49 *image = [[NSWorkspace sharedWorkspace] iconForFile:appPath]; 50 [*image setSize:NSMakeSize(16.f,16.f)]; 51 52 NSString *appName = [[NSFileManager defaultManager] displayNameAtPath:appPath]; 53 *name = appName; 54} 55 56 57@implementation PluginPDFView (PluginPDFViewMenu) 58 59- (BOOL)acceptsFirstResponder { 60 return YES; 61} 62 63- (BOOL)becomeFirstResponder 64{ 65 // This works together with setNextKeyView to splice our PDFSubview into 66 // the key loop similar to the way NSScrollView does this. 67 NSWindow *window = [self window]; 68 id newFirstResponder = nil; 69 70 if ([window keyViewSelectionDirection] == NSSelectingPrevious) { 71 NSView *previousValidKeyView = [self previousValidKeyView]; 72 if ((previousValidKeyView != self) && (previousValidKeyView != pdfView)) 73 newFirstResponder = previousValidKeyView; 74 } else { 75 NSView *PDFDocumentView = [pdfView documentView]; 76 if ([PDFDocumentView acceptsFirstResponder]) 77 newFirstResponder = PDFDocumentView; 78 } 79 80 if (!newFirstResponder) 81 return NO; 82 83 if (![window makeFirstResponder:newFirstResponder]) 84 return NO; 85 86 //[[dataSource webFrame] _clearSelectionInOtherFrames]; 87 88 return YES; 89} 90 91 92- (NSMenuItem*) menuItemOpenWithFinder 93{ 94 NSString *appName = nil; 95 NSImage *appIcon = nil; 96 97 _applicationInfoForMIMEType(@"application/pdf", &appName, &appIcon); 98 if (!appName) 99 appName = @"Finder"; 100 101 NSBundle* bundle = [NSBundle bundleForClass:[self class]]; 102 NSString* openStr = NSLocalizedStringFromTableInBundle(@"Open with %@", nil, bundle, @"Open PDF with application"); 103 104 // To match the PDFKit style, we'll add Open with Preview even when there's no document yet to view, and 105 // disable it using validateUserInterfaceItem. 106 NSString *title = [NSString stringWithFormat:openStr, appName]; 107 NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title action:@selector(openWithFinder:) keyEquivalent:@""]; 108 if (appIcon) { 109 [item setImage:appIcon]; 110 } 111 return [item autorelease]; 112} 113 114- (int) menuInsertIndex:(NSMenu*)menu 115{ 116 NSSet* priorActions = [[NSSet alloc] initWithObjects: 117 NSStringFromSelector(@selector(_searchInSpotlight:)), 118 NSStringFromSelector(@selector(_searchInGoogle:)), 119 NSStringFromSelector(@selector(_searchInDictionary:)), 120 NSStringFromSelector(@selector(copy:)), 121 nil]; 122 int length = [[menu itemArray] count]; 123 for (int i = 0; i < length; i++) { 124 NSString* action = NSStringFromSelector([[menu itemAtIndex:i] action]); 125 if (action != nil && ![priorActions containsObject:action]) { 126 return i; 127 } 128 } 129 return -1; 130} 131 132- (NSMenu *)menuForEvent:(NSEvent*)theEvent 133{ 134 NSMenu* menu = [pdfView menuForEvent:theEvent]; 135 int insertIndex = [self menuInsertIndex:menu]; 136 137 NSBundle* bundle = [NSBundle bundleForClass:[self class]]; 138 NSString* printStr = NSLocalizedStringFromTableInBundle(@"Print File...", nil, bundle, @"Print PDF file"); 139 NSString* saveStr = NSLocalizedStringFromTableInBundle(@"Save File As...", nil, bundle, @"Save PDF file"); 140 141 // Add the Open with Preview/Finder item 142 [menu insertItem:[NSMenuItem separatorItem] atIndex:insertIndex]; 143 [menu insertItem:[self menuItemOpenWithFinder] atIndex:insertIndex]; 144 145 [menu insertItem:[NSMenuItem separatorItem] atIndex:insertIndex]; 146 [menu insertItemWithTitle:printStr action:@selector(doPrint:) keyEquivalent:@"" atIndex:insertIndex]; 147 [menu insertItemWithTitle:saveStr action:@selector(saveAs:) keyEquivalent:@"" atIndex:insertIndex]; 148 149 // Swizzle the search in google 150 NSEnumerator *e = [[menu itemArray] objectEnumerator]; 151 NSMenuItem *item; 152 for (int i = 0; (item = [e nextObject]) != nil; i++) { 153 NSString *actionString = NSStringFromSelector([item action]); 154 if ([actionString isEqualToString:NSStringFromSelector(@selector(_searchInGoogle:))]) { 155 [item setAction:@selector(googleInFirefox:)]; 156 break; 157 } 158 } 159 160 return menu; 161} 162 163// Code courtesy of Chris Wegg 164// TODO: possibly implement with gecko API 165- (void)googleInFirefox:(id)sender { 166 //Get selection, URL encode it, add it to the google search string, and ask the OS to open that URL. 167 //Should open a new firefox tab provided its the default browser. 168 PDFSelection *selection = [pdfView currentSelection]; 169 NSString *escapedselection=(NSString*)CFURLCreateStringByAddingPercentEscapes(NULL, 170 (CFStringRef) [selection string], NULL, NULL, kCFStringEncodingUTF8); 171 NSString *searchurl=[NSString stringWithFormat:@"http://www.google.com/search?q=%@",escapedselection]; 172 [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:searchurl]]; 173} 174 175- (void)doPrint:(id)sender 176{ 177 [plugin print]; 178} 179 180- (void)saveAs:(id)sender 181{ 182 [plugin save]; 183} 184 185- (void)openWithFinder:(id)sender 186{ 187 [plugin openWithFinder]; 188} 189 190@end