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..634598e1e94628b21103508090b210724b30ecbe |
--- /dev/null |
+++ b/ui/views/controls/views_text_services_context_menu_mac.mm |
@@ -0,0 +1,172 @@ |
+// Copyright 2016 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> |
tapted
2016/12/21 11:20:27
nit: blank line before
spqchan
2016/12/21 22:00:14
Done.
|
+ |
+#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" |
+#include "ui/gfx/decorated_text_mac.h" |
tapted
2016/12/21 11:20:27
nit: import
spqchan
2016/12/21 22:00:14
Done.
|
+#include "ui/strings/grit/ui_strings.h" |
+#include "ui/views/controls/textfield/textfield.h" |
+#include "ui/views/controls/views_text_services_context_menu.h" |
tapted
2016/12/21 11:20:27
I think you can put this one first (before Cocoa)
spqchan
2016/12/21 22:00:14
Done.
|
+#include "ui/views/view.h" |
+#include "ui/views/widget/widget.h" |
+ |
+namespace views { |
+ |
+namespace { |
+ |
+// The menu index for "Look Up". |
+int kLookupMenuIndex = 0; |
tapted
2016/12/21 11:20:27
constexpr
spqchan
2016/12/21 22:00:14
Done.
|
+ |
+// 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); |
+ ~ViewsTextServicesContextMenuMac() override; |
+ |
+ // Handler for the "Look Up" menu item. |
+ void LookUpInDictionary(); |
+ |
+ // ViewTextServiceContextMenu: |
tapted
2016/12/21 11:20:27
Service -> Services
spqchan
2016/12/21 22:00:14
Done.
|
+ bool HandlesCommandId(int command_id) const override; |
+ void ExecuteCommand(int command_id, int event_flags) override; |
tapted
2016/12/21 11:20:27
nit: reorder
spqchan
2016/12/21 22:00:14
Done.
|
+ bool IsCommandIdChecked(int command_id) const override; |
+ bool IsCommandIdEnabled(int command_id) const override; |
+ |
+ // TextServicesContextMenu::Delegate: |
+ base::string16 GetSelectedText() const override; |
+ void OnSpeakRequested() override; |
+ bool IsTextDirectionEnabled( |
+ base::i18n::TextDirection direction) const override; |
+ bool IsTextDirectionChecked( |
+ base::i18n::TextDirection direction) const override; |
+ void UpdateTextDirection(base::i18n::TextDirection direction) override; |
+ |
+ private: |
+ // Appends and handles the text service menu. |
+ ui::TextServicesContextMenu menu_; |
+ |
+ // The view associated with the menu. Weak. |
tapted
2016/12/21 11:20:27
add "Owns |this|."
spqchan
2016/12/21 22:00:14
Done.
|
+ Textfield* client_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ViewsTextServicesContextMenuMac); |
+}; |
+ |
+ViewsTextServicesContextMenuMac::ViewsTextServicesContextMenuMac( |
+ ui::SimpleMenuModel* menu, |
+ Textfield* client) |
+ : menu_(this), client_(client) { |
+ menu->InsertItemAt(kLookupMenuIndex, IDS_CONTENT_CONTEXT_LOOK_UP, |
+ l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_LOOK_UP, |
+ GetSelectedText())); |
+ menu->InsertSeparatorAt(kLookupMenuIndex + 1, ui::NORMAL_SEPARATOR); |
+ menu_.AppendToContextMenu(menu); |
+} |
+ |
+ViewsTextServicesContextMenuMac::~ViewsTextServicesContextMenuMac() {} |
+ |
+void ViewsTextServicesContextMenuMac::LookUpInDictionary() { |
+ gfx::Point baseline_point; |
+ gfx::DecoratedText text; |
+ client_->GetDecoratedTextAndBaselineFromSelection(&text, &baseline_point); |
tapted
2016/12/21 11:20:27
check return value?
spqchan
2016/12/21 22:00:14
Done.
|
+ |
+ 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]; |
+} |
+ |
+bool ViewsTextServicesContextMenuMac::HandlesCommandId(int command_id) const { |
+ return menu_.IsTextServicesCommandId(command_id) || |
+ command_id == IDS_CONTENT_CONTEXT_LOOK_UP; |
+} |
+ |
+void ViewsTextServicesContextMenuMac::ExecuteCommand(int command_id, |
+ int event_flags) { |
+ if (command_id == IDS_CONTENT_CONTEXT_LOOK_UP) |
+ LookUpInDictionary(); |
+ else |
+ menu_.ExecuteCommand(command_id, event_flags); |
+} |
+ |
+bool ViewsTextServicesContextMenuMac::IsCommandIdChecked(int command_id) const { |
+ if (command_id == IDS_CONTENT_CONTEXT_LOOK_UP) |
+ return false; |
+ |
+ return menu_.IsCommandIdChecked(command_id); |
+} |
+ |
+bool ViewsTextServicesContextMenuMac::IsCommandIdEnabled(int command_id) const { |
+ if (command_id == IDS_CONTENT_CONTEXT_LOOK_UP) |
+ return true; |
+ |
+ return menu_.IsCommandIdEnabled(command_id); |
+} |
+ |
+base::string16 ViewsTextServicesContextMenuMac::GetSelectedText() const { |
+ gfx::Range range; |
tapted
2016/12/21 11:20:27
I think client_->GetSelectedText() will work now
spqchan
2016/12/21 22:00:14
Done.
|
+ base::string16 text; |
+ client_->GetSelectionRange(&range); |
+ client_->GetTextFromRange(range, &text); |
+ return text; |
+} |
+ |
+void ViewsTextServicesContextMenuMac::OnSpeakRequested() { |
+ menu_.SpeakText(GetSelectedText()); |
+} |
+ |
+bool ViewsTextServicesContextMenuMac::IsTextDirectionEnabled( |
+ base::i18n::TextDirection direction) const { |
+ return direction != base::i18n::TextDirection::UNKNOWN_DIRECTION; |
+} |
+ |
+bool ViewsTextServicesContextMenuMac::IsTextDirectionChecked( |
+ base::i18n::TextDirection direction) const { |
+ switch (direction) { |
+ case base::i18n::TextDirection::UNKNOWN_DIRECTION: |
+ return false; |
+ case base::i18n::TextDirection::RIGHT_TO_LEFT: |
+ return client_->GetTextDirection() == base::i18n::RIGHT_TO_LEFT; |
+ case base::i18n::TextDirection::LEFT_TO_RIGHT: |
+ return client_->GetTextDirection() == base::i18n::LEFT_TO_RIGHT; |
+ case base::i18n::TextDirection::TEXT_DIRECTION_NUM_DIRECTIONS: |
+ NOTREACHED(); |
+ return false; |
+ } |
+} |
+ |
+void ViewsTextServicesContextMenuMac::UpdateTextDirection( |
+ base::i18n::TextDirection direction) { |
+ DCHECK_NE(direction, base::i18n::TextDirection::UNKNOWN_DIRECTION); |
+ |
+ base::i18n::TextDirection text_direction = |
+ direction == base::i18n::TextDirection::LEFT_TO_RIGHT |
tapted
2016/12/21 11:20:27
I think the `TextDirection::` part of this is redu
spqchan
2016/12/21 22:00:14
Done.
|
+ ? base::i18n::LEFT_TO_RIGHT |
+ : base::i18n::RIGHT_TO_LEFT; |
+ client_->ChangeTextDirectionAndLayoutAlignment(text_direction); |
+} |
+ |
+} // namespace |
+ |
+// static |
+std::unique_ptr<ViewsTextServicesContextMenu> |
+ViewsTextServicesContextMenu::Create(ui::SimpleMenuModel* menu, |
+ Textfield* client) { |
+ return base::MakeUnique<ViewsTextServicesContextMenuMac>(menu, client); |
+} |
+ |
+} // namespace views |