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 30 matching lines...) Expand all Loading... |
41 namespace { | 41 namespace { |
42 | 42 |
43 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the | 43 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the |
44 // property with |new_prop|. Returns true if such a property is found. | 44 // property with |new_prop|. Returns true if such a property is found. |
45 bool FindAndUpdateProperty( | 45 bool FindAndUpdateProperty( |
46 const chromeos::input_method::InputMethodProperty& new_prop, | 46 const chromeos::input_method::InputMethodProperty& new_prop, |
47 chromeos::input_method::InputMethodPropertyList* prop_list) { | 47 chromeos::input_method::InputMethodPropertyList* prop_list) { |
48 for (size_t i = 0; i < prop_list->size(); ++i) { | 48 for (size_t i = 0; i < prop_list->size(); ++i) { |
49 chromeos::input_method::InputMethodProperty& prop = prop_list->at(i); | 49 chromeos::input_method::InputMethodProperty& prop = prop_list->at(i); |
50 if (prop.key == new_prop.key) { | 50 if (prop.key == new_prop.key) { |
51 const int saved_id = prop.selection_item_id; | |
52 // Update the list except the radio id. As written in | |
53 // chromeos_input_method.h, |prop.selection_item_id| is dummy. | |
54 prop = new_prop; | 51 prop = new_prop; |
55 prop.selection_item_id = saved_id; | |
56 return true; | 52 return true; |
57 } | 53 } |
58 } | 54 } |
59 return false; | 55 return false; |
60 } | 56 } |
61 | 57 |
62 } // namespace | 58 } // namespace |
63 | 59 |
64 namespace chromeos { | 60 namespace chromeos { |
65 namespace input_method { | 61 namespace input_method { |
(...skipping 25 matching lines...) Expand all Loading... |
91 bool PropertyHasChildren(IBusProperty* prop) { | 87 bool PropertyHasChildren(IBusProperty* prop) { |
92 return prop && ibus_property_get_sub_props(prop) && | 88 return prop && ibus_property_get_sub_props(prop) && |
93 ibus_prop_list_get(ibus_property_get_sub_props(prop), 0); | 89 ibus_prop_list_get(ibus_property_get_sub_props(prop), 0); |
94 } | 90 } |
95 | 91 |
96 // This function is called by and FlattenProperty() and converts IBus | 92 // This function is called by and FlattenProperty() and converts IBus |
97 // representation of a property, |ibus_prop|, to our own and push_back the | 93 // representation of a property, |ibus_prop|, to our own and push_back the |
98 // result to |out_prop_list|. This function returns true on success, and | 94 // result to |out_prop_list|. This function returns true on success, and |
99 // returns false if sanity checks for |ibus_prop| fail. | 95 // returns false if sanity checks for |ibus_prop| fail. |
100 bool ConvertProperty(IBusProperty* ibus_prop, | 96 bool ConvertProperty(IBusProperty* ibus_prop, |
101 int selection_item_id, | |
102 InputMethodPropertyList* out_prop_list) { | 97 InputMethodPropertyList* out_prop_list) { |
103 DCHECK(ibus_prop); | 98 DCHECK(ibus_prop); |
104 DCHECK(out_prop_list); | 99 DCHECK(out_prop_list); |
105 | 100 |
106 const IBusPropType type = ibus_property_get_prop_type(ibus_prop); | 101 const IBusPropType type = ibus_property_get_prop_type(ibus_prop); |
107 const IBusPropState state = ibus_property_get_state(ibus_prop); | 102 const IBusPropState state = ibus_property_get_state(ibus_prop); |
108 const IBusText* tooltip = ibus_property_get_tooltip(ibus_prop); | 103 const IBusText* tooltip = ibus_property_get_tooltip(ibus_prop); |
109 const IBusText* label = ibus_property_get_label(ibus_prop); | 104 const IBusText* label = ibus_property_get_label(ibus_prop); |
110 const gchar* key = ibus_property_get_key(ibus_prop); | 105 const gchar* key = ibus_property_get_key(ibus_prop); |
111 DCHECK(key); | 106 DCHECK(key); |
112 | 107 |
113 // Sanity checks. | 108 // Sanity checks. |
114 const bool has_sub_props = PropertyHasChildren(ibus_prop); | 109 const bool has_sub_props = PropertyHasChildren(ibus_prop); |
115 if (has_sub_props && (type != PROP_TYPE_MENU)) { | 110 if (has_sub_props && (type != PROP_TYPE_MENU)) { |
116 DVLOG(1) << "The property has sub properties, " | 111 DVLOG(1) << "The property has sub properties, " |
117 << "but the type of the property is not PROP_TYPE_MENU"; | 112 << "but the type of the property is not PROP_TYPE_MENU"; |
118 return false; | 113 return false; |
119 } | 114 } |
120 if ((!has_sub_props) && (type == PROP_TYPE_MENU)) { | 115 if ((!has_sub_props) && (type == PROP_TYPE_MENU)) { |
121 // This is usually not an error. ibus-daemon sometimes sends empty props. | 116 // This is usually not an error. ibus-daemon sometimes sends empty props. |
122 DVLOG(1) << "Property list is empty"; | 117 DVLOG(1) << "Property list is empty"; |
123 return false; | 118 return false; |
124 } | 119 } |
125 if (type == PROP_TYPE_SEPARATOR || type == PROP_TYPE_MENU) { | 120 if (type == PROP_TYPE_SEPARATOR || type == PROP_TYPE_MENU) { |
126 // This is not an error, but we don't push an item for these types. | 121 // This is not an error, but we don't push an item for these types. |
127 return true; | 122 return true; |
128 } | 123 } |
129 | 124 |
130 const bool is_selection_item = (type == PROP_TYPE_RADIO); | 125 const bool is_selection_item = (type == PROP_TYPE_RADIO); |
131 selection_item_id = is_selection_item ? | |
132 selection_item_id : InputMethodProperty::kInvalidSelectionItemId; | |
133 | 126 |
134 bool is_selection_item_checked = false; | 127 bool is_selection_item_checked = false; |
135 if (state == PROP_STATE_INCONSISTENT) { | 128 if (state == PROP_STATE_INCONSISTENT) { |
136 DVLOG(1) << "The property is in PROP_STATE_INCONSISTENT, " | 129 DVLOG(1) << "The property is in PROP_STATE_INCONSISTENT, " |
137 << "which is not supported."; | 130 << "which is not supported."; |
138 } else if ((!is_selection_item) && (state == PROP_STATE_CHECKED)) { | 131 } else if ((!is_selection_item) && (state == PROP_STATE_CHECKED)) { |
139 DVLOG(1) << "PROP_STATE_CHECKED is meaningful only if the type is " | 132 DVLOG(1) << "PROP_STATE_CHECKED is meaningful only if the type is " |
140 << "PROP_TYPE_RADIO."; | 133 << "PROP_TYPE_RADIO."; |
141 } else { | 134 } else { |
142 is_selection_item_checked = (state == PROP_STATE_CHECKED); | 135 is_selection_item_checked = (state == PROP_STATE_CHECKED); |
(...skipping 18 matching lines...) Expand all Loading... |
161 label_to_use = (label && label->text) ? label->text : ""; | 154 label_to_use = (label && label->text) ? label->text : ""; |
162 } | 155 } |
163 if (label_to_use.empty()) { | 156 if (label_to_use.empty()) { |
164 DVLOG(1) << "The tooltip and label are both empty. Use " << key; | 157 DVLOG(1) << "The tooltip and label are both empty. Use " << key; |
165 label_to_use = Or(key, ""); | 158 label_to_use = Or(key, ""); |
166 } | 159 } |
167 | 160 |
168 out_prop_list->push_back(InputMethodProperty(key, | 161 out_prop_list->push_back(InputMethodProperty(key, |
169 label_to_use, | 162 label_to_use, |
170 is_selection_item, | 163 is_selection_item, |
171 is_selection_item_checked, | 164 is_selection_item_checked)); |
172 selection_item_id)); | |
173 return true; | 165 return true; |
174 } | 166 } |
175 | 167 |
176 // Converts |ibus_prop| to |out_prop_list|. Please note that |ibus_prop| | 168 // Converts |ibus_prop| to |out_prop_list|. Please note that |ibus_prop| |
177 // may or may not have children. See the comment for FlattenPropertyList | 169 // may or may not have children. See the comment for FlattenPropertyList |
178 // for details. Returns true if no error is found. | 170 // for details. Returns true if no error is found. |
179 bool FlattenProperty(IBusProperty* ibus_prop, | 171 bool FlattenProperty(IBusProperty* ibus_prop, |
180 InputMethodPropertyList* out_prop_list) { | 172 InputMethodPropertyList* out_prop_list) { |
181 DCHECK(ibus_prop); | 173 DCHECK(ibus_prop); |
182 DCHECK(out_prop_list); | 174 DCHECK(out_prop_list); |
183 | 175 |
184 int selection_item_id = -1; | 176 const gchar* key = ibus_property_get_key(ibus_prop); |
185 std::stack<std::pair<IBusProperty*, int> > prop_stack; | |
186 prop_stack.push(std::make_pair(ibus_prop, selection_item_id)); | |
187 | 177 |
188 while (!prop_stack.empty()) { | 178 // Filter out unnecessary properties. |
189 IBusProperty* prop = prop_stack.top().first; | 179 if (PropertyKeyIsBlacklisted(key)) |
190 const gchar* key = ibus_property_get_key(prop); | 180 return true; |
191 const int current_selection_item_id = prop_stack.top().second; | |
192 prop_stack.pop(); | |
193 | 181 |
194 // Filter out unnecessary properties. | 182 // Convert |prop| to InputMethodProperty and push it to |out_prop_list|. |
195 if (PropertyKeyIsBlacklisted(key)) | 183 if (!ConvertProperty(ibus_prop, out_prop_list)) |
196 continue; | 184 return false; |
197 | 185 |
198 // Convert |prop| to InputMethodProperty and push it to |out_prop_list|. | 186 // Process childrens iteratively (if any). Push all sub properties to the |
199 if (!ConvertProperty(prop, current_selection_item_id, out_prop_list)) | 187 // stack. |
200 return false; | 188 if (PropertyHasChildren(ibus_prop)) { |
201 | 189 for (int i = 0;; ++i) { |
202 // Process childrens iteratively (if any). Push all sub properties to the | 190 IBusProperty* sub_prop = |
203 // stack. | 191 ibus_prop_list_get(ibus_property_get_sub_props(ibus_prop), i); |
204 if (PropertyHasChildren(prop)) { | 192 if (!sub_prop) |
205 ++selection_item_id; | 193 break; |
206 for (int i = 0;; ++i) { | 194 if (!FlattenProperty(sub_prop, out_prop_list)) |
207 IBusProperty* sub_prop = | 195 return false; |
208 ibus_prop_list_get(ibus_property_get_sub_props(prop), i); | |
209 if (!sub_prop) | |
210 break; | |
211 prop_stack.push(std::make_pair(sub_prop, selection_item_id)); | |
212 } | |
213 ++selection_item_id; | |
214 } | 196 } |
215 } | 197 } |
216 std::reverse(out_prop_list->begin(), out_prop_list->end()); | |
217 | |
218 return true; | 198 return true; |
219 } | 199 } |
220 | 200 |
221 // Converts IBus representation of a property list, |ibus_prop_list| to our | 201 // Converts IBus representation of a property list, |ibus_prop_list| to our |
222 // own. This function also flatten the original list (actually it's a tree). | 202 // own. This function also flatten the original list (actually it's a tree). |
223 // Returns true if no error is found. The conversion to our own type is | 203 // Returns true if no error is found. The conversion to our own type is |
224 // necessary since our language switcher in Chrome tree don't (or can't) know | 204 // necessary since our language switcher in Chrome tree don't (or can't) know |
225 // IBus types. Here is an example: | 205 // IBus types. Here is an example: |
226 // | 206 // |
227 // ====================================================================== | 207 // ====================================================================== |
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1096 | 1076 |
1097 // static | 1077 // static |
1098 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( | 1078 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( |
1099 const chromeos::input_method::InputMethodProperty& new_prop, | 1079 const chromeos::input_method::InputMethodProperty& new_prop, |
1100 chromeos::input_method::InputMethodPropertyList* prop_list) { | 1080 chromeos::input_method::InputMethodPropertyList* prop_list) { |
1101 return FindAndUpdateProperty(new_prop, prop_list); | 1081 return FindAndUpdateProperty(new_prop, prop_list); |
1102 } | 1082 } |
1103 | 1083 |
1104 } // namespace input_method | 1084 } // namespace input_method |
1105 } // namespace chromeos | 1085 } // namespace chromeos |
OLD | NEW |