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.h" | 5 #include "chrome/browser/chromeos/input_method/ibus_controller.h" |
6 | 6 |
7 #if defined(HAVE_IBUS) | 7 #if defined(HAVE_IBUS) |
8 #include <ibus.h> | 8 #include <ibus.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 std::string InputMethodDescriptor::ToString() const { | 130 std::string InputMethodDescriptor::ToString() const { |
131 std::stringstream stream; | 131 std::stringstream stream; |
132 stream << "id=" << id() | 132 stream << "id=" << id() |
133 << ", name=" << name() | 133 << ", name=" << name() |
134 << ", keyboard_layout=" << keyboard_layout() | 134 << ", keyboard_layout=" << keyboard_layout() |
135 << ", virtual_keyboard_layouts=" << virtual_keyboard_layouts_.size() | 135 << ", virtual_keyboard_layouts=" << virtual_keyboard_layouts_.size() |
136 << ", language_code=" << language_code(); | 136 << ", language_code=" << language_code(); |
137 return stream.str(); | 137 return stream.str(); |
138 } | 138 } |
139 | 139 |
140 ImeProperty::ImeProperty(const std::string& in_key, | 140 InputMethodProperty::InputMethodProperty(const std::string& in_key, |
141 const std::string& in_label, | 141 const std::string& in_label, |
142 bool in_is_selection_item, | 142 bool in_is_selection_item, |
143 bool in_is_selection_item_checked, | 143 bool in_is_selection_item_checked, |
144 int in_selection_item_id) | 144 int in_selection_item_id) |
145 : key(in_key), | 145 : key(in_key), |
146 label(in_label), | 146 label(in_label), |
147 is_selection_item(in_is_selection_item), | 147 is_selection_item(in_is_selection_item), |
148 is_selection_item_checked(in_is_selection_item_checked), | 148 is_selection_item_checked(in_is_selection_item_checked), |
149 selection_item_id(in_selection_item_id) { | 149 selection_item_id(in_selection_item_id) { |
150 DCHECK(!key.empty()); | 150 DCHECK(!key.empty()); |
151 } | 151 } |
152 | 152 |
153 ImeProperty::ImeProperty() | 153 InputMethodProperty::InputMethodProperty() |
154 : is_selection_item(false), | 154 : is_selection_item(false), |
155 is_selection_item_checked(false), | 155 is_selection_item_checked(false), |
156 selection_item_id(kInvalidSelectionItemId) { | 156 selection_item_id(kInvalidSelectionItemId) { |
157 } | 157 } |
158 | 158 |
159 ImeProperty::~ImeProperty() { | 159 InputMethodProperty::~InputMethodProperty() { |
160 } | 160 } |
161 | 161 |
162 std::string ImeProperty::ToString() const { | 162 std::string InputMethodProperty::ToString() const { |
163 std::stringstream stream; | 163 std::stringstream stream; |
164 stream << "key=" << key | 164 stream << "key=" << key |
165 << ", label=" << label | 165 << ", label=" << label |
166 << ", is_selection_item=" << is_selection_item | 166 << ", is_selection_item=" << is_selection_item |
167 << ", is_selection_item_checked=" << is_selection_item_checked | 167 << ", is_selection_item_checked=" << is_selection_item_checked |
168 << ", selection_item_id=" << selection_item_id; | 168 << ", selection_item_id=" << selection_item_id; |
169 return stream.str(); | 169 return stream.str(); |
170 } | 170 } |
171 | 171 |
172 InputMethodConfigValue::InputMethodConfigValue() | 172 InputMethodConfigValue::InputMethodConfigValue() |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 bool PropertyHasChildren(IBusProperty* prop) { | 255 bool PropertyHasChildren(IBusProperty* prop) { |
256 return prop && prop->sub_props && ibus_prop_list_get(prop->sub_props, 0); | 256 return prop && prop->sub_props && ibus_prop_list_get(prop->sub_props, 0); |
257 } | 257 } |
258 | 258 |
259 // This function is called by and FlattenProperty() and converts IBus | 259 // This function is called by and FlattenProperty() and converts IBus |
260 // representation of a property, |ibus_prop|, to our own and push_back the | 260 // representation of a property, |ibus_prop|, to our own and push_back the |
261 // result to |out_prop_list|. This function returns true on success, and | 261 // result to |out_prop_list|. This function returns true on success, and |
262 // returns false if sanity checks for |ibus_prop| fail. | 262 // returns false if sanity checks for |ibus_prop| fail. |
263 bool ConvertProperty(IBusProperty* ibus_prop, | 263 bool ConvertProperty(IBusProperty* ibus_prop, |
264 int selection_item_id, | 264 int selection_item_id, |
265 ImePropertyList* out_prop_list) { | 265 InputMethodPropertyList* out_prop_list) { |
266 DCHECK(ibus_prop); | 266 DCHECK(ibus_prop); |
267 DCHECK(ibus_prop->key); | 267 DCHECK(ibus_prop->key); |
268 DCHECK(out_prop_list); | 268 DCHECK(out_prop_list); |
269 | 269 |
270 // Sanity checks. | 270 // Sanity checks. |
271 const bool has_sub_props = PropertyHasChildren(ibus_prop); | 271 const bool has_sub_props = PropertyHasChildren(ibus_prop); |
272 if (has_sub_props && (ibus_prop->type != PROP_TYPE_MENU)) { | 272 if (has_sub_props && (ibus_prop->type != PROP_TYPE_MENU)) { |
273 LOG(ERROR) << "The property has sub properties, " | 273 LOG(ERROR) << "The property has sub properties, " |
274 << "but the type of the property is not PROP_TYPE_MENU"; | 274 << "but the type of the property is not PROP_TYPE_MENU"; |
275 return false; | 275 return false; |
276 } | 276 } |
277 if ((!has_sub_props) && (ibus_prop->type == PROP_TYPE_MENU)) { | 277 if ((!has_sub_props) && (ibus_prop->type == PROP_TYPE_MENU)) { |
278 // This is usually not an error. ibus-daemon sometimes sends empty props. | 278 // This is usually not an error. ibus-daemon sometimes sends empty props. |
279 VLOG(1) << "Property list is empty"; | 279 VLOG(1) << "Property list is empty"; |
280 return false; | 280 return false; |
281 } | 281 } |
282 if (ibus_prop->type == PROP_TYPE_SEPARATOR || | 282 if (ibus_prop->type == PROP_TYPE_SEPARATOR || |
283 ibus_prop->type == PROP_TYPE_MENU) { | 283 ibus_prop->type == PROP_TYPE_MENU) { |
284 // This is not an error, but we don't push an item for these types. | 284 // This is not an error, but we don't push an item for these types. |
285 return true; | 285 return true; |
286 } | 286 } |
287 | 287 |
288 const bool is_selection_item = (ibus_prop->type == PROP_TYPE_RADIO); | 288 const bool is_selection_item = (ibus_prop->type == PROP_TYPE_RADIO); |
289 selection_item_id = is_selection_item ? | 289 selection_item_id = is_selection_item ? |
290 selection_item_id : ImeProperty::kInvalidSelectionItemId; | 290 selection_item_id : InputMethodProperty::kInvalidSelectionItemId; |
291 | 291 |
292 bool is_selection_item_checked = false; | 292 bool is_selection_item_checked = false; |
293 if (ibus_prop->state == PROP_STATE_INCONSISTENT) { | 293 if (ibus_prop->state == PROP_STATE_INCONSISTENT) { |
294 LOG(WARNING) << "The property is in PROP_STATE_INCONSISTENT, " | 294 LOG(WARNING) << "The property is in PROP_STATE_INCONSISTENT, " |
295 << "which is not supported."; | 295 << "which is not supported."; |
296 } else if ((!is_selection_item) && (ibus_prop->state == PROP_STATE_CHECKED)) { | 296 } else if ((!is_selection_item) && (ibus_prop->state == PROP_STATE_CHECKED)) { |
297 LOG(WARNING) << "PROP_STATE_CHECKED is meaningful only if the type is " | 297 LOG(WARNING) << "PROP_STATE_CHECKED is meaningful only if the type is " |
298 << "PROP_TYPE_RADIO."; | 298 << "PROP_TYPE_RADIO."; |
299 } else { | 299 } else { |
300 is_selection_item_checked = (ibus_prop->state == PROP_STATE_CHECKED); | 300 is_selection_item_checked = (ibus_prop->state == PROP_STATE_CHECKED); |
(...skipping 20 matching lines...) Expand all Loading... |
321 // Usually tooltips are more descriptive than labels. | 321 // Usually tooltips are more descriptive than labels. |
322 label = (ibus_prop->label && ibus_prop->label->text) | 322 label = (ibus_prop->label && ibus_prop->label->text) |
323 ? ibus_prop->label->text : ""; | 323 ? ibus_prop->label->text : ""; |
324 } | 324 } |
325 if (label.empty()) { | 325 if (label.empty()) { |
326 // ibus-pinyin has a property whose label and tooltip are empty. Fall back | 326 // ibus-pinyin has a property whose label and tooltip are empty. Fall back |
327 // to the key. | 327 // to the key. |
328 label = Or(ibus_prop->key, ""); | 328 label = Or(ibus_prop->key, ""); |
329 } | 329 } |
330 | 330 |
331 out_prop_list->push_back(ImeProperty(ibus_prop->key, | 331 out_prop_list->push_back(InputMethodProperty(ibus_prop->key, |
332 label, | 332 label, |
333 is_selection_item, | 333 is_selection_item, |
334 is_selection_item_checked, | 334 is_selection_item_checked, |
335 selection_item_id)); | 335 selection_item_id)); |
336 return true; | 336 return true; |
337 } | 337 } |
338 | 338 |
339 // Converts |ibus_prop| to |out_prop_list|. Please note that |ibus_prop| | 339 // Converts |ibus_prop| to |out_prop_list|. Please note that |ibus_prop| |
340 // may or may not have children. See the comment for FlattenPropertyList | 340 // may or may not have children. See the comment for FlattenPropertyList |
341 // for details. Returns true if no error is found. | 341 // for details. Returns true if no error is found. |
342 // TODO(yusukes): Write unittest. | 342 // TODO(yusukes): Write unittest. |
343 bool FlattenProperty(IBusProperty* ibus_prop, ImePropertyList* out_prop_list) { | 343 bool FlattenProperty(IBusProperty* ibus_prop, |
| 344 InputMethodPropertyList* out_prop_list) { |
344 DCHECK(ibus_prop); | 345 DCHECK(ibus_prop); |
345 DCHECK(out_prop_list); | 346 DCHECK(out_prop_list); |
346 | 347 |
347 int selection_item_id = -1; | 348 int selection_item_id = -1; |
348 std::stack<std::pair<IBusProperty*, int> > prop_stack; | 349 std::stack<std::pair<IBusProperty*, int> > prop_stack; |
349 prop_stack.push(std::make_pair(ibus_prop, selection_item_id)); | 350 prop_stack.push(std::make_pair(ibus_prop, selection_item_id)); |
350 | 351 |
351 while (!prop_stack.empty()) { | 352 while (!prop_stack.empty()) { |
352 IBusProperty* prop = prop_stack.top().first; | 353 IBusProperty* prop = prop_stack.top().first; |
353 const int current_selection_item_id = prop_stack.top().second; | 354 const int current_selection_item_id = prop_stack.top().second; |
354 prop_stack.pop(); | 355 prop_stack.pop(); |
355 | 356 |
356 // Filter out unnecessary properties. | 357 // Filter out unnecessary properties. |
357 if (PropertyKeyIsBlacklisted(prop->key)) { | 358 if (PropertyKeyIsBlacklisted(prop->key)) { |
358 continue; | 359 continue; |
359 } | 360 } |
360 | 361 |
361 // Convert |prop| to ImeProperty and push it to |out_prop_list|. | 362 // Convert |prop| to InputMethodProperty and push it to |out_prop_list|. |
362 if (!ConvertProperty(prop, current_selection_item_id, out_prop_list)) { | 363 if (!ConvertProperty(prop, current_selection_item_id, out_prop_list)) { |
363 return false; | 364 return false; |
364 } | 365 } |
365 | 366 |
366 // Process childrens iteratively (if any). Push all sub properties to the | 367 // Process childrens iteratively (if any). Push all sub properties to the |
367 // stack. | 368 // stack. |
368 if (PropertyHasChildren(prop)) { | 369 if (PropertyHasChildren(prop)) { |
369 ++selection_item_id; | 370 ++selection_item_id; |
370 for (int i = 0;; ++i) { | 371 for (int i = 0;; ++i) { |
371 IBusProperty* sub_prop = ibus_prop_list_get(prop->sub_props, i); | 372 IBusProperty* sub_prop = ibus_prop_list_get(prop->sub_props, i); |
(...skipping 28 matching lines...) Expand all Loading... |
400 // | 401 // |
401 // (Note: Item-3-X is a selection item since they're on a sub menu.) | 402 // (Note: Item-3-X is a selection item since they're on a sub menu.) |
402 // | 403 // |
403 // Output: | 404 // Output: |
404 // | 405 // |
405 // Item-1, Item-2, Item-3-1, Item-3-2, Item-3-3, Item-4 | 406 // Item-1, Item-2, Item-3-1, Item-3-2, Item-3-3, Item-4 |
406 // (Note: SubMenuRoot does not appear in the output.) | 407 // (Note: SubMenuRoot does not appear in the output.) |
407 // ====================================================================== | 408 // ====================================================================== |
408 // TODO(yusukes): Write unittest. | 409 // TODO(yusukes): Write unittest. |
409 bool FlattenPropertyList( | 410 bool FlattenPropertyList( |
410 IBusPropList* ibus_prop_list, ImePropertyList* out_prop_list) { | 411 IBusPropList* ibus_prop_list, InputMethodPropertyList* out_prop_list) { |
411 DCHECK(ibus_prop_list); | 412 DCHECK(ibus_prop_list); |
412 DCHECK(out_prop_list); | 413 DCHECK(out_prop_list); |
413 | 414 |
414 IBusProperty* fake_root_prop = ibus_property_new("Dummy.Key", | 415 IBusProperty* fake_root_prop = ibus_property_new("Dummy.Key", |
415 PROP_TYPE_MENU, | 416 PROP_TYPE_MENU, |
416 NULL, /* label */ | 417 NULL, /* label */ |
417 "", /* icon */ | 418 "", /* icon */ |
418 NULL, /* tooltip */ | 419 NULL, /* tooltip */ |
419 FALSE, /* sensitive */ | 420 FALSE, /* sensitive */ |
420 FALSE, /* visible */ | 421 FALSE, /* visible */ |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 if (ibus_config_ && !ibus_bus_is_connected(ibus_)) { | 980 if (ibus_config_ && !ibus_bus_is_connected(ibus_)) { |
980 g_object_unref(ibus_config_); | 981 g_object_unref(ibus_config_); |
981 ibus_config_ = NULL; | 982 ibus_config_ = NULL; |
982 } | 983 } |
983 } | 984 } |
984 | 985 |
985 // Handles "RegisterProperties" signal from chromeos_input_method_ui. | 986 // Handles "RegisterProperties" signal from chromeos_input_method_ui. |
986 void DoRegisterProperties(IBusPropList* ibus_prop_list) { | 987 void DoRegisterProperties(IBusPropList* ibus_prop_list) { |
987 VLOG(1) << "RegisterProperties" << (ibus_prop_list ? "" : " (clear)"); | 988 VLOG(1) << "RegisterProperties" << (ibus_prop_list ? "" : " (clear)"); |
988 | 989 |
989 ImePropertyList prop_list; // our representation. | 990 InputMethodPropertyList prop_list; // our representation. |
990 if (ibus_prop_list) { | 991 if (ibus_prop_list) { |
991 // You can call | 992 // You can call |
992 // LOG(INFO) << "\n" << PrintPropList(ibus_prop_list, 0); | 993 // LOG(INFO) << "\n" << PrintPropList(ibus_prop_list, 0); |
993 // here to dump |ibus_prop_list|. | 994 // here to dump |ibus_prop_list|. |
994 if (!FlattenPropertyList(ibus_prop_list, &prop_list)) { | 995 if (!FlattenPropertyList(ibus_prop_list, &prop_list)) { |
995 // Clear properties on errors. | 996 // Clear properties on errors. |
996 DoRegisterProperties(NULL); | 997 DoRegisterProperties(NULL); |
997 return; | 998 return; |
998 } | 999 } |
999 } | 1000 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 | 1191 |
1191 // Handles "UpdateProperty" signal from chromeos_input_method_ui. | 1192 // Handles "UpdateProperty" signal from chromeos_input_method_ui. |
1192 void UpdateProperty(IBusPanelService* panel, IBusProperty* ibus_prop) { | 1193 void UpdateProperty(IBusPanelService* panel, IBusProperty* ibus_prop) { |
1193 VLOG(1) << "UpdateProperty"; | 1194 VLOG(1) << "UpdateProperty"; |
1194 DCHECK(ibus_prop); | 1195 DCHECK(ibus_prop); |
1195 | 1196 |
1196 // You can call | 1197 // You can call |
1197 // LOG(INFO) << "\n" << PrintProp(ibus_prop, 0); | 1198 // LOG(INFO) << "\n" << PrintProp(ibus_prop, 0); |
1198 // here to dump |ibus_prop|. | 1199 // here to dump |ibus_prop|. |
1199 | 1200 |
1200 ImePropertyList prop_list; // our representation. | 1201 InputMethodPropertyList prop_list; // our representation. |
1201 if (!FlattenProperty(ibus_prop, &prop_list)) { | 1202 if (!FlattenProperty(ibus_prop, &prop_list)) { |
1202 // Don't update the UI on errors. | 1203 // Don't update the UI on errors. |
1203 LOG(ERROR) << "Malformed properties are detected"; | 1204 LOG(ERROR) << "Malformed properties are detected"; |
1204 return; | 1205 return; |
1205 } | 1206 } |
1206 // Notify the change. | 1207 // Notify the change. |
1207 if (!prop_list.empty()) { | 1208 if (!prop_list.empty()) { |
1208 FOR_EACH_OBSERVER(Observer, observers_, | 1209 FOR_EACH_OBSERVER(Observer, observers_, |
1209 OnUpdateImeProperty(prop_list)); | 1210 OnUpdateImeProperty(prop_list)); |
1210 } | 1211 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 #else | 1387 #else |
1387 return new IBusControllerStubImpl; | 1388 return new IBusControllerStubImpl; |
1388 #endif | 1389 #endif |
1389 } | 1390 } |
1390 | 1391 |
1391 IBusController::~IBusController() { | 1392 IBusController::~IBusController() { |
1392 } | 1393 } |
1393 | 1394 |
1394 } // namespace input_method | 1395 } // namespace input_method |
1395 } // namespace chromeos | 1396 } // namespace chromeos |
OLD | NEW |