• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_CHROMEOS_STATUS_INPUT_METHOD_MENU_H_
6 #define CHROME_BROWSER_CHROMEOS_STATUS_INPUT_METHOD_MENU_H_
7 #pragma once
8 
9 #include <string>
10 
11 #include "chrome/browser/chromeos/cros/input_method_library.h"
12 #include "chrome/browser/chromeos/status/status_area_host.h"
13 #include "chrome/browser/prefs/pref_member.h"
14 #include "content/common/notification_observer.h"
15 #include "content/common/notification_registrar.h"
16 #include "content/common/notification_type.h"
17 #include "ui/base/models/simple_menu_model.h"
18 #include "views/controls/menu/menu_2.h"
19 #include "views/controls/menu/view_menu_delegate.h"
20 
21 class PrefService;
22 class SkBitmap;
23 
24 namespace chromeos {
25 
26 // A class for the dropdown menu for switching input method and keyboard layout.
27 // Since the class provides the views::ViewMenuDelegate interface, it's easy to
28 // create a button widget (e.g. views::MenuButton, chromeos::StatusAreaButton)
29 // which shows the dropdown menu on click.
30 class InputMethodMenu : public views::ViewMenuDelegate,
31                         public ui::MenuModel,
32                         public InputMethodLibrary::Observer,
33                         public NotificationObserver {
34  public:
35   InputMethodMenu(PrefService* pref_service,
36                   StatusAreaHost::ScreenMode screen_mode,
37                   bool for_out_of_box_experience_dialog);
38   virtual ~InputMethodMenu();
39 
40   // ui::MenuModel implementation.
41   virtual bool HasIcons() const;
42   virtual int GetItemCount() const;
43   virtual ui::MenuModel::ItemType GetTypeAt(int index) const;
44   virtual int GetCommandIdAt(int index) const;
45   virtual string16 GetLabelAt(int index) const;
46   virtual bool IsItemDynamicAt(int index) const;
47   virtual bool GetAcceleratorAt(int index,
48                                 ui::Accelerator* accelerator) const;
49   virtual bool IsItemCheckedAt(int index) const;
50   virtual int GetGroupIdAt(int index) const;
51   virtual bool GetIconAt(int index, SkBitmap* icon);
52   virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const;
53   virtual bool IsEnabledAt(int index) const;
54   virtual ui::MenuModel* GetSubmenuModelAt(int index) const;
55   virtual void HighlightChangedTo(int index);
56   virtual void ActivatedAt(int index);
57   virtual void MenuWillShow();
58   virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate);
59 
60   // views::ViewMenuDelegate implementation. Sub classes can override the method
61   // to adjust the position of the menu.
62   virtual void RunMenu(views::View* unused_source,
63                        const gfx::Point& pt);
64 
65   // InputMethodLibrary::Observer implementation.
66   virtual void InputMethodChanged(
67       InputMethodLibrary* obj,
68       const InputMethodDescriptor& current_input_method,
69       size_t num_active_input_methods);
70   virtual void ActiveInputMethodsChanged(
71       InputMethodLibrary* obj,
72       const InputMethodDescriptor& current_input_method,
73       size_t num_active_input_methods);
74   virtual void PreferenceUpdateNeeded(
75     InputMethodLibrary* obj,
76     const InputMethodDescriptor& previous_input_method,
77     const InputMethodDescriptor& current_input_method);
78   virtual void PropertyListChanged(
79       InputMethodLibrary* obj,
80       const ImePropertyList& current_ime_properties);
81   virtual void FirstObserverIsAdded(InputMethodLibrary* obj);
82 
83   // NotificationObserver implementation.
84   virtual void Observe(NotificationType type,
85                        const NotificationSource& source,
86                        const NotificationDetails& details);
87 
88   // Sets the minimum width of the dropdown menu.
89   void SetMinimumWidth(int width);
90 
91   // Rebuilds model and menu2 objects.
92   void PrepareMenu();
93 
94   // Registers input method preferences for the login screen.
95   static void RegisterPrefs(PrefService* local_state);
96 
97   // Returns a string for the indicator on top right corner of the Chrome
98   // window. The method is public for unit tests.
99   static std::wstring GetTextForIndicator(
100       const InputMethodDescriptor& input_method);
101 
102   // Returns a string for the drop-down menu and the tooltip for the indicator.
103   // The method is public for unit tests.
104   static std::wstring GetTextForMenu(const InputMethodDescriptor& input_method);
105 
106  protected:
107   // Prepares menu: saves user metrics and rebuilds.
108   void PrepareForMenuOpen();
109 
110   // Returns menu2 object for language menu.
input_method_menu()111   views::Menu2& input_method_menu() {
112     return input_method_menu_;
113   }
114 
115  private:
116   // Updates UI of a container of the menu (e.g. the "US" menu button in the
117   // status area). Sub classes have to implement the interface for their own UI.
118   virtual void UpdateUI(const std::string& input_method_id,  // e.g. "mozc"
119                         const std::wstring& name,  // e.g. "US", "INTL"
120                         const std::wstring& tooltip,
121                         size_t num_active_input_methods) = 0;
122 
123   // Sub classes have to implement the interface. This interface should return
124   // true if the dropdown menu should show an item like "Customize languages
125   // and input..." WebUI.
126   virtual bool ShouldSupportConfigUI() = 0;
127 
128   // Sub classes have to implement the interface which opens an UI for
129   // customizing languages and input.
130   virtual void OpenConfigUI() = 0;
131 
132   // Parses |input_method| and then calls UpdateUI().
133   void UpdateUIFromInputMethod(const InputMethodDescriptor& input_method,
134                                size_t num_active_input_methods);
135 
136   // Rebuilds |model_|. This function should be called whenever
137   // |input_method_descriptors_| is updated, or ImePropertiesChanged() is
138   // called.
139   void RebuildModel();
140 
141   // Returns true if the zero-origin |index| points to one of the input methods.
142   bool IndexIsInInputMethodList(int index) const;
143 
144   // Returns true if the zero-origin |index| points to one of the IME
145   // properties. When returning true, |property_index| is updated so that
146   // property_list.at(property_index) points to the menu item.
147   bool GetPropertyIndex(int index, int* property_index) const;
148 
149   // Returns true if the zero-origin |index| points to the "Configure IME" menu
150   // item.
151   bool IndexPointsToConfigureImeMenuItem(int index) const;
152 
153   // The current input method list.
154   scoped_ptr<InputMethodDescriptors> input_method_descriptors_;
155 
156   // Objects for reading/writing the Chrome prefs.
157   StringPrefMember previous_input_method_pref_;
158   StringPrefMember current_input_method_pref_;
159 
160   // We borrow ui::SimpleMenuModel implementation to maintain the current
161   // content of the pop-up menu. The ui::MenuModel is implemented using this
162   // |model_|.
163   scoped_ptr<ui::SimpleMenuModel> model_;
164 
165   // The language menu which pops up when the button in status area is clicked.
166   views::Menu2 input_method_menu_;
167   int minimum_input_method_menu_width_;
168 
169   PrefService* pref_service_;
170   NotificationRegistrar registrar_;
171 
172   // The mode of the host screen  (e.g. browser, screen locker, login screen.)
173   const StatusAreaHost::ScreenMode screen_mode_;
174   // true if the menu is for a dialog in OOBE screen. In the dialog, we don't
175   // use radio buttons.
176   const bool for_out_of_box_experience_dialog_;
177 
178   DISALLOW_COPY_AND_ASSIGN(InputMethodMenu);
179 };
180 
181 }  // namespace chromeos
182 
183 #endif  // CHROME_BROWSER_CHROMEOS_STATUS_INPUT_METHOD_MENU_H_
184