Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5318)

Unified Diff: chrome/browser/ui/cocoa/share_menu/share_menu_controller.mm

Issue 1105143005: Issue 465302:System wide share options on Mac Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adds an attachment to Mail Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/share_menu/share_menu_controller.mm
diff --git a/chrome/browser/ui/cocoa/share_menu/share_menu_controller.mm b/chrome/browser/ui/cocoa/share_menu/share_menu_controller.mm
new file mode 100644
index 0000000000000000000000000000000000000000..f2e1cad0088412d99dd7f3cac0f084451521c7da
--- /dev/null
+++ b/chrome/browser/ui/cocoa/share_menu/share_menu_controller.mm
@@ -0,0 +1,314 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/ui/cocoa/share_menu/share_menu_controller.h"
+
+#include "base/strings/sys_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/app/chrome_command_ids.h"
+#import "chrome/browser/app_controller_mac.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_list_observer.h"
+#include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
+#include "chrome/browser/ui/cocoa/share_menu/share_menu_manager.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
+#include "chrome/grit/generated_resources.h"
+#include "skia/ext/image_operations.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/l10n/l10n_util_mac.h"
+#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
+#include "ui/gfx/skbitmap_operations.h"
+#include "ui/snapshot/snapshot.h"
+#include "net/base/escape.h"
+
+@interface ShareMenuController() <NSSharingServiceDelegate, NSMenuDelegate>
+- (void)buildShareItemsFor:(Browser* )browser;
+- (NSMenuItem*)createItemWithTitle:(NSString*)title action:(SEL)sel;
+- (void)enableShareMenuItemsFor:(Browser*)browser;
+// Retrieve the list of possible sharing options and create menu item for each.
+- (NSArray*)shareMenuItemsFor:(NSArray*)items;
+- (void)setPageScreenShotFor:(content::WebContents*)contents;
+- (void)setPageUrlFor:(content::WebContents*)contents;
+@end
+
+namespace ShareMenuControllerInternal {
+
+class Observer : public chrome::BrowserListObserver,TabStripModelObserver {
+ public:
+ Observer(ShareMenuController* controller) : controller_(controller) {
+ BrowserList::AddObserver(this);
+ }
+
+ ~Observer() override {
+ BrowserList::RemoveObserver(this);
+ }
+
+ void OnBrowserAdded(Browser* browser) override {
+ tab_strip_ = browser->tab_strip_model();
+ tab_strip_->AddObserver(this);
+ }
+
+ void OnBrowserRemoved(Browser* browser) override {
+ tab_strip_->RemoveObserver(this);
+ }
+
+ // Wait for a browser tab to become active before building the share menu.
+ void OnBrowserSetLastActive(Browser* browser) override {
+ [controller_ setActiveBrowser:browser];
+ if (browser && ![controller_ menuItemsLoaded]) {
+ [controller_ initShareMenuItem];
+ [controller_ buildShareItemsFor:browser];
+ }
+ LOG(ERROR) << "page refreshed";
+ [controller_ enableShareMenuItemsFor:browser];
+ [controller_ setPageContents:tab_strip_->GetActiveWebContents()];
+ }
+ // When a detached tab / or a NTP is added to the tabstrip update webcontents.
+ void TabInsertedAt(content::WebContents* contents,
+ int index,
+ bool foreground) override {
+ [controller_ setPageUrlFor:contents];
+ [controller_ setPageContents:contents];
+ }
+
+ // When tabs are switched update webcontents.
+ void TabSelectionChanged(TabStripModel* tab_strip_model,
+ const ui::ListSelectionModel& old_model) override {
+ [controller_ setPageContents:tab_strip_->GetActiveWebContents()];
+ Browser* browser = chrome::GetLastActiveBrowser();
+ [controller_ enableShareMenuItemsFor:browser];
+ LOG(ERROR) << "Tabs switched";
+ }
+
+ void TabChangedAt(content::WebContents* contents,
+ int index,
+ TabChangeType change_type) override {
+ LOG(ERROR) << "Tab contents changed";
+ [controller_ setPageContents:contents];
+ }
+
+ private:
+ ShareMenuController* controller_; // Weak; owns this.
+ TabStripModel* tab_strip_;
+ };
+
+} // namespace ShareMenuControllerInternal
+
+////////////////////////////////////////////////////////////////////////////////
+
+@implementation ShareMenuController
+
+- (id)initWithMainMenu:(NSMenu*)menu {
+ if (self = [super init]) {
+ mainMenu_ = menu;
+ shareItems_.reset([[NSMutableArray alloc] init]);
+ pageInfo_.reset([[NSMutableDictionary alloc] init]);
+ menuItemsLoaded_ = NO;
+ observer_.reset(new ShareMenuControllerInternal::Observer(self));
+ }
+ return self;
+}
+
+- (BOOL) menuItemsLoaded {
+ return menuItemsLoaded_;
+}
+
+- (void)setPageContents:(content::WebContents*)contents {
+ pageContents_ = contents;
+}
+
+- (void)setActiveBrowser:(Browser*)browser {
+ lastActiveBrowser_ = browser;
+}
+
+- (void)rebuildShareMenu {
+ //[shareSubMenu_ removeAllItems];
+ //[self buildShareItemsFor:lastActiveBrowser_];
+}
+
+// Create a submenu for displaying various system wide sharing options.
+- (void)initShareMenuItem {
+ shareSubMenu_.reset([[NSMenu alloc] initWithTitle:@"ShareSubMenu"]);
+ fileMenuItem_ = [mainMenu_ itemWithTag:IDC_FILE_MENU];
+ NSString* shareMenuName =
+ l10n_util::GetNSStringWithFixup(IDS_SHARE_MENU_MAC);
+ shareMenuItem_ = [self createItemWithTitle:shareMenuName action:nil];
+ [shareMenuItem_ setTag:IDC_SHARE_MENU];
+}
+
+- (NSMenu*)shareSubMenu {
+ return shareSubMenu_;
+}
+
+- (NSMenuItem*)shareSubMenuItem {
+ return shareMenuItem_;
+}
+
+- (void)buildShareItemsFor:(Browser*)browser {
+ if (!shareSubMenu_)
+ return;
+
+ [shareItems_ addObject:pageUrlForCurrentTab_];
+ NSArray* menuItems = [self shareMenuItemsFor:shareItems_];
+ for (NSMenuItem* item in menuItems) {
+ [shareSubMenu_ addItem:item];
+ }
+
+ // Add the Share Menu Item.
+ NSMenuItem* savePageItem = [[fileMenuItem_ submenu]
+ itemWithTag:IDC_SAVE_PAGE];
+ NSInteger idxSavePage = [[fileMenuItem_ submenu] indexOfItem:savePageItem];
+ [[fileMenuItem_ submenu] insertItem:shareMenuItem_ atIndex:idxSavePage + 2];
+
+ // Remove the Email Page location Menu Item.
+ NSMenuItem* emailPageItem = [[fileMenuItem_ submenu]
+ itemWithTag:IDC_EMAIL_PAGE_LOCATION];
+ [[fileMenuItem_ submenu] removeItem:emailPageItem];
+
+ [[fileMenuItem_ submenu] setSubmenu:shareSubMenu_ forItem:shareMenuItem_];
+ menuItemsLoaded_ = YES;
+}
+
+- (NSMenuItem*)createItemWithTitle:(NSString*)title action:(SEL)sel {
+ NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title action:sel
+ keyEquivalent:@""]
+ autorelease];
+ [item setTarget:self];
+ return item;
+}
+
+- (void)enableShareMenuItemsFor:(Browser*)browser {
+ [shareSubMenu_ setAutoenablesItems:NO];
+ for (NSMenuItem* item in [shareSubMenu_ itemArray]) {
+ BOOL enabled = chrome::CanEmailPageLocation(browser) ?
+ [self validateMenuItem:item] : NO;
+ [item setEnabled:enabled];
+ }
+}
+
+- (NSArray*)shareMenuItemsFor:(NSArray*)items {
+ base::scoped_nsobject<NSMutableArray>
+ menuItems([[NSMutableArray alloc] init]);
+ NSArray *sharingServices = [NSSharingService sharingServicesForItems:items];
+ //originalSharableItems_.reset([[NSArray alloc] initWithArray:sharingServices]);
+ for (NSSharingService* currentService in sharingServices) {
+ NSString* titleText = nil;
+ if ([currentService isEqualTo:[NSSharingService sharingServiceNamed
+ : NSSharingServiceNameComposeEmail]]) {
+ titleText = l10n_util::GetNSString(IDS_EMAIL_PAGE_LOCATION_MAC);
+ } else {
+ titleText = currentService.title;
+ }
+ NSMenuItem* item = [self createItemWithTitle:titleText
+ action:@selector(
+ systemShareService:)];
+ item.image = currentService.image;
+ item.representedObject = currentService;
+ [item setTarget:self];
+ currentService.delegate = self;
+ [menuItems addObject:item];
+ }
+
+ // Add the AirDrop menu item.
+ NSMenuItem* item = nil;
+ NSSharingService* customService = nil;
+ customService = [NSSharingService sharingServiceNamed
+ :NSSharingServiceNameSendViaAirDrop];
+ item = [self createItemWithTitle:customService.title
+ action:@selector(
+ systemShareService:)];
+ item.image = customService.image;
+ item.representedObject = customService;
+ [item setTarget:self];
+ customService.delegate = self;
+ [menuItems addObject:item];
+
+ // Add a menu item to open up system share panel.
+ customService = [[NSSharingService alloc] initWithTitle:@"More"
+ image:nil
+ alternateImage:nil
+ handler:nil];
+ item = [self createItemWithTitle:customService.title
+ action:@selector(
+ systemShareService:)];
+ item.representedObject = customService;
+ [item setTarget:self];
+ customService.delegate = self;
+ [menuItems addObject:item];
+
+ return [NSArray arrayWithArray:menuItems];
+}
+
+- (void)setPageScreenShotFor:(content::WebContents*)contents {
+ scoped_ptr<std::vector<unsigned char> > png_representation(
+ new std::vector<unsigned char>);
+ NSView* webView = contents->GetNativeView();
+ NSRect frame = [webView frame];
+ gfx::Rect bounds(frame.origin.x, frame.origin.y, frame.size.width,
+ frame.size.height);
+ if (ui::GrabViewSnapshot(
+ contents->GetNativeView(), png_representation.get(), bounds)) {
+ base::scoped_nsobject<NSData> image_data(
+ [[NSData alloc] initWithBytes:&(*png_representation)[0]
+ length:png_representation->size()]);
+ contentSnapShot_.reset([[NSImage alloc] initWithData:image_data]);
+ NSURL* pageUrl = [NSURL URLWithString:pageUrlForCurrentTab_];
+ base::scoped_nsobject<NSData> pageData([[NSData alloc]
+ initWithContentsOfURL:pageUrl]);
+ NSLog(@"page url %@", pageUrlForCurrentTab_);
+ page_.reset([[NSString alloc] initWithData:pageData
+ encoding:NSUTF8StringEncoding]);
+ pageHtml_.reset([[NSMutableAttributedString alloc]
+ initWithData:pageData.get() documentAttributes:nil]);
+ //NSLog(@"page html size %ld", [pageHtml_ length]);
+ }
+}
+
+- (void)setPageUrlFor:(content::WebContents*)contents {
+ std::string pageUrl = contents->GetVisibleURL().spec();
+ pageUrlForCurrentTab_ = base::SysUTF8ToNSString(pageUrl);
+}
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
+ return ([menuItem action] == @selector(systemShareService:));
+}
+
+- (void)systemShareService:(id)sender {
+ NSMenuItem* currentMenuItem = (NSMenuItem*)sender;
+ [self setPageUrlFor:pageContents_];
+ [self setPageScreenShotFor:pageContents_];
+ pageInfo_.reset([[NSDictionary alloc]
+ initWithObjectsAndKeys:pageUrlForCurrentTab_, kPageUrl,
+ contentSnapShot_.get(), kPageScreenShot,
+ pageHtml_.get(), kPageHtml,nil]);
+
+ [ShareMenuManager dispatchSharingServiceEventsFor:
+ currentMenuItem.representedObject AndPageInfo:pageInfo_];
+}
+
+// Sharing Service delegate methods.
+- (NSRect)sharingService:(NSSharingService*)sharingService
+ sourceFrameOnScreenForShareItem:(id<NSPasteboardWriting>)item {
+ if (![item isKindOfClass:[NSImage class]])
+ return NSZeroRect;
+
+ NSView* webView = pageContents_->GetNativeView();
+ NSRect frame = [webView frame];
+ return frame;
+}
+
+- (NSImage *)sharingService:(NSSharingService*)sharingService
+ transitionImageForShareItem:(id<NSPasteboardWriting>)item
+ contentRect:(NSRect *)contentRect {
+ if (![item isKindOfClass:[NSImage class]])
+ return nil;
+
+ return contentSnapShot_.get();
+}
+
+@end
« no previous file with comments | « chrome/browser/ui/cocoa/share_menu/share_menu_controller.h ('k') | chrome/browser/ui/cocoa/share_menu/share_menu_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698