1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* IBus - The Input Bus
4 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2010 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
22 #include "ibuslookuptable.h"
24 /* functions prototype */
25 static void ibus_lookup_table_destroy (IBusLookupTable *table);
26 static gboolean ibus_lookup_table_serialize (IBusLookupTable *table,
27 GVariantBuilder *builder);
28 static gint ibus_lookup_table_deserialize (IBusLookupTable *table,
30 static gboolean ibus_lookup_table_copy (IBusLookupTable *dest,
31 IBusLookupTable *src);
33 G_DEFINE_TYPE (IBusLookupTable, ibus_lookup_table, IBUS_TYPE_SERIALIZABLE)
36 ibus_lookup_table_class_init (IBusLookupTableClass *class)
38 IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
39 IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
41 object_class->destroy = (IBusObjectDestroyFunc) ibus_lookup_table_destroy;
43 serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_lookup_table_serialize;
44 serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_lookup_table_deserialize;
45 serializable_class->copy = (IBusSerializableCopyFunc) ibus_lookup_table_copy;
49 ibus_lookup_table_init (IBusLookupTable *table)
51 table->candidates = g_array_new (TRUE, TRUE, sizeof (IBusText *));
52 table->labels = g_array_new (TRUE, TRUE, sizeof (IBusText *));
56 ibus_lookup_table_destroy (IBusLookupTable *table)
61 if (table->candidates != NULL) {
62 p = (IBusText **) g_array_free (table->candidates, FALSE);
63 table->candidates = NULL;
65 for (i = 0; p[i] != NULL; i++) {
66 g_object_unref (p[i]);
71 if (table->labels != NULL) {
72 p = (IBusText **) g_array_free (table->labels, FALSE);
74 for (i = 0; p[i] != NULL; i++) {
75 g_object_unref (p[i]);
80 IBUS_OBJECT_CLASS (ibus_lookup_table_parent_class)->destroy ((IBusObject *) table);
84 ibus_lookup_table_serialize (IBusLookupTable *table,
85 GVariantBuilder *builder)
90 retval = IBUS_SERIALIZABLE_CLASS (ibus_lookup_table_parent_class)->serialize ((IBusSerializable *)table, builder);
91 g_return_val_if_fail (retval, 0);
93 g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (table), 0);
95 g_variant_builder_add (builder, "u", table->page_size);
96 g_variant_builder_add (builder, "u", table->cursor_pos);
97 g_variant_builder_add (builder, "b", table->cursor_visible);
98 g_variant_builder_add (builder, "b", table->round);
99 g_variant_builder_add (builder, "i", table->orientation);
101 GVariantBuilder array;
102 /* append candidates */
103 g_variant_builder_init (&array, G_VARIANT_TYPE ("av"));
105 IBusText *text = ibus_lookup_table_get_candidate (table, i);
108 g_variant_builder_add (&array, "v", ibus_serializable_serialize ((IBusSerializable *)text));
110 g_variant_builder_add (builder, "av", &array);
113 g_variant_builder_init (&array, G_VARIANT_TYPE ("av"));
115 IBusText *text = ibus_lookup_table_get_label (table, i);
119 g_variant_builder_add (&array, "v", ibus_serializable_serialize ((IBusSerializable *)text));
121 g_variant_builder_add (builder, "av", &array);
127 ibus_lookup_table_deserialize (IBusLookupTable *table,
132 retval = IBUS_SERIALIZABLE_CLASS (ibus_lookup_table_parent_class)->deserialize ((IBusSerializable *)table, variant);
133 g_return_val_if_fail (retval, 0);
135 g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (table), 0);
137 g_variant_get_child (variant, retval++, "u", &table->page_size);
138 g_variant_get_child (variant, retval++, "u", &table->cursor_pos);
139 g_variant_get_child (variant, retval++, "b", &table->cursor_visible);
140 g_variant_get_child (variant, retval++, "b", &table->round);
141 g_variant_get_child (variant, retval++, "i", &table->orientation);
144 // deserialize candidates
145 GVariantIter *iter = NULL;
146 g_variant_get_child (variant, retval++, "av", &iter);
147 while (g_variant_iter_loop (iter, "v", &var)) {
148 ibus_lookup_table_append_candidate (table, IBUS_TEXT (ibus_serializable_deserialize (var)));
150 g_variant_iter_free (iter);
152 // deserialize labels
154 g_variant_get_child (variant, retval++, "av", &iter);
155 while (g_variant_iter_loop (iter, "v", &var)) {
156 ibus_lookup_table_append_label (table, IBUS_TEXT (ibus_serializable_deserialize (var)));
158 g_variant_iter_free (iter);
164 ibus_lookup_table_copy (IBusLookupTable *dest,
165 IBusLookupTable *src)
170 retval = IBUS_SERIALIZABLE_CLASS (ibus_lookup_table_parent_class)->copy ((IBusSerializable *)dest, (IBusSerializable *)src);
171 g_return_val_if_fail (retval, FALSE);
173 g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (dest), FALSE);
174 g_return_val_if_fail (IBUS_IS_LOOKUP_TABLE (src), FALSE);
180 text = ibus_lookup_table_get_candidate (src, i);
184 text = (IBusText *) ibus_serializable_copy ((IBusSerializable *) text);
186 ibus_lookup_table_append_candidate (dest, text);
193 text = ibus_lookup_table_get_label (src, i);
197 text = (IBusText *) ibus_serializable_copy ((IBusSerializable *) text);
199 ibus_lookup_table_append_label (dest, text);
206 ibus_lookup_table_new (guint page_size,
208 gboolean cursor_visible,
211 g_assert (page_size > 0);
212 g_assert (page_size <= 16);
214 IBusLookupTable *table;
216 table= g_object_new (IBUS_TYPE_LOOKUP_TABLE, NULL);
218 table->page_size = page_size;
219 table->cursor_pos = cursor_pos;
220 table->cursor_visible = cursor_visible;
221 table->round = round;
222 table->orientation = IBUS_ORIENTATION_SYSTEM;
228 ibus_lookup_table_get_number_of_candidates (IBusLookupTable *table)
230 g_assert (IBUS_IS_LOOKUP_TABLE (table));
232 return table->candidates->len;
236 ibus_lookup_table_append_candidate (IBusLookupTable *table,
239 g_assert (IBUS_IS_LOOKUP_TABLE (table));
240 g_assert (IBUS_IS_TEXT (text));
242 g_object_ref_sink (text);
243 g_array_append_val (table->candidates, text);
247 ibus_lookup_table_get_candidate (IBusLookupTable *table,
250 g_assert (IBUS_IS_LOOKUP_TABLE (table));
252 if (index >= table->candidates->len)
255 return g_array_index (table->candidates, IBusText *, index);
259 ibus_lookup_table_append_label (IBusLookupTable *table,
262 g_assert (IBUS_IS_LOOKUP_TABLE (table));
263 g_assert (IBUS_IS_TEXT (text));
265 g_object_ref_sink (text);
266 g_array_append_val (table->labels, text);
270 ibus_lookup_table_set_label (IBusLookupTable *table,
274 g_assert (IBUS_IS_LOOKUP_TABLE (table));
275 g_assert (IBUS_IS_TEXT (text));
277 if (table->labels->len <= index) {
278 g_array_set_size (table->labels, index + 1);
281 IBusText *old = ibus_lookup_table_get_label (table, index);
283 g_object_unref (old);
286 g_object_ref_sink (text);
287 g_array_index (table->labels, IBusText *, index) = text;
291 ibus_lookup_table_get_label (IBusLookupTable *table,
294 g_assert (IBUS_IS_LOOKUP_TABLE (table));
296 if (index >= table->labels->len)
299 return g_array_index (table->labels, IBusText *, index);
303 ibus_lookup_table_clear (IBusLookupTable *table)
305 g_assert (IBUS_IS_LOOKUP_TABLE (table));
309 for (index = 0; index < table->candidates->len; index ++) {
310 g_object_unref (g_array_index (table->candidates, IBusText *, index));
313 g_array_set_size (table->candidates, 0);
315 table->cursor_pos = 0;
319 ibus_lookup_table_set_cursor_pos (IBusLookupTable *table,
322 g_assert (IBUS_IS_LOOKUP_TABLE (table));
323 g_assert (cursor_pos < table->candidates->len);
325 table->cursor_pos = cursor_pos;
329 ibus_lookup_table_get_cursor_pos (IBusLookupTable *table)
331 g_assert (IBUS_IS_LOOKUP_TABLE (table));
333 return table->cursor_pos;
337 ibus_lookup_table_get_cursor_in_page (IBusLookupTable *table)
339 g_assert (IBUS_IS_LOOKUP_TABLE (table));
341 return table->cursor_pos % table->page_size;
345 ibus_lookup_table_set_cursor_visible (IBusLookupTable *table,
348 g_assert (IBUS_IS_LOOKUP_TABLE (table));
350 table->cursor_visible = visible;
354 ibus_lookup_table_is_cursor_visible (IBusLookupTable *table)
356 g_assert (IBUS_IS_LOOKUP_TABLE (table));
358 return table->cursor_visible;
362 ibus_lookup_table_set_page_size (IBusLookupTable *table,
365 g_assert (IBUS_IS_LOOKUP_TABLE (table));
366 g_assert (page_size > 0);
368 table->page_size = page_size;
372 ibus_lookup_table_get_page_size (IBusLookupTable *table)
374 g_assert (IBUS_IS_LOOKUP_TABLE (table));
376 return table->page_size;
380 ibus_lookup_table_set_round (IBusLookupTable *table,
383 g_assert (IBUS_IS_LOOKUP_TABLE (table));
385 table->round = round ? TRUE: FALSE;
389 ibus_lookup_table_is_round (IBusLookupTable *table)
391 g_assert (IBUS_IS_LOOKUP_TABLE (table));
397 ibus_lookup_table_set_orientation (IBusLookupTable *table,
400 g_assert (IBUS_IS_LOOKUP_TABLE (table));
401 g_assert (orientation == IBUS_ORIENTATION_HORIZONTAL ||
402 orientation == IBUS_ORIENTATION_VERTICAL ||
403 orientation == IBUS_ORIENTATION_SYSTEM);
405 table->orientation = orientation;
409 ibus_lookup_table_get_orientation (IBusLookupTable *table)
411 g_assert (IBUS_IS_LOOKUP_TABLE (table));
413 return table->orientation;
418 ibus_lookup_table_page_up (IBusLookupTable *table)
420 g_assert (IBUS_IS_LOOKUP_TABLE (table));
422 if (table->cursor_pos < table->page_size) {
430 /* cursor index in page */
431 i = table->cursor_pos % table->page_size;
432 page_nr = (table->candidates->len + table->page_size - 1) / table->page_size;
434 table->cursor_pos = page_nr * table->page_size + i;
435 if (table->cursor_pos >= table->candidates->len) {
436 table->cursor_pos = table->candidates->len - 1;
441 table->cursor_pos -= table->page_size;
446 ibus_lookup_table_page_down (IBusLookupTable *table)
448 g_assert (IBUS_IS_LOOKUP_TABLE (table));
454 /* cursor index in page */
455 i = table->cursor_pos % table->page_size;
456 page = table->cursor_pos / table->page_size;
457 page_nr = (table->candidates->len + table->page_size - 1) / table->page_size;
459 if (page == page_nr - 1) {
463 table->cursor_pos = i;
467 table->cursor_pos += table->page_size;
468 if (table->cursor_pos > table->candidates->len - 1) {
469 table->cursor_pos = table->candidates->len - 1;
475 ibus_lookup_table_cursor_up (IBusLookupTable *table)
477 g_assert (IBUS_IS_LOOKUP_TABLE (table));
479 if (table->cursor_pos == 0) {
483 table->cursor_pos = table->candidates->len - 1;
487 table->cursor_pos --;
493 ibus_lookup_table_cursor_down (IBusLookupTable *table)
495 g_assert (IBUS_IS_LOOKUP_TABLE (table));
497 if (table->cursor_pos == table->candidates->len - 1) {
501 table->cursor_pos = 0;
505 table->cursor_pos ++;