Add Ctrl+space customization.
[platform/upstream/ibus.git] / src / ibustext.c
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.
6  *
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.
11  *
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.
16  *
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.
21  */
22 #include "ibustext.h"
23
24 /* functions prototype */
25 static void         ibus_text_destroy      (IBusText            *text);
26 static gboolean     ibus_text_serialize    (IBusText            *text,
27                                             GVariantBuilder     *builder);
28 static int          ibus_text_deserialize  (IBusText            *text,
29                                             GVariant            *variant);
30 static gboolean     ibus_text_copy         (IBusText            *dest,
31                                             const IBusText      *src);
32
33 G_DEFINE_TYPE (IBusText, ibus_text, IBUS_TYPE_SERIALIZABLE)
34
35 static void
36 ibus_text_class_init (IBusTextClass *class)
37 {
38     IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
39     IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
40
41     ibus_text_parent_class = (IBusSerializableClass *) g_type_class_peek_parent (class);
42
43     object_class->destroy = (IBusObjectDestroyFunc) ibus_text_destroy;
44
45     serializable_class->serialize   = (IBusSerializableSerializeFunc) ibus_text_serialize;
46     serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_text_deserialize;
47     serializable_class->copy        = (IBusSerializableCopyFunc) ibus_text_copy;
48 }
49
50 static void
51 ibus_text_init (IBusText *text)
52 {
53     text->is_static = TRUE;
54     text->text = "";
55     text->attrs = NULL;
56 }
57
58 static void
59 ibus_text_destroy (IBusText *text)
60 {
61     if (text->text != NULL && text->is_static == FALSE) {
62         g_free (text->text);
63         text->text = NULL;
64     }
65
66     if (text->attrs) {
67         g_object_unref (text->attrs);
68         text->attrs = NULL;
69     }
70
71     IBUS_OBJECT_CLASS (ibus_text_parent_class)->destroy ((IBusObject *)text);
72 }
73
74 static gboolean
75 ibus_text_serialize (IBusText        *text,
76                      GVariantBuilder *builder)
77 {
78     gboolean retval;
79
80     retval = IBUS_SERIALIZABLE_CLASS (ibus_text_parent_class)->serialize (
81                         (IBusSerializable *)text, builder);
82     g_return_val_if_fail (retval, FALSE);
83
84     g_variant_builder_add (builder, "s", text->text);
85
86     if (text->attrs == NULL) {
87         text->attrs = ibus_attr_list_new ();
88         g_object_ref_sink (text->attrs);
89     }
90     g_variant_builder_add (builder, "v", ibus_serializable_serialize ((IBusSerializable *)text->attrs));
91
92     return TRUE;
93 }
94
95 static gint
96 ibus_text_deserialize (IBusText *text,
97                        GVariant *variant)
98 {
99     gint retval;
100     retval = IBUS_SERIALIZABLE_CLASS (ibus_text_parent_class)->deserialize (
101                             (IBusSerializable *)text, variant);
102
103     if (text->is_static == FALSE)
104         g_free (text->text);
105     g_variant_get_child (variant, retval++, "s", &text->text);
106     text->is_static = FALSE;
107
108     if (text->attrs)
109         g_object_unref (text->attrs);
110
111     GVariant *var = g_variant_get_child_value (variant, retval++);
112     text->attrs = IBUS_ATTR_LIST (ibus_serializable_deserialize (var));
113     g_variant_unref (var);
114     g_object_ref_sink (text->attrs);
115
116     return retval;
117 }
118
119 static gboolean
120 ibus_text_copy (IBusText       *dest,
121                 const IBusText *src)
122 {
123     gboolean retval;
124
125     retval = IBUS_SERIALIZABLE_CLASS (ibus_text_parent_class)->copy (
126                             (IBusSerializable *)dest,
127                             (IBusSerializable *)src);
128     g_return_val_if_fail (retval, FALSE);
129
130     g_return_val_if_fail (IBUS_IS_TEXT (dest), FALSE);
131     g_return_val_if_fail (IBUS_IS_TEXT (src), FALSE);
132
133     dest->text = g_strdup (src->text);
134     dest->is_static = FALSE;
135     if (src->attrs) {
136         dest->attrs = (IBusAttrList *)ibus_serializable_copy ((IBusSerializable *)src->attrs);
137         g_object_ref_sink (dest->attrs);
138     }
139
140     return TRUE;
141 }
142
143 IBusText *
144 ibus_text_new_from_string (const gchar *str)
145 {
146     g_assert (str);
147
148     IBusText *text;
149
150     text= g_object_new (IBUS_TYPE_TEXT, NULL);
151
152     text->is_static = FALSE;
153     text->text = g_strdup (str);
154
155     return text;
156 }
157
158 IBusText *
159 ibus_text_new_from_ucs4 (const gunichar *str)
160 {
161     g_assert (str);
162
163     gchar *buf = g_ucs4_to_utf8 (str, -1, NULL, NULL, NULL);
164     g_return_val_if_fail (buf != NULL, NULL);
165
166     IBusText *text= g_object_new (IBUS_TYPE_TEXT, NULL);
167
168     text->is_static = FALSE;
169     text->text = buf;
170
171     return text;
172 }
173
174 IBusText *
175 ibus_text_new_from_static_string (const gchar *str)
176 {
177     g_assert (str);
178
179     IBusText *text;
180
181     text= g_object_new (IBUS_TYPE_TEXT, NULL);
182
183     text->is_static = TRUE;
184     text->text = (gchar *)str;
185
186     return text;
187 }
188
189 IBusText *
190 ibus_text_new_from_printf (const gchar *format,
191                            ...)
192 {
193     g_assert (format);
194
195     gchar *str;
196     IBusText *text;
197     va_list args;
198
199     va_start (args, format);
200     str = g_strdup_vprintf (format, args);
201     va_end (args);
202
203     g_return_val_if_fail (str != NULL, NULL);
204
205     text= g_object_new (IBUS_TYPE_TEXT, NULL);
206     text->is_static = FALSE;
207     text->text = (gchar *)str;
208
209     return text;
210 }
211
212 IBusText *
213 ibus_text_new_from_unichar (gunichar c)
214 {
215     IBusText *text;
216     gint len;
217
218     g_return_val_if_fail (g_unichar_validate (c), NULL);
219
220     text= g_object_new (IBUS_TYPE_TEXT, NULL);
221
222     text->is_static = FALSE;
223     text->text = (gchar *)g_malloc (12);
224     len = g_unichar_to_utf8 (c, text->text);
225     text->text[len] =  0;
226
227     return text;
228 }
229
230 void
231 ibus_text_append_attribute (IBusText *text,
232                             guint     type,
233                             guint     value,
234                             guint     start_index,
235                             gint      end_index)
236 {
237     g_assert (IBUS_IS_TEXT (text));
238
239     IBusAttribute *attr;
240
241     if (end_index < 0) {
242         end_index  += g_utf8_strlen(text->text, -1) + 1;
243     }
244
245     if (end_index <= 0) {
246         return;
247     }
248
249     if (text->attrs == NULL) {
250         text->attrs = ibus_attr_list_new ();
251     }
252
253     attr = ibus_attribute_new (type, value, start_index, end_index);
254     ibus_attr_list_append (text->attrs, attr);
255 }
256
257 guint
258 ibus_text_get_length (IBusText *text)
259 {
260     return g_utf8_strlen (text->text, -1);
261 }
262
263 gboolean
264 ibus_text_get_is_static (IBusText *text)
265 {
266     return text->is_static;
267 }
268
269 const gchar *
270 ibus_text_get_text (IBusText *text)
271 {
272     return text->text;
273 }
274
275 IBusAttrList *
276 ibus_text_get_attributes (IBusText *text)
277 {
278     return text->attrs;
279 }
280
281 void
282 ibus_text_set_attributes (IBusText     *text,
283                           IBusAttrList *attrs)
284 {
285     if (text->attrs)
286         g_object_unref (text->attrs);
287     text->attrs = attrs;
288     g_object_ref_sink (text->attrs);
289 }