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.1 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 Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22 #include "ibusproperty.h"
23 #include "ibusproplist.h"
24 #include "ibusenumtypes.h"
44 /* _IBusPropertyPrivate */
45 struct _IBusPropertyPrivate {
57 IBusPropList *sub_props;
60 #define IBUS_PROPERTY_GET_PRIVATE(o) \
61 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_PROPERTY, IBusPropertyPrivate))
63 /* functions prototype */
64 static void ibus_property_set_property (IBusProperty *prop,
68 static void ibus_property_get_property (IBusProperty *prop,
72 static void ibus_property_destroy (IBusProperty *prop);
73 static gboolean ibus_property_serialize (IBusProperty *prop,
74 GVariantBuilder *builder);
75 static gint ibus_property_deserialize (IBusProperty *prop,
77 static gboolean ibus_property_copy (IBusProperty *dest,
78 const IBusProperty *src);
80 G_DEFINE_TYPE (IBusProperty, ibus_property, IBUS_TYPE_SERIALIZABLE)
83 ibus_property_class_init (IBusPropertyClass *class)
85 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
86 IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
87 IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
89 g_type_class_add_private (class, sizeof (IBusPropertyPrivate));
91 gobject_class->set_property = (GObjectSetPropertyFunc) ibus_property_set_property;
92 gobject_class->get_property = (GObjectGetPropertyFunc) ibus_property_get_property;
94 object_class->destroy = (IBusObjectDestroyFunc) ibus_property_destroy;
96 serializable_class->serialize = (IBusSerializableSerializeFunc) ibus_property_serialize;
97 serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_property_deserialize;
98 serializable_class->copy = (IBusSerializableCopyFunc) ibus_property_copy;
100 /* install properties */
104 * The key of property
106 g_object_class_install_property (gobject_class,
108 g_param_spec_string ("key",
110 "The key of property",
112 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
117 * The icon of property
119 g_object_class_install_property (gobject_class,
121 g_param_spec_string ("icon",
123 "The icon of property",
130 * The label of property
132 g_object_class_install_property (gobject_class,
134 g_param_spec_object("label",
136 "The label of property",
138 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
141 * IBusPropert:symbol:
143 * The symbol of property
145 g_object_class_install_property (gobject_class,
147 g_param_spec_object("symbol",
149 "The symbol of property",
151 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
154 * IBusPropert:tooltip:
156 * The tooltip of property
158 g_object_class_install_property (gobject_class,
160 g_param_spec_object("tooltip",
162 "The tooltip of property",
167 * IBusPropert:sensitive:
169 * The sensitive of property
171 g_object_class_install_property (gobject_class,
173 g_param_spec_boolean("sensitive",
175 "The sensitive of property",
180 * IBusPropert:visible:
182 * The visible of property
184 g_object_class_install_property (gobject_class,
186 g_param_spec_boolean("visible",
188 "The visible of property",
195 * The type of property
197 g_object_class_install_property (gobject_class,
199 g_param_spec_enum("prop-type",
201 "The type of property",
204 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
208 * The state of property
210 g_object_class_install_property (gobject_class,
212 g_param_spec_enum("state",
214 "The state of property",
215 IBUS_TYPE_PROP_STATE,
216 PROP_STATE_UNCHECKED,
220 * IBusPropert:sub-props:
222 * The sub properties of property
224 g_object_class_install_property (gobject_class,
226 g_param_spec_object("sub-props",
228 "The sub properties of property",
234 ibus_property_init (IBusProperty *prop)
236 prop->priv = IBUS_PROPERTY_GET_PRIVATE (prop);
238 ibus_property_set_label (prop, NULL);
239 ibus_property_set_symbol (prop, NULL);
240 ibus_property_set_tooltip (prop, NULL);
241 ibus_property_set_sub_props (prop, NULL);
245 ibus_property_set_property (IBusProperty *prop,
252 g_assert (prop->priv->key == NULL);
253 prop->priv->key = g_value_dup_string (value);
256 ibus_property_set_icon (prop, g_value_get_string (value));
259 ibus_property_set_label (prop, g_value_get_object (value));
262 ibus_property_set_symbol (prop, g_value_get_object (value));
265 ibus_property_set_tooltip (prop, g_value_get_object (value));
268 ibus_property_set_sensitive (prop, g_value_get_boolean (value));
271 ibus_property_set_visible (prop, g_value_get_boolean (value));
274 prop->priv->type = g_value_get_enum (value);
277 ibus_property_set_state (prop, g_value_get_enum (value));
280 ibus_property_set_sub_props (prop,
281 (IBusPropList *)g_value_get_object (value));
284 G_OBJECT_WARN_INVALID_PROPERTY_ID (prop, prop_id, pspec);
289 ibus_property_get_property (IBusProperty *prop,
296 g_value_set_string (value, ibus_property_get_key (prop));
299 g_value_set_string (value, ibus_property_get_icon (prop));
302 g_value_set_object (value, ibus_property_get_label (prop));
305 g_value_set_object (value, ibus_property_get_symbol (prop));
308 g_value_set_object (value, ibus_property_get_tooltip (prop));
311 g_value_set_boolean (value, ibus_property_get_sensitive (prop));
314 g_value_set_boolean (value, ibus_property_get_visible (prop));
317 g_value_set_enum (value, ibus_property_get_prop_type (prop));
320 g_value_set_enum (value, ibus_property_get_state (prop));
323 g_value_set_object (value, ibus_property_get_sub_props (prop));
326 G_OBJECT_WARN_INVALID_PROPERTY_ID (prop, prop_id, pspec);
331 ibus_property_destroy (IBusProperty *prop)
333 g_free (prop->priv->key);
334 prop->priv->key = NULL;
336 g_free (prop->priv->icon);
337 prop->priv->icon = NULL;
339 if (prop->priv->label) {
340 g_object_unref (prop->priv->label);
341 prop->priv->label = NULL;
344 if (prop->priv->symbol) {
345 g_object_unref (prop->priv->symbol);
346 prop->priv->symbol = NULL;
349 if (prop->priv->tooltip) {
350 g_object_unref (prop->priv->tooltip);
351 prop->priv->tooltip = NULL;
354 if (prop->priv->sub_props) {
355 g_object_unref (prop->priv->sub_props);
356 prop->priv->sub_props = NULL;
359 IBUS_OBJECT_CLASS (ibus_property_parent_class)->destroy ((IBusObject *)prop);
363 ibus_property_serialize (IBusProperty *prop,
364 GVariantBuilder *builder)
368 retval = IBUS_SERIALIZABLE_CLASS (ibus_property_parent_class)->serialize ((IBusSerializable *) prop, builder);
369 g_return_val_if_fail (retval, FALSE);
371 g_return_val_if_fail (IBUS_IS_PROPERTY (prop), FALSE);
373 g_variant_builder_add (builder, "s", prop->priv->key);
374 g_variant_builder_add (builder, "u", prop->priv->type);
375 g_variant_builder_add (builder, "v",
376 ibus_serializable_serialize ((IBusSerializable *)prop->priv->label));
377 g_variant_builder_add (builder, "s", prop->priv->icon);
378 g_variant_builder_add (builder, "v",
379 ibus_serializable_serialize ((IBusSerializable *)prop->priv->tooltip));
380 g_variant_builder_add (builder, "b", prop->priv->sensitive);
381 g_variant_builder_add (builder, "b", prop->priv->visible);
382 g_variant_builder_add (builder, "u", prop->priv->state);
383 g_variant_builder_add (builder, "v",
384 ibus_serializable_serialize ((IBusSerializable *)prop->priv->sub_props));
385 /* Keep the serialized order for the compatibility when add new members. */
386 g_variant_builder_add (builder, "v",
387 ibus_serializable_serialize ((IBusSerializable *)prop->priv->symbol));
393 ibus_property_deserialize (IBusProperty *prop,
398 retval = IBUS_SERIALIZABLE_CLASS (ibus_property_parent_class)->deserialize ((IBusSerializable *) prop, variant);
399 g_return_val_if_fail (retval, 0);
401 g_variant_get_child (variant, retval++, "s", &prop->priv->key);
402 g_variant_get_child (variant, retval++, "u", &prop->priv->type);
404 GVariant *subvar = g_variant_get_child_value (variant, retval++);
405 prop->priv->label = IBUS_TEXT (ibus_serializable_deserialize (subvar));
406 g_object_ref_sink (prop->priv->label);
407 g_variant_unref (subvar);
409 g_variant_get_child (variant, retval++, "s", &prop->priv->icon);
411 subvar = g_variant_get_child_value (variant, retval++);
412 prop->priv->tooltip = IBUS_TEXT (ibus_serializable_deserialize (subvar));
413 g_object_ref_sink (prop->priv->tooltip);
414 g_variant_unref (subvar);
416 g_variant_get_child (variant, retval++, "b", &prop->priv->sensitive);
417 g_variant_get_child (variant, retval++, "b", &prop->priv->visible);
418 g_variant_get_child (variant, retval++, "u", &prop->priv->state);
420 subvar = g_variant_get_child_value (variant, retval++);
421 prop->priv->sub_props = IBUS_PROP_LIST (ibus_serializable_deserialize (subvar));
422 g_object_ref_sink (prop->priv->sub_props);
423 g_variant_unref (subvar);
425 /* Keep the serialized order for the compatibility when add new members. */
426 subvar = g_variant_get_child_value (variant, retval++);
427 prop->priv->symbol = IBUS_TEXT (ibus_serializable_deserialize (subvar));
428 g_object_ref_sink (prop->priv->symbol);
429 g_variant_unref (subvar);
435 ibus_property_copy (IBusProperty *dest,
436 const IBusProperty *src)
440 retval = IBUS_SERIALIZABLE_CLASS (ibus_property_parent_class)->copy ((IBusSerializable *) dest, (IBusSerializable *) src);
441 g_return_val_if_fail (retval, FALSE);
443 g_return_val_if_fail (IBUS_IS_PROPERTY (dest), FALSE);
444 g_return_val_if_fail (IBUS_IS_PROPERTY (src), FALSE);
446 dest->priv->key = g_strdup (src->priv->key);
447 dest->priv->icon = g_strdup (src->priv->icon);
448 if (src->priv->label) {
449 dest->priv->label = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->priv->label);
452 dest->priv->label = ibus_text_new_from_static_string ("");
453 if (src->priv->symbol) {
454 dest->priv->symbol = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->priv->symbol);
457 dest->priv->symbol = ibus_text_new_from_static_string ("");
458 if (src->priv->tooltip) {
459 dest->priv->tooltip = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->priv->tooltip);
462 dest->priv->tooltip = ibus_text_new_from_static_string ("");
464 dest->priv->sensitive = src->priv->sensitive;
465 dest->priv->visible = src->priv->visible;
466 dest->priv->type = src->priv->type;
467 dest->priv->state = src->priv->state;
469 dest->priv->sub_props = (IBusPropList *) ibus_serializable_copy ((IBusSerializable *) src->priv->sub_props);
475 ibus_property_new (const gchar *key,
485 g_return_val_if_fail (key != NULL, NULL);
486 g_return_val_if_fail (type >= PROP_TYPE_NORMAL &&
487 type <= PROP_TYPE_SEPARATOR,
490 return ibus_property_new_varargs ("key", key,
495 "sensitive", sensitive,
503 ibus_property_new_varargs (const gchar *first_property_name, ...)
508 g_assert (first_property_name);
510 va_start (var_args, first_property_name);
511 prop = (IBusProperty *) g_object_new_valist (IBUS_TYPE_PROPERTY,
516 g_assert (prop->priv->key);
517 g_assert (prop->priv->type >= PROP_TYPE_NORMAL &&
518 prop->priv->type <= PROP_TYPE_SEPARATOR);
523 #define IBUS_PROPERTY_GET_FIELD(field, return_type) \
525 ibus_property_get_ ## field (IBusProperty *prop) \
527 return prop->priv->field; \
530 IBUS_PROPERTY_GET_FIELD (key, const gchar *)
531 IBUS_PROPERTY_GET_FIELD (icon, const gchar *)
532 IBUS_PROPERTY_GET_FIELD (label, IBusText *)
533 IBUS_PROPERTY_GET_FIELD (symbol, IBusText *)
534 IBUS_PROPERTY_GET_FIELD (tooltip, IBusText *)
535 IBUS_PROPERTY_GET_FIELD (sensitive, gboolean)
536 IBUS_PROPERTY_GET_FIELD (visible, gboolean)
537 IBUS_PROPERTY_GET_FIELD (state, IBusPropState)
538 IBUS_PROPERTY_GET_FIELD (sub_props, IBusPropList *)
539 #undef IBUS_PROPERTY_GET_FIELD
541 /* ibus_property_get_type() exists */
543 ibus_property_get_prop_type (IBusProperty *prop)
545 g_assert (IBUS_IS_PROPERTY (prop));
546 return prop->priv->type;
550 ibus_property_set_label (IBusProperty *prop,
553 g_assert (IBUS_IS_PROPERTY (prop));
554 g_return_if_fail (label == NULL || IBUS_IS_TEXT (label));
556 if (prop->priv->label) {
557 g_object_unref (prop->priv->label);
561 prop->priv->label = ibus_text_new_from_static_string ("");
564 prop->priv->label = g_object_ref_sink (label);
569 ibus_property_set_symbol (IBusProperty *prop,
572 g_assert (IBUS_IS_PROPERTY (prop));
573 g_return_if_fail (symbol == NULL || IBUS_IS_TEXT (symbol));
575 if (prop->priv->symbol) {
576 g_object_unref (prop->priv->symbol);
579 if (symbol == NULL) {
580 prop->priv->symbol = ibus_text_new_from_static_string ("");
583 prop->priv->symbol = g_object_ref_sink (symbol);
588 ibus_property_set_icon (IBusProperty *prop,
591 g_assert (IBUS_IS_PROPERTY (prop));
593 g_free (prop->priv->icon);
594 prop->priv->icon = g_strdup (icon != NULL ? icon : "");
598 ibus_property_set_tooltip (IBusProperty *prop,
601 g_assert (IBUS_IS_PROPERTY (prop));
602 g_assert (tooltip == NULL || IBUS_IS_TEXT (tooltip));
604 IBusPropertyPrivate *priv = prop->priv;
607 g_object_unref (priv->tooltip);
610 if (tooltip == NULL) {
611 priv->tooltip = ibus_text_new_from_static_string ("");
612 g_object_ref_sink (priv->tooltip);
615 priv->tooltip = tooltip;
616 g_object_ref_sink (priv->tooltip);
621 ibus_property_set_sensitive (IBusProperty *prop,
624 g_assert (IBUS_IS_PROPERTY (prop));
625 prop->priv->sensitive = sensitive;
629 ibus_property_set_visible (IBusProperty *prop,
632 g_assert (IBUS_IS_PROPERTY (prop));
633 prop->priv->visible = visible;
637 ibus_property_set_state (IBusProperty *prop,
640 g_assert (IBUS_IS_PROPERTY (prop));
641 g_assert (state == PROP_STATE_UNCHECKED ||
642 state == PROP_STATE_CHECKED ||
643 state == PROP_STATE_INCONSISTENT);
645 prop->priv->state = state;
649 ibus_property_set_sub_props (IBusProperty *prop,
650 IBusPropList *prop_list)
652 g_assert (IBUS_IS_PROPERTY (prop));
653 g_assert (IBUS_IS_PROP_LIST (prop_list) || prop_list == NULL);
655 IBusPropertyPrivate *priv = prop->priv;
657 if (priv->sub_props) {
658 g_object_unref (priv->sub_props);
662 priv->sub_props = prop_list;
663 g_object_ref_sink (prop_list);
666 priv->sub_props = ibus_prop_list_new ();
667 g_object_ref_sink (priv->sub_props);
672 ibus_property_update (IBusProperty *prop,
673 IBusProperty *prop_update)
675 g_assert (IBUS_IS_PROPERTY (prop));
676 g_assert (IBUS_IS_PROPERTY (prop_update));
678 IBusPropertyPrivate *priv = prop->priv;
679 IBusPropertyPrivate *priv_update = prop_update->priv;
681 if (g_strcmp0 (priv->key, priv_update->key) != 0) {
682 return ibus_prop_list_update_property (priv->sub_props, prop_update);
685 /* Do not support update prop type */
686 g_assert (priv->type == priv_update->type);
688 ibus_property_set_icon (prop, ibus_property_get_icon (prop_update));
689 ibus_property_set_label (prop, ibus_property_get_label (prop_update));
690 ibus_property_set_symbol (prop, ibus_property_get_symbol (prop_update));
691 ibus_property_set_tooltip (prop, ibus_property_get_tooltip (prop_update));
692 ibus_property_set_visible (prop, ibus_property_get_visible (prop_update));
693 ibus_property_set_state (prop, ibus_property_get_state (prop_update));
694 ibus_property_set_sensitive (prop, ibus_property_get_sensitive (prop_update));
696 /* Do not support update sub props */