OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/input_method/ibus_controller_impl.h" | 5 #include "chrome/browser/chromeos/input_method/ibus_controller_impl.h" |
6 | 6 |
7 #include <algorithm> // for std::reverse. | 7 #include <algorithm> // for std::reverse. |
8 #include <cstdio> | 8 #include <cstdio> |
9 #include <cstring> // for std::strcmp. | 9 #include <cstring> // for std::strcmp. |
10 #include <set> | 10 #include <set> |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 if (key == kInputMethodPropertyKeysBlacklist[i]) | 75 if (key == kInputMethodPropertyKeysBlacklist[i]) |
76 return true; | 76 return true; |
77 } | 77 } |
78 return false; | 78 return false; |
79 } | 79 } |
80 | 80 |
81 // This function is called by and FlattenProperty() and converts IBus | 81 // This function is called by and FlattenProperty() and converts IBus |
82 // representation of a property, |ibus_prop|, to our own and push_back the | 82 // representation of a property, |ibus_prop|, to our own and push_back the |
83 // result to |out_prop_list|. This function returns true on success, and | 83 // result to |out_prop_list|. This function returns true on success, and |
84 // returns false if sanity checks for |ibus_prop| fail. | 84 // returns false if sanity checks for |ibus_prop| fail. |
85 bool ConvertProperty(const ibus::IBusProperty& ibus_prop, | 85 bool ConvertProperty(const IBusProperty& ibus_prop, |
86 InputMethodPropertyList* out_prop_list) { | 86 InputMethodPropertyList* out_prop_list) { |
87 DCHECK(out_prop_list); | 87 DCHECK(out_prop_list); |
88 DCHECK(ibus_prop.key().empty()); | 88 DCHECK(ibus_prop.key().empty()); |
89 ibus::IBusProperty::IBusPropertyType type = ibus_prop.type(); | 89 IBusProperty::IBusPropertyType type = ibus_prop.type(); |
90 | 90 |
91 // Sanity checks. | 91 // Sanity checks. |
92 const bool has_sub_props = !ibus_prop.sub_properties().empty(); | 92 const bool has_sub_props = !ibus_prop.sub_properties().empty(); |
93 if (has_sub_props && (type != ibus::IBusProperty::IBUS_PROPERTY_TYPE_MENU)) { | 93 if (has_sub_props && (type != IBusProperty::IBUS_PROPERTY_TYPE_MENU)) { |
94 DVLOG(1) << "The property has sub properties, " | 94 DVLOG(1) << "The property has sub properties, " |
95 << "but the type of the property is not PROP_TYPE_MENU"; | 95 << "but the type of the property is not PROP_TYPE_MENU"; |
96 return false; | 96 return false; |
97 } | 97 } |
98 if ((!has_sub_props) && | 98 if ((!has_sub_props) && |
99 (type == ibus::IBusProperty::IBUS_PROPERTY_TYPE_MENU)) { | 99 (type == IBusProperty::IBUS_PROPERTY_TYPE_MENU)) { |
100 // This is usually not an error. ibus-daemon sometimes sends empty props. | 100 // This is usually not an error. ibus-daemon sometimes sends empty props. |
101 DVLOG(1) << "Property list is empty"; | 101 DVLOG(1) << "Property list is empty"; |
102 return false; | 102 return false; |
103 } | 103 } |
104 if (type == ibus::IBusProperty::IBUS_PROPERTY_TYPE_SEPARATOR || | 104 if (type == IBusProperty::IBUS_PROPERTY_TYPE_SEPARATOR || |
105 type == ibus::IBusProperty::IBUS_PROPERTY_TYPE_MENU) { | 105 type == IBusProperty::IBUS_PROPERTY_TYPE_MENU) { |
106 // This is not an error, but we don't push an item for these types. | 106 // This is not an error, but we don't push an item for these types. |
107 return true; | 107 return true; |
108 } | 108 } |
109 | 109 |
110 // This label will be localized later. | 110 // This label will be localized later. |
111 // See chrome/browser/chromeos/input_method/input_method_util.cc. | 111 // See chrome/browser/chromeos/input_method/input_method_util.cc. |
112 std::string label_to_use; | 112 std::string label_to_use; |
113 if (!ibus_prop.tooltip().empty()) | 113 if (!ibus_prop.tooltip().empty()) |
114 label_to_use = ibus_prop.tooltip(); | 114 label_to_use = ibus_prop.tooltip(); |
115 else if (!ibus_prop.label().empty()) | 115 else if (!ibus_prop.label().empty()) |
116 label_to_use = ibus_prop.label(); | 116 label_to_use = ibus_prop.label(); |
117 else | 117 else |
118 label_to_use = ibus_prop.key(); | 118 label_to_use = ibus_prop.key(); |
119 | 119 |
120 out_prop_list->push_back(InputMethodProperty( | 120 out_prop_list->push_back(InputMethodProperty( |
121 ibus_prop.key(), | 121 ibus_prop.key(), |
122 label_to_use, | 122 label_to_use, |
123 (type == ibus::IBusProperty::IBUS_PROPERTY_TYPE_RADIO), | 123 (type == IBusProperty::IBUS_PROPERTY_TYPE_RADIO), |
124 ibus_prop.checked())); | 124 ibus_prop.checked())); |
125 return true; | 125 return true; |
126 } | 126 } |
127 | 127 |
128 // Converts |ibus_prop| to |out_prop_list|. Please note that |ibus_prop| | 128 // Converts |ibus_prop| to |out_prop_list|. Please note that |ibus_prop| |
129 // may or may not have children. See the comment for FlattenPropertyList | 129 // may or may not have children. See the comment for FlattenPropertyList |
130 // for details. Returns true if no error is found. | 130 // for details. Returns true if no error is found. |
131 bool FlattenProperty(const ibus::IBusProperty& ibus_prop, | 131 bool FlattenProperty(const IBusProperty& ibus_prop, |
132 InputMethodPropertyList* out_prop_list) { | 132 InputMethodPropertyList* out_prop_list) { |
133 DCHECK(out_prop_list); | 133 DCHECK(out_prop_list); |
134 | 134 |
135 // Filter out unnecessary properties. | 135 // Filter out unnecessary properties. |
136 if (PropertyKeyIsBlacklisted(ibus_prop.key())) | 136 if (PropertyKeyIsBlacklisted(ibus_prop.key())) |
137 return true; | 137 return true; |
138 | 138 |
139 // Convert |prop| to InputMethodProperty and push it to |out_prop_list|. | 139 // Convert |prop| to InputMethodProperty and push it to |out_prop_list|. |
140 if (!ConvertProperty(ibus_prop, out_prop_list)) | 140 if (!ConvertProperty(ibus_prop, out_prop_list)) |
141 return false; | 141 return false; |
142 | 142 |
143 // Process childrens iteratively (if any). Push all sub properties to the | 143 // Process childrens iteratively (if any). Push all sub properties to the |
144 // stack. | 144 // stack. |
145 if (!ibus_prop.sub_properties().empty()) { | 145 if (!ibus_prop.sub_properties().empty()) { |
146 const ibus::IBusPropertyList& sub_props = ibus_prop.sub_properties(); | 146 const IBusPropertyList& sub_props = ibus_prop.sub_properties(); |
147 for (size_t i = 0; i < sub_props.size(); ++i) { | 147 for (size_t i = 0; i < sub_props.size(); ++i) { |
148 if (!FlattenProperty(*sub_props[i], out_prop_list)) | 148 if (!FlattenProperty(*sub_props[i], out_prop_list)) |
149 return false; | 149 return false; |
150 } | 150 } |
151 } | 151 } |
152 return true; | 152 return true; |
153 } | 153 } |
154 | 154 |
155 // Converts IBus representation of a property list, |ibus_prop_list| to our | 155 // Converts IBus representation of a property list, |ibus_prop_list| to our |
156 // own. This function also flatten the original list (actually it's a tree). | 156 // own. This function also flatten the original list (actually it's a tree). |
(...skipping 11 matching lines...) Expand all Loading... |
168 // | |- Item-3-3 | 168 // | |- Item-3-3 |
169 // |- Item-4 | 169 // |- Item-4 |
170 // | 170 // |
171 // (Note: Item-3-X is a selection item since they're on a sub menu.) | 171 // (Note: Item-3-X is a selection item since they're on a sub menu.) |
172 // | 172 // |
173 // Output: | 173 // Output: |
174 // | 174 // |
175 // Item-1, Item-2, Item-3-1, Item-3-2, Item-3-3, Item-4 | 175 // Item-1, Item-2, Item-3-1, Item-3-2, Item-3-3, Item-4 |
176 // (Note: SubMenuRoot does not appear in the output.) | 176 // (Note: SubMenuRoot does not appear in the output.) |
177 // ====================================================================== | 177 // ====================================================================== |
178 bool FlattenPropertyList(const ibus::IBusPropertyList& ibus_prop_list, | 178 bool FlattenPropertyList(const IBusPropertyList& ibus_prop_list, |
179 InputMethodPropertyList* out_prop_list) { | 179 InputMethodPropertyList* out_prop_list) { |
180 DCHECK(out_prop_list); | 180 DCHECK(out_prop_list); |
181 | 181 |
182 bool result = true; | 182 bool result = true; |
183 for (size_t i = 0; i < ibus_prop_list.size(); ++i) { | 183 for (size_t i = 0; i < ibus_prop_list.size(); ++i) { |
184 result &= FlattenProperty(*ibus_prop_list[i], out_prop_list); | 184 result &= FlattenProperty(*ibus_prop_list[i], out_prop_list); |
185 } | 185 } |
186 return result; | 186 return result; |
187 } | 187 } |
188 | 188 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 // When |id| and |current_input_method_id_| are the same, the properties | 297 // When |id| and |current_input_method_id_| are the same, the properties |
298 // shouldn't be cleared. If we do that, something wrong happens in step #4 | 298 // shouldn't be cleared. If we do that, something wrong happens in step #4 |
299 // below: | 299 // below: |
300 // 1. Enable "xkb:us::eng" and "mozc". Switch to "mozc". | 300 // 1. Enable "xkb:us::eng" and "mozc". Switch to "mozc". |
301 // 2. Focus Omnibox. IME properties for mozc are sent to Chrome. | 301 // 2. Focus Omnibox. IME properties for mozc are sent to Chrome. |
302 // 3. Switch to "xkb:us::eng". No function in this file is called. | 302 // 3. Switch to "xkb:us::eng". No function in this file is called. |
303 // 4. Switch back to "mozc". ChangeInputMethod("mozc") is called, but it's | 303 // 4. Switch back to "mozc". ChangeInputMethod("mozc") is called, but it's |
304 // basically NOP since ibus-daemon's current IME is already "mozc". | 304 // basically NOP since ibus-daemon's current IME is already "mozc". |
305 // IME properties are not sent to Chrome for the same reason. | 305 // IME properties are not sent to Chrome for the same reason. |
306 if (id != current_input_method_id_) { | 306 if (id != current_input_method_id_) { |
307 const ibus::IBusPropertyList empty_list; | 307 const IBusPropertyList empty_list; |
308 RegisterProperties(empty_list); | 308 RegisterProperties(empty_list); |
309 } | 309 } |
310 | 310 |
311 current_input_method_id_ = id; | 311 current_input_method_id_ = id; |
312 | 312 |
313 if (!IBusConnectionsAreAlive()) { | 313 if (!IBusConnectionsAreAlive()) { |
314 DVLOG(1) << "ChangeInputMethod: IBus connection is not alive (yet)."; | 314 DVLOG(1) << "ChangeInputMethod: IBus connection is not alive (yet)."; |
315 // |id| will become usable shortly since Start() has already been called. | 315 // |id| will become usable shortly since Start() has already been called. |
316 // Just return true. | 316 // Just return true. |
317 } else { | 317 } else { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 value.string_list_value, | 404 value.string_list_value, |
405 base::Bind(&ConfigSetValueErrorCallback)); | 405 base::Bind(&ConfigSetValueErrorCallback)); |
406 return true; | 406 return true; |
407 default: | 407 default: |
408 NOTREACHED() << "SendInputMethodConfig: unknown value.type"; | 408 NOTREACHED() << "SendInputMethodConfig: unknown value.type"; |
409 return false; | 409 return false; |
410 } | 410 } |
411 } | 411 } |
412 | 412 |
413 void IBusControllerImpl::RegisterProperties( | 413 void IBusControllerImpl::RegisterProperties( |
414 const ibus::IBusPropertyList& ibus_prop_list) { | 414 const IBusPropertyList& ibus_prop_list) { |
415 // Note: |panel| can be NULL. See ChangeInputMethod(). | 415 // Note: |panel| can be NULL. See ChangeInputMethod(). |
416 current_property_list_.clear(); | 416 current_property_list_.clear(); |
417 if (!FlattenPropertyList(ibus_prop_list, ¤t_property_list_)) | 417 if (!FlattenPropertyList(ibus_prop_list, ¤t_property_list_)) |
418 current_property_list_.clear(); // Clear properties on errors. | 418 current_property_list_.clear(); // Clear properties on errors. |
419 FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged()); | 419 FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged()); |
420 } | 420 } |
421 | 421 |
422 void IBusControllerImpl::UpdateProperty(const ibus::IBusProperty& ibus_prop) { | 422 void IBusControllerImpl::UpdateProperty(const IBusProperty& ibus_prop) { |
423 InputMethodPropertyList prop_list; // our representation. | 423 InputMethodPropertyList prop_list; // our representation. |
424 if (!FlattenProperty(ibus_prop, &prop_list)) { | 424 if (!FlattenProperty(ibus_prop, &prop_list)) { |
425 // Don't update the UI on errors. | 425 // Don't update the UI on errors. |
426 DVLOG(1) << "Malformed properties are detected"; | 426 DVLOG(1) << "Malformed properties are detected"; |
427 return; | 427 return; |
428 } | 428 } |
429 | 429 |
430 // Notify the change. | 430 // Notify the change. |
431 if (!prop_list.empty()) { | 431 if (!prop_list.empty()) { |
432 for (size_t i = 0; i < prop_list.size(); ++i) { | 432 for (size_t i = 0; i < prop_list.size(); ++i) { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 | 604 |
605 // static | 605 // static |
606 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( | 606 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( |
607 const chromeos::input_method::InputMethodProperty& new_prop, | 607 const chromeos::input_method::InputMethodProperty& new_prop, |
608 chromeos::input_method::InputMethodPropertyList* prop_list) { | 608 chromeos::input_method::InputMethodPropertyList* prop_list) { |
609 return FindAndUpdateProperty(new_prop, prop_list); | 609 return FindAndUpdateProperty(new_prop, prop_list); |
610 } | 610 } |
611 | 611 |
612 } // namespace input_method | 612 } // namespace input_method |
613 } // namespace chromeos | 613 } // namespace chromeos |
OLD | NEW |