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
3 // found in the LICENSE file.
5 #include "chromeos/dbus/ibus/ibus_lookup_table.h"
8 #include "base/logging.h"
9 #include "base/values.h"
10 #include "chromeos/dbus/ibus/ibus_object.h"
11 #include "chromeos/dbus/ibus/ibus_text.h"
12 #include "dbus/message.h"
17 // The default entry number of a page in IBusLookupTable.
18 const int kDefaultPageSize
= 9;
19 const char kShowWindowAtCompositionKey
[] = "show_window_at_composition";
22 void AppendIBusLookupTable(const IBusLookupTable
& table
,
23 dbus::MessageWriter
* writer
) {
24 IBusObjectWriter
ibus_lookup_table_writer("IBusLookupTable",
27 scoped_ptr
<base::Value
> show_position(
28 base::Value::CreateBooleanValue(table
.show_window_at_composition()));
29 ibus_lookup_table_writer
.AddAttachment(kShowWindowAtCompositionKey
,
30 *show_position
.get());
31 ibus_lookup_table_writer
.CloseHeader();
32 ibus_lookup_table_writer
.AppendUint32(table
.page_size());
33 ibus_lookup_table_writer
.AppendUint32(table
.cursor_position());
34 ibus_lookup_table_writer
.AppendBool(table
.is_cursor_visible());
35 ibus_lookup_table_writer
.AppendBool(false); // Not used in Chrome.
36 ibus_lookup_table_writer
.AppendInt32(static_cast<int32
>(table
.orientation()));
38 const std::vector
<IBusLookupTable::Entry
>& candidates
= table
.candidates();
39 dbus::MessageWriter
text_writer(NULL
);
40 ibus_lookup_table_writer
.OpenArray("v", &text_writer
);
41 bool have_labels
= false;
42 for (size_t i
= 0; i
< candidates
.size(); ++i
) {
43 // Write candidate string as IBusText.
45 text
.set_text(candidates
[i
].value
);
46 text
.set_annotation(candidates
[i
].annotation
);
47 text
.set_description_title(candidates
[i
].description_title
);
48 text
.set_description_body(candidates
[i
].description_body
);
49 AppendIBusText(text
, &text_writer
);
50 if (!candidates
[i
].label
.empty())
53 ibus_lookup_table_writer
.CloseContainer(&text_writer
);
55 dbus::MessageWriter
label_writer(NULL
);
56 ibus_lookup_table_writer
.OpenArray("v", &label_writer
);
58 // If there are not any labels, don't append labels.
60 for (size_t i
= 0; i
< candidates
.size(); ++i
) {
61 // Write label string as IBusText.
62 AppendStringAsIBusText(candidates
[i
].label
, &label_writer
);
65 ibus_lookup_table_writer
.CloseContainer(&label_writer
);
67 ibus_lookup_table_writer
.CloseAll();
70 bool PopIBusLookupTable(dbus::MessageReader
* reader
, IBusLookupTable
* table
) {
71 IBusObjectReader
ibus_object_reader("IBusLookupTable", reader
);
73 if (!ibus_object_reader
.Init())
76 const base::Value
* value
=
77 ibus_object_reader
.GetAttachment(kShowWindowAtCompositionKey
);
79 bool show_window_at_composition
;
80 if (value
->GetAsBoolean(&show_window_at_composition
))
81 table
->set_show_window_at_composition(show_window_at_composition
);
85 if (!ibus_object_reader
.PopUint32(&page_size
)) {
86 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
87 << "1st argument should be uint32.";
90 table
->set_page_size(page_size
);
92 uint32 cursor_position
= 0;
93 if (!ibus_object_reader
.PopUint32(&cursor_position
)) {
94 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
95 << "2nd argument should be uint32.";
98 table
->set_cursor_position(cursor_position
);
100 bool cursor_visible
= true;
101 if (!ibus_object_reader
.PopBool(&cursor_visible
)) {
102 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
103 << "3rd argument should be boolean.";
106 table
->set_is_cursor_visible(cursor_visible
);
108 bool unused_round_value
= true;
109 if (!ibus_object_reader
.PopBool(&unused_round_value
)) {
110 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
111 << "4th argument should be boolean.";
115 int32 orientation
= 0;
116 if (!ibus_object_reader
.PopInt32(&orientation
)) {
117 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
118 << "5th argument should be int32.";
122 // Original IBus spec has third orientation IBUS_ORIENTATION_SYSTEM but it
123 // was not supported in Chrome OS. Thus do not cast from integer to enum.
124 table
->set_orientation(
125 orientation
== IBusLookupTable::HORIZONTAL
?
126 IBusLookupTable::HORIZONTAL
: IBusLookupTable::VERTICAL
);
128 dbus::MessageReader
text_array_reader(NULL
);
129 if (!ibus_object_reader
.PopArray(&text_array_reader
)) {
130 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
131 << "6th argument should be array.";
135 std::vector
<IBusLookupTable::Entry
>* candidates
= table
->mutable_candidates();
136 while (text_array_reader
.HasMoreData()) {
137 IBusText candidate_text
;
138 // The attributes in IBusText are not used in Chrome.
139 if (!PopIBusText(&text_array_reader
, &candidate_text
)) {
140 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
141 << "6th argument should be array of IBusText.";
144 IBusLookupTable::Entry entry
;
145 entry
.value
= candidate_text
.text();
146 entry
.annotation
= candidate_text
.annotation();
147 entry
.description_title
= candidate_text
.description_title();
148 entry
.description_body
= candidate_text
.description_body();
149 candidates
->push_back(entry
);
152 dbus::MessageReader
label_array_reader(NULL
);
153 if (!ibus_object_reader
.PopArray(&label_array_reader
)) {
154 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
155 << "7th argument should be array.";
159 if (!label_array_reader
.HasMoreData()) {
163 for (size_t i
= 0; i
< candidates
->size(); ++i
) {
164 if (!label_array_reader
.HasMoreData()) {
165 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
166 << "The number of label entry does not match with candidate "
167 << "text. Same length or no label entry can be accepted.";
171 std::string label_text
;
172 // The attributes in IBusText are not used in Chrome.
173 if (!PopStringFromIBusText(&label_array_reader
, &label_text
)) {
174 LOG(ERROR
) << "Invalid variant structure[IBusLookupTable]: "
175 << "7th argument should be array of IBusText.";
178 (*candidates
)[i
].label
= label_text
;
183 ///////////////////////////////////////////////////////////////////////////////
185 IBusLookupTable::IBusLookupTable()
186 : page_size_(kDefaultPageSize
),
188 is_cursor_visible_(true),
189 orientation_(HORIZONTAL
),
190 show_window_at_composition_(false) {
193 IBusLookupTable::~IBusLookupTable() {
196 bool IBusLookupTable::IsEqual(const IBusLookupTable
& table
) const {
197 if (page_size_
!= table
.page_size_
||
198 cursor_position_
!= table
.cursor_position_
||
199 is_cursor_visible_
!= table
.is_cursor_visible_
||
200 orientation_
!= table
.orientation_
||
201 show_window_at_composition_
!= table
.show_window_at_composition_
||
202 candidates_
.size() != table
.candidates_
.size())
205 for (size_t i
= 0; i
< candidates_
.size(); ++i
) {
206 const Entry
& left
= candidates_
[i
];
207 const Entry
& right
= table
.candidates_
[i
];
208 if (left
.value
!= right
.value
||
209 left
.label
!= right
.label
||
210 left
.annotation
!= right
.annotation
||
211 left
.description_title
!= right
.description_title
||
212 left
.description_body
!= right
.description_body
)
218 void IBusLookupTable::CopyFrom(const IBusLookupTable
& table
) {
219 page_size_
= table
.page_size_
;
220 cursor_position_
= table
.cursor_position_
;
221 is_cursor_visible_
= table
.is_cursor_visible_
;
222 orientation_
= table
.orientation_
;
223 show_window_at_composition_
= table
.show_window_at_composition_
;
225 candidates_
= table
.candidates_
;
228 IBusLookupTable::Entry::Entry() {
231 IBusLookupTable::Entry::~Entry() {
234 } // namespace chromeos