OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h" | 5 #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h" |
6 | 6 |
7 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
8 #include "chrome/browser/extensions/extension_service.h" | 8 #include "chrome/browser/extensions/extension_service.h" |
9 #include "chrome/browser/extensions/extension_tab_util.h" | 9 #include "chrome/browser/extensions/extension_tab_util.h" |
10 #include "chrome/browser/extensions/extension_uninstall_dialog.h" | 10 #include "chrome/browser/extensions/extension_uninstall_dialog.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 const Extension* extension_; | 65 const Extension* extension_; |
66 | 66 |
67 // The current profile. Weak. | 67 // The current profile. Weak. |
68 Profile* profile_; | 68 Profile* profile_; |
69 | 69 |
70 scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_; | 70 scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_; |
71 | 71 |
72 DISALLOW_COPY_AND_ASSIGN(AsyncUninstaller); | 72 DISALLOW_COPY_AND_ASSIGN(AsyncUninstaller); |
73 }; | 73 }; |
74 | 74 |
75 namespace extension_action_context_menu { | |
76 | |
77 class DevmodeObserver : public content::NotificationObserver { | |
78 public: | |
79 DevmodeObserver(ExtensionActionContextMenu* menu, | |
80 PrefService* service) | |
81 : menu_(menu), pref_service_(service) { | |
82 registrar_.Init(pref_service_); | |
83 registrar_.Add(prefs::kExtensionsUIDeveloperMode, this); | |
84 } | |
85 virtual ~DevmodeObserver() {} | |
86 | |
87 void Observe(int type, | |
88 const content::NotificationSource& source, | |
89 const content::NotificationDetails& details) { | |
90 if (type == chrome::NOTIFICATION_PREF_CHANGED) | |
91 [menu_ updateInspectorItem]; | |
92 else | |
93 NOTREACHED(); | |
94 } | |
95 | |
96 private: | |
97 ExtensionActionContextMenu* menu_; | |
98 PrefService* pref_service_; | |
99 PrefChangeRegistrar registrar_; | |
100 }; | |
101 | |
102 class ProfileObserverBridge : public content::NotificationObserver { | |
103 public: | |
104 ProfileObserverBridge(ExtensionActionContextMenu* owner, | |
105 const Profile* profile) | |
106 : owner_(owner), | |
107 profile_(profile) { | |
108 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | |
109 content::Source<Profile>(profile)); | |
110 } | |
111 | |
112 ~ProfileObserverBridge() {} | |
113 | |
114 // Overridden from content::NotificationObserver | |
115 void Observe(int type, | |
116 const content::NotificationSource& source, | |
117 const content::NotificationDetails& details) { | |
118 if (type == chrome::NOTIFICATION_PROFILE_DESTROYED && | |
119 source == content::Source<Profile>(profile_)) { | |
120 [owner_ invalidateProfile]; | |
121 } | |
122 } | |
123 | |
124 private: | |
125 ExtensionActionContextMenu* owner_; | |
126 const Profile* profile_; | |
127 content::NotificationRegistrar registrar_; | |
128 }; | |
129 | |
130 } // namespace extension_action_context_menu | |
131 | |
132 @interface ExtensionActionContextMenu(Private) | 75 @interface ExtensionActionContextMenu(Private) |
133 // Callback for the context menu items. | 76 // Callback for the context menu items. |
134 - (void)dispatch:(id)menuItem; | 77 - (void)dispatch:(id)menuItem; |
135 @end | 78 @end |
136 | 79 |
137 @implementation ExtensionActionContextMenu | 80 @implementation ExtensionActionContextMenu |
138 | 81 |
139 namespace { | 82 namespace { |
140 // Enum of menu item choices to their respective indices. | 83 // Enum of menu item choices to their respective indices. |
141 // NOTE: You MUST keep this in sync with the |menuItems| NSArray below. | 84 // NOTE: You MUST keep this in sync with the |menuItems| NSArray below. |
142 enum { | 85 enum { |
143 kExtensionContextName = 0, | 86 kExtensionContextName = 0, |
144 kExtensionContextOptions = 2, | 87 kExtensionContextOptions = 2, |
145 kExtensionContextDisable = 3, | 88 kExtensionContextDisable = 3, |
146 kExtensionContextUninstall = 4, | 89 kExtensionContextUninstall = 4, |
147 kExtensionContextHide = 5, | 90 kExtensionContextHide = 5, |
148 kExtensionContextManage = 7, | 91 kExtensionContextManage = 7, |
149 kExtensionContextInspect = 8 | |
150 }; | 92 }; |
151 | 93 |
152 int CurrentTabId() { | 94 int CurrentTabId() { |
153 Browser* browser = BrowserList::GetLastActive(); | 95 Browser* browser = BrowserList::GetLastActive(); |
154 if(!browser) | 96 if(!browser) |
155 return -1; | 97 return -1; |
156 WebContents* contents = browser->GetSelectedWebContents(); | 98 WebContents* contents = browser->GetSelectedWebContents(); |
157 if (!contents) | 99 if (!contents) |
158 return -1; | 100 return -1; |
159 return ExtensionTabUtil::GetTabId(contents); | 101 return ExtensionTabUtil::GetTabId(contents); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 if ([itemObj tag] == kExtensionContextHide && | 138 if ([itemObj tag] == kExtensionContextHide && |
197 !extension->browser_action()) { | 139 !extension->browser_action()) { |
198 [itemObj setTarget:nil]; // Item is disabled. | 140 [itemObj setTarget:nil]; // Item is disabled. |
199 [itemObj setHidden:YES]; // Item is hidden. | 141 [itemObj setHidden:YES]; // Item is hidden. |
200 } else { | 142 } else { |
201 [itemObj setTarget:self]; | 143 [itemObj setTarget:self]; |
202 } | 144 } |
203 } | 145 } |
204 } | 146 } |
205 | 147 |
206 NSString* inspectorTitle = | |
207 l10n_util::GetNSStringWithFixup(IDS_EXTENSION_ACTION_INSPECT_POPUP); | |
208 inspectorItem_.reset([[NSMenuItem alloc] initWithTitle:inspectorTitle | |
209 action:@selector(dispatch:) | |
210 keyEquivalent:@""]); | |
211 [inspectorItem_.get() setTarget:self]; | |
212 [inspectorItem_.get() setTag:kExtensionContextInspect]; | |
213 | |
214 PrefService* service = profile_->GetPrefs(); | |
215 observer_.reset( | |
216 new extension_action_context_menu::DevmodeObserver(self, service)); | |
217 profile_observer_.reset( | |
218 new extension_action_context_menu::ProfileObserverBridge(self, | |
219 profile)); | |
220 | |
221 [self updateInspectorItem]; | |
222 return self; | 148 return self; |
223 } | 149 } |
224 return nil; | 150 return nil; |
225 } | 151 } |
226 | 152 |
227 - (void)updateInspectorItem { | |
228 PrefService* service = profile_->GetPrefs(); | |
229 bool devmode = service->GetBoolean(prefs::kExtensionsUIDeveloperMode); | |
230 if (devmode) { | |
231 if ([self indexOfItem:inspectorItem_.get()] == -1) | |
232 [self addItem:inspectorItem_.get()]; | |
233 } else { | |
234 if ([self indexOfItem:inspectorItem_.get()] != -1) | |
235 [self removeItem:inspectorItem_.get()]; | |
236 } | |
237 } | |
238 | |
239 - (void)dispatch:(id)menuItem { | 153 - (void)dispatch:(id)menuItem { |
240 Browser* browser = BrowserList::FindBrowserWithProfile(profile_); | 154 Browser* browser = BrowserList::FindBrowserWithProfile(profile_); |
241 if (!browser) | 155 if (!browser) |
242 return; | 156 return; |
243 | 157 |
244 NSMenuItem* item = (NSMenuItem*)menuItem; | 158 NSMenuItem* item = (NSMenuItem*)menuItem; |
245 switch ([item tag]) { | 159 switch ([item tag]) { |
246 case kExtensionContextName: { | 160 case kExtensionContextName: { |
247 GURL url(std::string(extension_urls::kGalleryBrowsePrefix) + | 161 GURL url(std::string(extension_urls::kGalleryBrowsePrefix) + |
248 std::string("/detail/") + extension_->id()); | 162 std::string("/detail/") + extension_->id()); |
(...skipping 22 matching lines...) Expand all Loading... |
271 } | 185 } |
272 case kExtensionContextHide: { | 186 case kExtensionContextHide: { |
273 ExtensionService* extension_service = profile_->GetExtensionService(); | 187 ExtensionService* extension_service = profile_->GetExtensionService(); |
274 extension_service->SetBrowserActionVisibility(extension_, false); | 188 extension_service->SetBrowserActionVisibility(extension_, false); |
275 break; | 189 break; |
276 } | 190 } |
277 case kExtensionContextManage: { | 191 case kExtensionContextManage: { |
278 browser->ShowExtensionsTab(); | 192 browser->ShowExtensionsTab(); |
279 break; | 193 break; |
280 } | 194 } |
281 case kExtensionContextInspect: { | |
282 BrowserWindowCocoa* window = | |
283 static_cast<BrowserWindowCocoa*>(browser->window()); | |
284 ToolbarController* toolbarController = | |
285 [window->cocoa_controller() toolbarController]; | |
286 LocationBarViewMac* locationBarView = | |
287 [toolbarController locationBarBridge]; | |
288 | |
289 NSPoint popupPoint = NSZeroPoint; | |
290 if (extension_->page_action() == action_) { | |
291 popupPoint = locationBarView->GetPageActionBubblePoint(action_); | |
292 | |
293 } else if (extension_->browser_action() == action_) { | |
294 BrowserActionsController* controller = | |
295 [toolbarController browserActionsController]; | |
296 popupPoint = [controller popupPointForBrowserAction:extension_]; | |
297 | |
298 } else { | |
299 NOTREACHED() << "action_ is not a page action or browser action?"; | |
300 } | |
301 | |
302 int tabId = CurrentTabId(); | |
303 GURL url = action_->GetPopupUrl(tabId); | |
304 DCHECK(url.is_valid()); | |
305 [ExtensionPopupController showURL:url | |
306 inBrowser:BrowserList::GetLastActive() | |
307 anchoredAt:popupPoint | |
308 arrowLocation:info_bubble::kTopRight | |
309 devMode:YES]; | |
310 break; | |
311 } | |
312 default: | 195 default: |
313 NOTREACHED(); | 196 NOTREACHED(); |
314 break; | 197 break; |
315 } | 198 } |
316 } | 199 } |
317 | 200 |
318 - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { | 201 - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { |
319 if ([menuItem tag] == kExtensionContextInspect) { | 202 if ([menuItem tag] == kExtensionContextOptions) { |
320 // Disable 'Inspect popup' if there is no popup. | |
321 return action_ && action_->HasPopup(CurrentTabId()); | |
322 } else if ([menuItem tag] == kExtensionContextOptions) { | |
323 // Disable 'Options' if there are no options to set. | 203 // Disable 'Options' if there are no options to set. |
324 return extension_->options_url().spec().length() > 0; | 204 return extension_->options_url().spec().length() > 0; |
325 } | 205 } |
326 return YES; | 206 return YES; |
327 } | 207 } |
328 | 208 |
329 - (void)invalidateProfile { | |
330 observer_.reset(); | |
331 profile_ = NULL; | |
332 } | |
333 | |
334 @end | 209 @end |
OLD | NEW |