Index: ui/views/controls/views_text_services_context_menu_mac.mm |
diff --git a/ui/views/controls/views_text_services_context_menu_mac.mm b/ui/views/controls/views_text_services_context_menu_mac.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..70dce933e8f3da0f2810a3ed7809f6712719216a |
--- /dev/null |
+++ b/ui/views/controls/views_text_services_context_menu_mac.mm |
@@ -0,0 +1,135 @@ |
+// Copyright 2017 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 "ui/views/controls/views_text_services_context_menu.h" |
+ |
+#import <Cocoa/Cocoa.h> |
+ |
+#include "base/memory/ptr_util.h" |
+#include "ui/base/cocoa/text_services_context_menu.h" |
+#include "ui/base/l10n/l10n_util.h" |
+#include "ui/base/models/simple_menu_model.h" |
+#include "ui/gfx/decorated_text.h" |
+#import "ui/gfx/decorated_text_mac.h" |
+#include "ui/strings/grit/ui_strings.h" |
+#include "ui/views/controls/textfield/textfield.h" |
+#include "ui/views/view.h" |
+#include "ui/views/widget/widget.h" |
+ |
+namespace views { |
+ |
+namespace { |
+ |
+// This class serves as a bridge to TextServicesContextMenu to add and handle |
+// text service items in the context menu. The items include Speech, Look Up |
+// and BiDi. |
+class ViewsTextServicesContextMenuMac |
+ : public ViewsTextServicesContextMenu, |
+ public ui::TextServicesContextMenu::Delegate { |
+ public: |
+ ViewsTextServicesContextMenuMac(ui::SimpleMenuModel* menu, Textfield* client) |
+ : menu_(this), client_(client) { |
+ // The menu index for "Look Up". |
+ constexpr int kLookupMenuIndex = 0; |
+ |
+ base::string16 text = GetSelectedText(); |
+ if (!text.empty()) { |
+ menu->InsertItemAt( |
+ kLookupMenuIndex, IDS_CONTENT_CONTEXT_LOOK_UP, |
+ l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_LOOK_UP, text)); |
+ menu->InsertSeparatorAt(kLookupMenuIndex + 1, ui::NORMAL_SEPARATOR); |
+ } |
+ menu_.AppendToContextMenu(menu); |
+ } |
+ |
+ ~ViewsTextServicesContextMenuMac() override {} |
+ |
+ // Handler for the "Look Up" menu item. |
+ void LookUpInDictionary() { |
+ gfx::Point baseline_point; |
+ gfx::DecoratedText text; |
+ if (client_->GetDecoratedTextAndBaselineFromSelection(&text, |
+ &baseline_point)) { |
+ Widget* widget = client_->GetWidget(); |
+ gfx::NativeView view = widget->GetNativeView(); |
+ views::View::ConvertPointToTarget(client_, widget->GetRootView(), |
+ &baseline_point); |
+ |
+ NSPoint lookup_point = NSMakePoint( |
+ baseline_point.x(), NSHeight([view frame]) - baseline_point.y()); |
+ [view showDefinitionForAttributedString: |
+ gfx::GetAttributedStringFromDecoratedText(text) |
+ atPoint:lookup_point]; |
+ } |
+ } |
+ |
+ // ViewTextServicesContextMenu: |
+ bool HandlesCommandId(int command_id) const override { |
+ return command_id == IDS_CONTENT_CONTEXT_LOOK_UP; |
+ } |
+ |
+ bool IsCommandIdChecked(int command_id) const override { |
+ DCHECK_EQ(IDS_CONTENT_CONTEXT_LOOK_UP, command_id); |
+ return false; |
+ } |
+ |
+ bool IsCommandIdEnabled(int command_id) const override { |
+ DCHECK_EQ(IDS_CONTENT_CONTEXT_LOOK_UP, command_id); |
+ return true; |
+ } |
+ |
+ void ExecuteCommand(int command_id, int event_flags) override { |
+ DCHECK_EQ(IDS_CONTENT_CONTEXT_LOOK_UP, command_id); |
+ LookUpInDictionary(); |
+ } |
+ |
+ bool IsTextDirectionCheckedForTesting( |
+ base::i18n::TextDirection direction) const override { |
+ return IsTextDirectionChecked(direction); |
+ } |
+ |
+ // TextServicesContextMenu::Delegate: |
+ base::string16 GetSelectedText() const override { |
+ return client_->GetSelectedText(); |
+ } |
+ |
+ bool IsTextDirectionEnabled( |
+ base::i18n::TextDirection direction) const override { |
+ return direction != base::i18n::UNKNOWN_DIRECTION; |
+ } |
+ |
+ bool IsTextDirectionChecked( |
+ base::i18n::TextDirection direction) const override { |
+ return direction != base::i18n::UNKNOWN_DIRECTION && |
+ client_->GetTextDirection() == direction; |
+ } |
+ |
+ void UpdateTextDirection(base::i18n::TextDirection direction) override { |
+ DCHECK_NE(direction, base::i18n::UNKNOWN_DIRECTION); |
+ |
+ base::i18n::TextDirection text_direction = |
+ direction == base::i18n::LEFT_TO_RIGHT ? base::i18n::LEFT_TO_RIGHT |
+ : base::i18n::RIGHT_TO_LEFT; |
+ client_->ChangeTextDirectionAndLayoutAlignment(text_direction); |
+ } |
+ |
+ private: |
+ // Appends and handles the text service menu. |
+ ui::TextServicesContextMenu menu_; |
+ |
+ // The view associated with the menu. Weak. Owns |this|. |
+ Textfield* client_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ViewsTextServicesContextMenuMac); |
+}; |
+ |
+} // namespace |
+ |
+// static |
+std::unique_ptr<ViewsTextServicesContextMenu> |
+ViewsTextServicesContextMenu::Create(ui::SimpleMenuModel* menu, |
+ Textfield* client) { |
+ return base::MakeUnique<ViewsTextServicesContextMenuMac>(menu, client); |
+} |
+ |
+} // namespace views |