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

Side by Side 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, 6 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "chrome/browser/ui/cocoa/share_menu/share_menu_controller.h"
6
7 #include "base/strings/sys_string_conversions.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #import "chrome/browser/app_controller_mac.h"
11 #include "chrome/browser/ui/browser_commands.h"
12 #include "chrome/browser/ui/browser_finder.h"
13 #include "chrome/browser/ui/browser_list.h"
14 #include "chrome/browser/ui/browser_list_observer.h"
15 #include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
16 #include "chrome/browser/ui/cocoa/share_menu/share_menu_manager.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
19 #include "chrome/grit/generated_resources.h"
20 #include "skia/ext/image_operations.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/l10n/l10n_util_mac.h"
23 #include "ui/gfx/geometry/size_conversions.h"
24 #include "ui/gfx/geometry/vector2d_conversions.h"
25 #include "ui/gfx/skbitmap_operations.h"
26 #include "ui/snapshot/snapshot.h"
27 #include "net/base/escape.h"
28
29 @interface ShareMenuController() <NSSharingServiceDelegate, NSMenuDelegate>
30 - (void)buildShareItemsFor:(Browser* )browser;
31 - (NSMenuItem*)createItemWithTitle:(NSString*)title action:(SEL)sel;
32 - (void)enableShareMenuItemsFor:(Browser*)browser;
33 // Retrieve the list of possible sharing options and create menu item for each.
34 - (NSArray*)shareMenuItemsFor:(NSArray*)items;
35 - (void)setPageScreenShotFor:(content::WebContents*)contents;
36 - (void)setPageUrlFor:(content::WebContents*)contents;
37 @end
38
39 namespace ShareMenuControllerInternal {
40
41 class Observer : public chrome::BrowserListObserver,TabStripModelObserver {
42 public:
43 Observer(ShareMenuController* controller) : controller_(controller) {
44 BrowserList::AddObserver(this);
45 }
46
47 ~Observer() override {
48 BrowserList::RemoveObserver(this);
49 }
50
51 void OnBrowserAdded(Browser* browser) override {
52 tab_strip_ = browser->tab_strip_model();
53 tab_strip_->AddObserver(this);
54 }
55
56 void OnBrowserRemoved(Browser* browser) override {
57 tab_strip_->RemoveObserver(this);
58 }
59
60 // Wait for a browser tab to become active before building the share menu.
61 void OnBrowserSetLastActive(Browser* browser) override {
62 [controller_ setActiveBrowser:browser];
63 if (browser && ![controller_ menuItemsLoaded]) {
64 [controller_ initShareMenuItem];
65 [controller_ buildShareItemsFor:browser];
66 }
67 LOG(ERROR) << "page refreshed";
68 [controller_ enableShareMenuItemsFor:browser];
69 [controller_ setPageContents:tab_strip_->GetActiveWebContents()];
70 }
71 // When a detached tab / or a NTP is added to the tabstrip update webcontents.
72 void TabInsertedAt(content::WebContents* contents,
73 int index,
74 bool foreground) override {
75 [controller_ setPageUrlFor:contents];
76 [controller_ setPageContents:contents];
77 }
78
79 // When tabs are switched update webcontents.
80 void TabSelectionChanged(TabStripModel* tab_strip_model,
81 const ui::ListSelectionModel& old_model) override {
82 [controller_ setPageContents:tab_strip_->GetActiveWebContents()];
83 Browser* browser = chrome::GetLastActiveBrowser();
84 [controller_ enableShareMenuItemsFor:browser];
85 LOG(ERROR) << "Tabs switched";
86 }
87
88 void TabChangedAt(content::WebContents* contents,
89 int index,
90 TabChangeType change_type) override {
91 LOG(ERROR) << "Tab contents changed";
92 [controller_ setPageContents:contents];
93 }
94
95 private:
96 ShareMenuController* controller_; // Weak; owns this.
97 TabStripModel* tab_strip_;
98 };
99
100 } // namespace ShareMenuControllerInternal
101
102 ////////////////////////////////////////////////////////////////////////////////
103
104 @implementation ShareMenuController
105
106 - (id)initWithMainMenu:(NSMenu*)menu {
107 if (self = [super init]) {
108 mainMenu_ = menu;
109 shareItems_.reset([[NSMutableArray alloc] init]);
110 pageInfo_.reset([[NSMutableDictionary alloc] init]);
111 menuItemsLoaded_ = NO;
112 observer_.reset(new ShareMenuControllerInternal::Observer(self));
113 }
114 return self;
115 }
116
117 - (BOOL) menuItemsLoaded {
118 return menuItemsLoaded_;
119 }
120
121 - (void)setPageContents:(content::WebContents*)contents {
122 pageContents_ = contents;
123 }
124
125 - (void)setActiveBrowser:(Browser*)browser {
126 lastActiveBrowser_ = browser;
127 }
128
129 - (void)rebuildShareMenu {
130 //[shareSubMenu_ removeAllItems];
131 //[self buildShareItemsFor:lastActiveBrowser_];
132 }
133
134 // Create a submenu for displaying various system wide sharing options.
135 - (void)initShareMenuItem {
136 shareSubMenu_.reset([[NSMenu alloc] initWithTitle:@"ShareSubMenu"]);
137 fileMenuItem_ = [mainMenu_ itemWithTag:IDC_FILE_MENU];
138 NSString* shareMenuName =
139 l10n_util::GetNSStringWithFixup(IDS_SHARE_MENU_MAC);
140 shareMenuItem_ = [self createItemWithTitle:shareMenuName action:nil];
141 [shareMenuItem_ setTag:IDC_SHARE_MENU];
142 }
143
144 - (NSMenu*)shareSubMenu {
145 return shareSubMenu_;
146 }
147
148 - (NSMenuItem*)shareSubMenuItem {
149 return shareMenuItem_;
150 }
151
152 - (void)buildShareItemsFor:(Browser*)browser {
153 if (!shareSubMenu_)
154 return;
155
156 [shareItems_ addObject:pageUrlForCurrentTab_];
157 NSArray* menuItems = [self shareMenuItemsFor:shareItems_];
158 for (NSMenuItem* item in menuItems) {
159 [shareSubMenu_ addItem:item];
160 }
161
162 // Add the Share Menu Item.
163 NSMenuItem* savePageItem = [[fileMenuItem_ submenu]
164 itemWithTag:IDC_SAVE_PAGE];
165 NSInteger idxSavePage = [[fileMenuItem_ submenu] indexOfItem:savePageItem];
166 [[fileMenuItem_ submenu] insertItem:shareMenuItem_ atIndex:idxSavePage + 2];
167
168 // Remove the Email Page location Menu Item.
169 NSMenuItem* emailPageItem = [[fileMenuItem_ submenu]
170 itemWithTag:IDC_EMAIL_PAGE_LOCATION];
171 [[fileMenuItem_ submenu] removeItem:emailPageItem];
172
173 [[fileMenuItem_ submenu] setSubmenu:shareSubMenu_ forItem:shareMenuItem_];
174 menuItemsLoaded_ = YES;
175 }
176
177 - (NSMenuItem*)createItemWithTitle:(NSString*)title action:(SEL)sel {
178 NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title action:sel
179 keyEquivalent:@""]
180 autorelease];
181 [item setTarget:self];
182 return item;
183 }
184
185 - (void)enableShareMenuItemsFor:(Browser*)browser {
186 [shareSubMenu_ setAutoenablesItems:NO];
187 for (NSMenuItem* item in [shareSubMenu_ itemArray]) {
188 BOOL enabled = chrome::CanEmailPageLocation(browser) ?
189 [self validateMenuItem:item] : NO;
190 [item setEnabled:enabled];
191 }
192 }
193
194 - (NSArray*)shareMenuItemsFor:(NSArray*)items {
195 base::scoped_nsobject<NSMutableArray>
196 menuItems([[NSMutableArray alloc] init]);
197 NSArray *sharingServices = [NSSharingService sharingServicesForItems:items];
198 //originalSharableItems_.reset([[NSArray alloc] initWithArray:sharingServices] );
199 for (NSSharingService* currentService in sharingServices) {
200 NSString* titleText = nil;
201 if ([currentService isEqualTo:[NSSharingService sharingServiceNamed
202 : NSSharingServiceNameComposeEmail]]) {
203 titleText = l10n_util::GetNSString(IDS_EMAIL_PAGE_LOCATION_MAC);
204 } else {
205 titleText = currentService.title;
206 }
207 NSMenuItem* item = [self createItemWithTitle:titleText
208 action:@selector(
209 systemShareService:)];
210 item.image = currentService.image;
211 item.representedObject = currentService;
212 [item setTarget:self];
213 currentService.delegate = self;
214 [menuItems addObject:item];
215 }
216
217 // Add the AirDrop menu item.
218 NSMenuItem* item = nil;
219 NSSharingService* customService = nil;
220 customService = [NSSharingService sharingServiceNamed
221 :NSSharingServiceNameSendViaAirDrop];
222 item = [self createItemWithTitle:customService.title
223 action:@selector(
224 systemShareService:)];
225 item.image = customService.image;
226 item.representedObject = customService;
227 [item setTarget:self];
228 customService.delegate = self;
229 [menuItems addObject:item];
230
231 // Add a menu item to open up system share panel.
232 customService = [[NSSharingService alloc] initWithTitle:@"More"
233 image:nil
234 alternateImage:nil
235 handler:nil];
236 item = [self createItemWithTitle:customService.title
237 action:@selector(
238 systemShareService:)];
239 item.representedObject = customService;
240 [item setTarget:self];
241 customService.delegate = self;
242 [menuItems addObject:item];
243
244 return [NSArray arrayWithArray:menuItems];
245 }
246
247 - (void)setPageScreenShotFor:(content::WebContents*)contents {
248 scoped_ptr<std::vector<unsigned char> > png_representation(
249 new std::vector<unsigned char>);
250 NSView* webView = contents->GetNativeView();
251 NSRect frame = [webView frame];
252 gfx::Rect bounds(frame.origin.x, frame.origin.y, frame.size.width,
253 frame.size.height);
254 if (ui::GrabViewSnapshot(
255 contents->GetNativeView(), png_representation.get(), bounds)) {
256 base::scoped_nsobject<NSData> image_data(
257 [[NSData alloc] initWithBytes:&(*png_representation)[0]
258 length:png_representation->size()]);
259 contentSnapShot_.reset([[NSImage alloc] initWithData:image_data]);
260 NSURL* pageUrl = [NSURL URLWithString:pageUrlForCurrentTab_];
261 base::scoped_nsobject<NSData> pageData([[NSData alloc]
262 initWithContentsOfURL:pageUrl]);
263 NSLog(@"page url %@", pageUrlForCurrentTab_);
264 page_.reset([[NSString alloc] initWithData:pageData
265 encoding:NSUTF8StringEncoding]);
266 pageHtml_.reset([[NSMutableAttributedString alloc]
267 initWithData:pageData.get() documentAttributes:nil]);
268 //NSLog(@"page html size %ld", [pageHtml_ length]);
269 }
270 }
271
272 - (void)setPageUrlFor:(content::WebContents*)contents {
273 std::string pageUrl = contents->GetVisibleURL().spec();
274 pageUrlForCurrentTab_ = base::SysUTF8ToNSString(pageUrl);
275 }
276
277 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
278 return ([menuItem action] == @selector(systemShareService:));
279 }
280
281 - (void)systemShareService:(id)sender {
282 NSMenuItem* currentMenuItem = (NSMenuItem*)sender;
283 [self setPageUrlFor:pageContents_];
284 [self setPageScreenShotFor:pageContents_];
285 pageInfo_.reset([[NSDictionary alloc]
286 initWithObjectsAndKeys:pageUrlForCurrentTab_, kPageUrl,
287 contentSnapShot_.get(), kPageScreenShot,
288 pageHtml_.get(), kPageHtml,nil]);
289
290 [ShareMenuManager dispatchSharingServiceEventsFor:
291 currentMenuItem.representedObject AndPageInfo:pageInfo_];
292 }
293
294 // Sharing Service delegate methods.
295 - (NSRect)sharingService:(NSSharingService*)sharingService
296 sourceFrameOnScreenForShareItem:(id<NSPasteboardWriting>)item {
297 if (![item isKindOfClass:[NSImage class]])
298 return NSZeroRect;
299
300 NSView* webView = pageContents_->GetNativeView();
301 NSRect frame = [webView frame];
302 return frame;
303 }
304
305 - (NSImage *)sharingService:(NSSharingService*)sharingService
306 transitionImageForShareItem:(id<NSPasteboardWriting>)item
307 contentRect:(NSRect *)contentRect {
308 if (![item isKindOfClass:[NSImage class]])
309 return nil;
310
311 return contentSnapShot_.get();
312 }
313
314 @end
OLDNEW
« 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