summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-20 17:59:26 +0000
committerpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-20 17:59:26 +0000
commit1870c693331f6f12a2075482884a2cb09f1ceab4 (patch)
treeabbb684b501ca6fefd743e894d55cd10a9c26620 /chrome/browser
parent5ee78e021cf0d67d72db177f330d123bafce53c0 (diff)
downloadchromium_src-1870c693331f6f12a2075482884a2cb09f1ceab4.zip
chromium_src-1870c693331f6f12a2075482884a2cb09f1ceab4.tar.gz
chromium_src-1870c693331f6f12a2075482884a2cb09f1ceab4.tar.bz2
Implement context menus on Mac.
Review URL: http://codereview.chromium.org/42448 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12198 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_mac.h48
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_mac.mm138
-rw-r--r--chrome/browser/tab_contents/web_contents_view_mac.mm5
3 files changed, 190 insertions, 1 deletions
diff --git a/chrome/browser/tab_contents/render_view_context_menu_mac.h b/chrome/browser/tab_contents/render_view_context_menu_mac.h
new file mode 100644
index 0000000..9a4f60e
--- /dev/null
+++ b/chrome/browser/tab_contents/render_view_context_menu_mac.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_MAC_H_
+#define CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_MAC_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include "chrome/browser/tab_contents/render_view_context_menu.h"
+
+@class ContextMenuTarget;
+
+// Mac implementation of the context menu display code. Uses a Cocoa NSMenu
+// to display the context menu. Internally uses an obj-c object as the
+// target of the NSMenu, bridging back to this C++ class.
+
+class RenderViewContextMenuMac : public RenderViewContextMenu {
+ public:
+ RenderViewContextMenuMac(WebContents* web_contents,
+ const ContextMenuParams& params,
+ NSView* parent_view);
+ virtual ~RenderViewContextMenuMac();
+
+ // Elevate to public so that the obj-c target can call it.
+ void ExecuteCommand(int command_id) { ExecuteItemCommand(command_id); }
+
+ protected:
+ // RenderViewContextMenu implementation-
+ virtual void AppendMenuItem(int id);
+ virtual void AppendMenuItem(int id, const std::wstring& label);
+ virtual void AppendRadioMenuItem(int id, const std::wstring& label);
+ virtual void AppendCheckboxMenuItem(int id, const std::wstring& label);
+ virtual void AppendSeparator();
+ virtual void StartSubMenu(int id, const std::wstring& label);
+ virtual void FinishSubMenu();
+
+ // Do things like remove the windows accelerators.
+ static NSString* PrepareLabelForDisplay(const std::wstring& label);
+
+ private:
+ NSMenu* menu_;
+ NSMenu* insert_menu_; // weak, where new items are inserted (usually
+ // |menu_| unless there's a submenu in progress).
+ ContextMenuTarget* target_; // obj-c target for menu actions
+};
+
+#endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_MAC_H_
diff --git a/chrome/browser/tab_contents/render_view_context_menu_mac.mm b/chrome/browser/tab_contents/render_view_context_menu_mac.mm
new file mode 100644
index 0000000..70d1900
--- /dev/null
+++ b/chrome/browser/tab_contents/render_view_context_menu_mac.mm
@@ -0,0 +1,138 @@
+// Copyright (c) 2009 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.
+
+#include "chrome/browser/tab_contents/render_view_context_menu_mac.h"
+
+#include "base/compiler_specific.h"
+#include "base/sys_string_conversions.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/l10n_util.h"
+#include "grit/generated_resources.h"
+
+// Obj-C bridge class that is the target of all items in the context menu.
+// Relies on the tag being set to the command id. Uses |context_| to
+// execute the command once it is selected and determine if commands should
+// be enabled or disabled.
+
+@interface ContextMenuTarget : NSObject {
+ @private
+ RenderViewContextMenuMac* context_; // weak, owns us.
+}
+- (id)initWithContext:(RenderViewContextMenuMac*)context;
+- (void)itemSelected:(id)sender;
+@end
+
+@implementation ContextMenuTarget
+
+- (id)initWithContext:(RenderViewContextMenuMac*)context {
+ if ((self = [super init])) {
+ DCHECK(context);
+ context_ = context;
+ }
+ return self;
+}
+
+- (void)itemSelected:(id)sender {
+ context_->ExecuteCommand([sender tag]);
+}
+
+@end
+
+RenderViewContextMenuMac::RenderViewContextMenuMac(
+ WebContents* web_contents,
+ const ContextMenuParams& params,
+ NSView* parent_view)
+ : RenderViewContextMenu(web_contents, params),
+ menu_([[NSMenu alloc] init]),
+ insert_menu_(menu_),
+ target_(nil) {
+ [menu_ setAutoenablesItems:NO];
+ target_ = [[ContextMenuTarget alloc] initWithContext:this];
+ InitMenu(params.node);
+
+ // show the menu
+ [NSMenu popUpContextMenu:menu_
+ withEvent:[NSApp currentEvent]
+ forView:parent_view];
+}
+
+RenderViewContextMenuMac::~RenderViewContextMenuMac() {
+ [target_ release];
+ [menu_ release];
+}
+
+// Do things like remove the windows accelerators.
+// TODO(pinkerton): Do we want to do anything like make a maximum string width
+// and middle-truncate?
+NSString* RenderViewContextMenuMac::PrepareLabelForDisplay(
+ const std::wstring& label) {
+ // Strip out any "&"'s that are windows accelerators and we don't use.
+ NSMutableString* title =
+ [NSMutableString stringWithString:base::SysWideToNSString(label)];
+ NSRange range = NSMakeRange(0, [title length]);
+ [title replaceOccurrencesOfString:@"&" withString:@"" options:0 range:range];
+ return title;
+}
+
+void RenderViewContextMenuMac::AppendMenuItem(int command_id) {
+ AppendMenuItem(command_id, l10n_util::GetString(command_id));
+}
+
+void RenderViewContextMenuMac::AppendMenuItem(int command_id,
+ const std::wstring& label) {
+ // Create the item and set its target/action to |target_| with the command
+ // as |command_id|. Then add it to the menu at the end.
+ NSMenuItem* item =
+ [[[NSMenuItem alloc] initWithTitle:PrepareLabelForDisplay(label)
+ action:@selector(itemSelected:)
+ keyEquivalent:@""] autorelease];
+ [item setTag:command_id];
+ [item setTarget:target_];
+ [item setEnabled:IsItemCommandEnabled(command_id) ? YES : NO];
+ [insert_menu_ addItem:item];
+}
+
+void RenderViewContextMenuMac::AppendRadioMenuItem(int id,
+ const std::wstring& label) {
+ NOTIMPLEMENTED();
+}
+
+void RenderViewContextMenuMac::AppendCheckboxMenuItem(int id,
+ const std::wstring& label) {
+ NOTIMPLEMENTED();
+}
+
+void RenderViewContextMenuMac::AppendSeparator() {
+ NSMenuItem* separator = [NSMenuItem separatorItem];
+ [insert_menu_ addItem:separator];
+}
+
+void RenderViewContextMenuMac::StartSubMenu(int command_id,
+ const std::wstring& label) {
+ // I'm not a fan of this kind of API, but the other platforms have similar
+ // guards so at least we know everyone will break together if someone
+ // tries to mis-use the API.
+ if (insert_menu_ != menu_) {
+ NOTREACHED();
+ return;
+ }
+
+ // We don't need to retain the submenu as the context menu already does, but
+ // we switch the "insert menu" so subsequent items are added to the submenu
+ // and not the main menu. This happens until someone calls FinishSubMenu().
+ NSMenuItem* submenu_item =
+ [[[NSMenuItem alloc] initWithTitle:PrepareLabelForDisplay(label)
+ action:nil
+ keyEquivalent:nil] autorelease];
+ insert_menu_ = [[[NSMenu alloc] init] autorelease];
+ [submenu_item setSubmenu:insert_menu_];
+ [menu_ addItem:submenu_item];
+}
+
+void RenderViewContextMenuMac::FinishSubMenu() {
+ // Set the "insert menu" back to the main menu so that subsequently added
+ // items get added to the main context menu.
+ DCHECK(insert_menu_ != menu_);
+ insert_menu_ = menu_;
+}
diff --git a/chrome/browser/tab_contents/web_contents_view_mac.mm b/chrome/browser/tab_contents/web_contents_view_mac.mm
index a63cf86..4c93ed7 100644
--- a/chrome/browser/tab_contents/web_contents_view_mac.mm
+++ b/chrome/browser/tab_contents/web_contents_view_mac.mm
@@ -8,6 +8,7 @@
#include "chrome/browser/cocoa/sad_tab_view.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
+#include "chrome/browser/tab_contents/render_view_context_menu_mac.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/common/temp_scaffolding_stubs.h"
@@ -180,7 +181,9 @@ void WebContentsViewMac::OnFindReply(int request_id,
}
void WebContentsViewMac::ShowContextMenu(const ContextMenuParams& params) {
- NOTIMPLEMENTED();
+ RenderViewContextMenuMac menu(web_contents_,
+ params,
+ GetNativeView());
}
WebContents* WebContentsViewMac::CreateNewWindowInternal(