summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/app_base.gypi1
-rw-r--r--app/menus/accelerator_cocoa.h58
-rw-r--r--chrome/browser/cocoa/accelerators_cocoa.h40
-rw-r--r--chrome/browser/cocoa/accelerators_cocoa.mm56
-rw-r--r--chrome/browser/cocoa/accelerators_cocoa_unittest.mm27
-rw-r--r--chrome/browser/cocoa/menu_controller.mm6
-rw-r--r--chrome/browser/cocoa/toolbar_controller.mm22
-rwxr-xr-xchrome/chrome_browser.gypi2
-rwxr-xr-xchrome/chrome_tests.gypi1
9 files changed, 210 insertions, 3 deletions
diff --git a/app/app_base.gypi b/app/app_base.gypi
index 5cd97ee..facbd4c 100644
--- a/app/app_base.gypi
+++ b/app/app_base.gypi
@@ -158,6 +158,7 @@
'linear_animation.h',
'menus/accelerator.h',
'menus/accelerator_gtk.h',
+ 'menus/accelerator_cocoa.h',
'menus/menu_model.cc',
'menus/menu_model.h',
'menus/simple_menu_model.cc',
diff --git a/app/menus/accelerator_cocoa.h b/app/menus/accelerator_cocoa.h
new file mode 100644
index 0000000..1866b4a
--- /dev/null
+++ b/app/menus/accelerator_cocoa.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 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 APP_MENUS_ACCELERATOR_COCOA_H_
+#define APP_MENUS_ACCELERATOR_COCOA_H_
+
+#include <Foundation/Foundation.h>
+
+#include "app/menus/accelerator.h"
+#include "base/scoped_nsobject.h"
+
+namespace menus {
+
+// This is a subclass of the cross-platform Accelerator, but with more direct
+// support for Cocoa key equivalents. Note that the typical use case for this
+// class is to initialize it with a string literal, which is why it sends
+// |-copy| to the |key_code| paramater in the constructor.
+class AcceleratorCocoa : public Accelerator {
+ public:
+ AcceleratorCocoa(NSString* key_code, NSUInteger mask)
+ : Accelerator(base::VKEY_UNKNOWN, mask),
+ characters_([key_code copy]) {
+ }
+
+ AcceleratorCocoa(const AcceleratorCocoa& accelerator)
+ : Accelerator(accelerator) {
+ characters_.reset([accelerator.characters_ copy]);
+ }
+
+ AcceleratorCocoa() : Accelerator() {}
+ virtual ~AcceleratorCocoa() {}
+
+ AcceleratorCocoa& operator=(const AcceleratorCocoa& accelerator) {
+ if (this != &accelerator) {
+ *static_cast<Accelerator*>(this) = accelerator;
+ characters_.reset([accelerator.characters_ copy]);
+ }
+ return *this;
+ }
+
+ bool operator==(const AcceleratorCocoa& rhs) const {
+ return [characters_ isEqualToString:rhs.characters_.get()] &&
+ (modifiers_ == rhs.modifiers_);
+ }
+
+ NSString* characters() const {
+ return characters_.get();
+ }
+
+ private:
+ // String of characters for the key equivalent.
+ scoped_nsobject<NSString> characters_;
+};
+
+} // namespace menus
+
+#endif // APP_MENUS_ACCELERATOR_COCOA_H_
diff --git a/chrome/browser/cocoa/accelerators_cocoa.h b/chrome/browser/cocoa/accelerators_cocoa.h
new file mode 100644
index 0000000..d4478f2
--- /dev/null
+++ b/chrome/browser/cocoa/accelerators_cocoa.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2010 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_COCOA_ACCELERATORS_COCOA_H_
+#define CHROME_BROWSER_COCOA_ACCELERATORS_COCOA_H_
+
+#include <map>
+
+#include "app/menus/accelerator_cocoa.h"
+
+// This class maintains a map of command_ids to AcceleratorCocoa objects (see
+// chrome/app/chrome_dll_resource.h). Currently, this only lists the commands
+// that are used in the Wrench menu.
+//
+// It is recommended that this class be used as a singleton so that the key map
+// isn't created multiple places.
+//
+// #import "base/singleton.h"
+// ...
+// AcceleratorsCocoa* keymap = Singleton<AcceleratorsCocoa>::get();
+// return keymap->GetAcceleratorForCommand(IDC_COPY);
+//
+class AcceleratorsCocoa {
+ public:
+ AcceleratorsCocoa();
+ ~AcceleratorsCocoa() {}
+
+ typedef std::map<int, menus::AcceleratorCocoa> AcceleratorCocoaMap;
+
+ // Returns NULL if there is no accelerator for the command.
+ const menus::AcceleratorCocoa* GetAcceleratorForCommand(int command_id);
+
+ private:
+ AcceleratorCocoaMap accelerators_;
+
+ DISALLOW_COPY_AND_ASSIGN(AcceleratorsCocoa);
+};
+
+#endif // CHROME_BROWSER_COCOA_ACCELERATORS_COCOA_H_
diff --git a/chrome/browser/cocoa/accelerators_cocoa.mm b/chrome/browser/cocoa/accelerators_cocoa.mm
new file mode 100644
index 0000000..8682997
--- /dev/null
+++ b/chrome/browser/cocoa/accelerators_cocoa.mm
@@ -0,0 +1,56 @@
+// Copyright (c) 2010 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/cocoa/accelerators_cocoa.h"
+
+#import <Cocoa/Cocoa.h>
+
+#include "chrome/app/chrome_dll_resource.h"
+
+namespace {
+
+const struct AcceleratorMapping {
+ int command_id;
+ NSString* key;
+ NSUInteger modifiers;
+} kAcceleratorMap[] = {
+ { IDC_COPY, @"c", NSCommandKeyMask },
+ { IDC_CUT, @"x", NSCommandKeyMask },
+ { IDC_DEV_TOOLS, @"i", NSCommandKeyMask | NSAlternateKeyMask },
+ { IDC_DEV_TOOLS_CONSOLE, @"j", NSCommandKeyMask | NSAlternateKeyMask },
+ { IDC_FIND, @"f", NSCommandKeyMask },
+ { IDC_FULLSCREEN, @"f", NSCommandKeyMask | NSShiftKeyMask },
+ { IDC_NEW_INCOGNITO_WINDOW, @"n", NSCommandKeyMask | NSShiftKeyMask },
+ { IDC_NEW_TAB, @"t", NSCommandKeyMask },
+ { IDC_NEW_WINDOW, @"n", NSCommandKeyMask },
+ { IDC_OPTIONS, @",", NSCommandKeyMask },
+ { IDC_PASTE, @"v", NSCommandKeyMask },
+ { IDC_PRINT, @"p", NSCommandKeyMask },
+ { IDC_SAVE_PAGE, @"s", NSCommandKeyMask },
+ { IDC_SHOW_BOOKMARK_BAR, @"b", NSCommandKeyMask | NSShiftKeyMask },
+ { IDC_SHOW_BOOKMARK_MANAGER, @"b", NSCommandKeyMask | NSAlternateKeyMask },
+ { IDC_SHOW_DOWNLOADS, @"j", NSCommandKeyMask | NSShiftKeyMask },
+ { IDC_SHOW_HISTORY, @"y", NSCommandKeyMask },
+ { IDC_VIEW_SOURCE, @"u", NSCommandKeyMask | NSAlternateKeyMask },
+ { IDC_ZOOM_MINUS, @"-", NSCommandKeyMask },
+ { IDC_ZOOM_PLUS, @"+", NSCommandKeyMask }
+};
+
+} // namespace
+
+AcceleratorsCocoa::AcceleratorsCocoa() {
+ for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) {
+ const AcceleratorMapping& entry = kAcceleratorMap[i];
+ menus::AcceleratorCocoa accelerator(entry.key, entry.modifiers);
+ accelerators_.insert(std::make_pair(entry.command_id, accelerator));
+ }
+}
+
+const menus::AcceleratorCocoa* AcceleratorsCocoa::GetAcceleratorForCommand(
+ int command_id) {
+ AcceleratorCocoaMap::iterator it = accelerators_.find(command_id);
+ if (it == accelerators_.end())
+ return NULL;
+ return &it->second;
+}
diff --git a/chrome/browser/cocoa/accelerators_cocoa_unittest.mm b/chrome/browser/cocoa/accelerators_cocoa_unittest.mm
new file mode 100644
index 0000000..cac5c20
--- /dev/null
+++ b/chrome/browser/cocoa/accelerators_cocoa_unittest.mm
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 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 <Cocoa/Cocoa.h>
+
+#include "app/menus/accelerator_cocoa.h"
+#include "base/singleton.h"
+#include "chrome/app/chrome_dll_resource.h"
+#import "chrome/browser/cocoa/accelerators_cocoa.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(AcceleratorsCocoaTest, GetAccelerator) {
+ AcceleratorsCocoa* keymap = Singleton<AcceleratorsCocoa>::get();
+ const menus::AcceleratorCocoa* accelerator =
+ keymap->GetAcceleratorForCommand(IDC_COPY);
+ ASSERT_TRUE(accelerator);
+ EXPECT_TRUE([@"c" isEqualToString:accelerator->characters()]);
+ EXPECT_EQ(NSCommandKeyMask, accelerator->modifiers());
+}
+
+TEST(AcceleratorsCocoaTest, GetNullAccelerator) {
+ AcceleratorsCocoa* keymap = Singleton<AcceleratorsCocoa>::get();
+ const menus::AcceleratorCocoa* accelerator =
+ keymap->GetAcceleratorForCommand(314159265);
+ EXPECT_FALSE(accelerator);
+}
diff --git a/chrome/browser/cocoa/menu_controller.mm b/chrome/browser/cocoa/menu_controller.mm
index 259c905..a34469e 100644
--- a/chrome/browser/cocoa/menu_controller.mm
+++ b/chrome/browser/cocoa/menu_controller.mm
@@ -5,6 +5,7 @@
#import "chrome/browser/cocoa/menu_controller.h"
#include "app/l10n_util_mac.h"
+#include "app/menus/accelerator_cocoa.h"
#include "app/menus/simple_menu_model.h"
#include "base/logging.h"
#include "base/sys_string_conversions.h"
@@ -102,6 +103,11 @@
[item setTarget:self];
NSValue* modelObject = [NSValue valueWithPointer:model];
[item setRepresentedObject:modelObject]; // Retains |modelObject|.
+ menus::AcceleratorCocoa accelerator;
+ if (model->GetAcceleratorAt(modelIndex, &accelerator)) {
+ [item setKeyEquivalent:accelerator.characters()];
+ [item setKeyEquivalentModifierMask:accelerator.modifiers()];
+ }
}
[menu insertItem:item atIndex:index];
}
diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm
index a17948d..c015f19 100644
--- a/chrome/browser/cocoa/toolbar_controller.mm
+++ b/chrome/browser/cocoa/toolbar_controller.mm
@@ -7,13 +7,17 @@
#include <algorithm>
#include "app/l10n_util_mac.h"
+#include "app/menus/accelerator_cocoa.h"
+#include "base/keyboard_codes.h"
#include "base/mac_util.h"
#include "base/nsimage_cache_mac.h"
+#include "base/singleton.h"
#include "base/sys_string_conversions.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
+#import "chrome/browser/cocoa/accelerators_cocoa.h"
#import "chrome/browser/cocoa/autocomplete_text_field.h"
#import "chrome/browser/cocoa/autocomplete_text_field_editor.h"
#import "chrome/browser/cocoa/back_forward_menu_controller.h"
@@ -98,9 +102,21 @@ class MenuDelegate : public menus::SimpleMenuModel::Delegate {
virtual bool IsCommandIdEnabled(int command_id) const {
return browser_->command_updater()->IsCommandEnabled(command_id);
}
- virtual bool GetAcceleratorForCommandId(
- int command_id,
- menus::Accelerator* accelerator) { return false; }
+ virtual bool GetAcceleratorForCommandId(int command_id,
+ menus::Accelerator* accelerator_generic) {
+ // Downcast so that when the copy constructor is invoked below, the key
+ // string gets copied, too.
+ menus::AcceleratorCocoa* out_accelerator =
+ static_cast<menus::AcceleratorCocoa*>(accelerator_generic);
+ AcceleratorsCocoa* keymap = Singleton<AcceleratorsCocoa>::get();
+ const menus::AcceleratorCocoa* accelerator =
+ keymap->GetAcceleratorForCommand(command_id);
+ if (accelerator) {
+ *out_accelerator = *accelerator;
+ return true;
+ }
+ return false;
+ }
virtual void ExecuteCommand(int command_id) {
browser_->ExecuteCommand(command_id);
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 608fc8e..5ede262 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -575,6 +575,8 @@
'browser/cocoa/about_ipc_dialog.mm',
'browser/cocoa/about_window_controller.h',
'browser/cocoa/about_window_controller.mm',
+ 'browser/cocoa/accelerators_cocoa.h',
+ 'browser/cocoa/accelerators_cocoa.mm',
'browser/cocoa/animatable_view.h',
'browser/cocoa/animatable_view.mm',
'browser/cocoa/authorization_util.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index d98e4d5..0b6099b 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -629,6 +629,7 @@
# exclude them from non-Mac builds.
'browser/cocoa/about_ipc_controller_unittest.mm',
'browser/cocoa/about_window_controller_unittest.mm',
+ 'browser/cocoa/accelerators_cocoa_unittest.mm',
'browser/cocoa/animatable_view_unittest.mm',
'browser/cocoa/autocomplete_text_field_cell_unittest.mm',
'browser/cocoa/autocomplete_text_field_editor_unittest.mm',