1
/* This file is part of Maliit framework
3
* Copyright (C) 2012 Openismus GmbH
5
* Contact: maliit-discuss@lists.maliit.org
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 licence, 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.
23
#include "maliitpluginsettingsprivate.h"
24
#include "maliitsettingsentryprivate.h"
26
#include <dbus/dbus-glib.h>
29
* SECTION:maliitsettingsentry
30
* @short_description: settings entry
31
* @title: MaliitSettingsEntry
32
* @see_also: #MaliitSettingsEntry, #MaliitPluginSettings
34
* @include: maliit/maliitsettingsentry.h
36
* The #MaliitSettingsEntry is a class holding single plugin
37
* setting. It can be one of several available types
38
* (#MaliitSettingsEntryType). It can also have some attributes like
39
* value domain (MALIIT_SETTING_VALUE_DOMAIN()), default value
40
* (MALIIT_SETTING_DEFAULT_VALUE) and value ranges
41
* (MALIIT_SETTING_VALUE_RANGE_MIN() and
42
* MALIIT_SETTING_VALUE_RANGE_MAX()).
45
struct _MaliitSettingsEntryPrivate
47
MaliitAttributeExtension *extension;
50
MaliitSettingsEntryType type;
52
GHashTable *attributes;
54
guint extension_signal_id;
57
G_DEFINE_TYPE (MaliitSettingsEntry, maliit_settings_entry, G_TYPE_OBJECT)
79
static guint signals[LAST_SIGNAL] = { 0 };
82
maliit_settings_entry_finalize (GObject *object)
84
MaliitSettingsEntry *entry = MALIIT_SETTINGS_ENTRY (object);
85
MaliitSettingsEntryPrivate *priv = entry->priv;
87
g_free (priv->description);
88
g_free (priv->extension_key);
90
G_OBJECT_CLASS (maliit_settings_entry_parent_class)->finalize (object);
94
maliit_settings_entry_dispose (GObject *object)
96
MaliitSettingsEntry *entry = MALIIT_SETTINGS_ENTRY (object);
97
MaliitSettingsEntryPrivate *priv = entry->priv;
99
if (priv->extension_signal_id) {
100
if (priv->extension) {
101
g_signal_handler_disconnect (priv->extension,
102
priv->extension_signal_id);
104
priv->extension_signal_id = 0;
106
g_clear_object (&priv->extension);
107
if (priv->attributes) {
108
GHashTable *attributes = priv->attributes;
110
priv->attributes = NULL;
111
g_hash_table_unref (attributes);
114
G_OBJECT_CLASS (maliit_settings_entry_parent_class)->dispose (object);
118
maliit_settings_entry_set_property (GObject *object,
123
MaliitSettingsEntry *entry = MALIIT_SETTINGS_ENTRY (object);
124
MaliitSettingsEntryPrivate *priv = entry->priv;
128
if (priv->extension) {
129
g_object_unref (priv->extension);
131
priv->extension = g_value_dup_object (value);
133
case PROP_DESCRIPTION:
134
g_free (priv->description);
135
priv->description = g_value_dup_string (value);
137
case PROP_EXTENSION_KEY:
138
g_free (priv->extension_key);
139
priv->extension_key = g_value_dup_string (value);
142
priv->type = g_value_get_enum (value);
145
priv->valid = g_value_get_boolean (value);
148
maliit_settings_entry_set_value (entry, g_value_get_variant (value));
150
case PROP_ATTRIBUTES:
151
if (priv->attributes) {
152
g_hash_table_unref (priv->attributes);
154
priv->attributes = g_value_dup_boxed (value);
157
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
163
maliit_settings_entry_get_property (GObject *object,
168
MaliitSettingsEntry *entry = MALIIT_SETTINGS_ENTRY (object);
169
MaliitSettingsEntryPrivate *priv = entry->priv;
172
/* PROP_EXTENSION is write only, construction only - omitted here */
173
case PROP_DESCRIPTION:
174
g_value_set_string (value, priv->description);
176
case PROP_EXTENSION_KEY:
177
g_value_set_string (value, priv->extension_key);
180
g_value_set_enum (value, priv->type);
183
g_value_set_boolean (value, priv->valid);
186
g_value_set_variant (value,
187
maliit_settings_entry_get_value (entry));
189
case PROP_ATTRIBUTES:
190
g_value_set_boxed (value, priv->attributes);
193
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
199
value_changed(MaliitSettingsEntry *entry,
201
GVariant *value G_GNUC_UNUSED,
202
gpointer user_data G_GNUC_UNUSED)
204
if (!g_strcmp0 (key, entry->priv->extension_key)) {
205
g_signal_emit(entry, signals[VALUE_CHANGED], 0);
210
maliit_settings_entry_constructed (GObject *object)
212
MaliitSettingsEntry *entry = MALIIT_SETTINGS_ENTRY (object);
213
MaliitSettingsEntryPrivate *priv = entry->priv;
215
if (priv->extension) {
216
priv->extension_signal_id = g_signal_connect_swapped (priv->extension,
217
"extended-attribute-changed",
218
G_CALLBACK (value_changed),
224
maliit_settings_entry_class_init (MaliitSettingsEntryClass *entry_class)
226
GObjectClass *g_object_class = G_OBJECT_CLASS (entry_class);
228
g_object_class->finalize = maliit_settings_entry_finalize;
229
g_object_class->dispose = maliit_settings_entry_dispose;
230
g_object_class->set_property = maliit_settings_entry_set_property;
231
g_object_class->get_property = maliit_settings_entry_get_property;
232
g_object_class->constructed = maliit_settings_entry_constructed;
235
* MaliitSettingsEntry:extension:
237
* #MaliitAttributeExtension used by this entry.
239
g_object_class_install_property (g_object_class,
241
g_param_spec_object ("extension",
242
"Extension", /* TODO: mark as translatable? */
243
"Extension used by this entry", /* TODO: mark as translatable? */
244
MALIIT_TYPE_ATTRIBUTE_EXTENSION,
246
G_PARAM_CONSTRUCT_ONLY |
247
G_PARAM_STATIC_NAME |
248
G_PARAM_STATIC_BLURB |
249
G_PARAM_STATIC_NICK));
252
* MaliitSettingsEntry:description:
254
* Description of the entry.
256
g_object_class_install_property (g_object_class,
258
g_param_spec_string ("description",
259
"Description", /* TODO: mark as translatable? */
260
"Description of the entry", /* TODO: mark as translatable? */
264
G_PARAM_CONSTRUCT_ONLY |
265
G_PARAM_STATIC_NAME |
266
G_PARAM_STATIC_BLURB |
267
G_PARAM_STATIC_NICK));
270
* MaliitSettingsEntry:extension-key:
274
g_object_class_install_property (g_object_class,
276
g_param_spec_string ("extension-key",
277
"Extension key", /* TODO: mark as translatable? */
278
"Key of the entry.", /* TODO: mark as translatable? */
282
G_PARAM_CONSTRUCT_ONLY |
283
G_PARAM_STATIC_NAME |
284
G_PARAM_STATIC_BLURB |
285
G_PARAM_STATIC_NICK));
288
* MaliitSettingsEntry:type:
292
g_object_class_install_property (g_object_class,
294
g_param_spec_enum ("type",
295
"Type", /* TODO: mark as translatable? */
296
"Type if the entry", /* TODO: mark as translatable? */
297
MALIIT_TYPE_SETTINGS_ENTRY_TYPE,
301
G_PARAM_CONSTRUCT_ONLY |
302
G_PARAM_STATIC_NAME |
303
G_PARAM_STATIC_BLURB |
304
G_PARAM_STATIC_NICK));
307
* MaliitSettingsEntry:valid:
309
* Whether entry's value is valid.
311
g_object_class_install_property (g_object_class,
313
g_param_spec_boolean ("valid",
314
"Valid", /* TODO: mark as translatable? */
315
"Whether entry's value is valid", /* TODO: mark as translatable? */
319
G_PARAM_CONSTRUCT_ONLY |
320
G_PARAM_STATIC_NAME |
321
G_PARAM_STATIC_BLURB |
322
G_PARAM_STATIC_NICK));
325
* MaliitSettingsEntry:value:
327
* Value of the entry.
329
g_object_class_install_property (g_object_class,
331
g_param_spec_variant ("value",
332
"Value", /* TODO: mark as translatable? */
333
"Value of the entry", /* TODO: mark as translatable? */
335
g_variant_new_int32 (0),
338
G_PARAM_CONSTRUCT_ONLY |
339
G_PARAM_STATIC_NAME |
340
G_PARAM_STATIC_BLURB |
341
G_PARAM_STATIC_NICK));
344
* MaliitSettingsEntry:attributes:
346
* Attributes of the entry.
348
g_object_class_install_property (g_object_class,
350
g_param_spec_boxed ("attributes",
351
"Attributes", /* TODO: mark as translatable? */
352
"Attributes of the entry", /* TODO: mark as translatable? */
356
G_PARAM_CONSTRUCT_ONLY |
357
G_PARAM_STATIC_NAME |
358
G_PARAM_STATIC_BLURB |
359
G_PARAM_STATIC_NICK));
362
* MaliitSettingsEntry::value-changed:
363
* @entry: The #MaliitSettingsEntry emitting the signal.
365
* Emitted when value of the entry was changed in the plugin.
367
signals[VALUE_CHANGED] =
368
g_signal_new ("value-changed",
369
MALIIT_TYPE_SETTINGS_ENTRY,
374
g_cclosure_marshal_VOID__VOID,
378
g_type_class_add_private (entry_class, sizeof (MaliitSettingsEntryPrivate));
382
maliit_settings_entry_init (MaliitSettingsEntry *entry)
384
MaliitSettingsEntryPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (entry,
385
MALIIT_TYPE_SETTINGS_ENTRY,
386
MaliitSettingsEntryPrivate);
388
priv->extension = NULL;
389
priv->description = NULL;
390
priv->extension_key = NULL;
391
priv->type = MALIIT_STRING_TYPE;
393
priv->attributes = NULL;
394
priv->extension_signal_id = 0;
400
attributes_from_dbus_g_hash_table (GHashTable *dbus_attributes)
402
GHashTable *attributes = g_hash_table_new_full (g_str_hash,
405
(GDestroyNotify)g_variant_unref);
410
g_hash_table_iter_init (&iter, dbus_attributes);
411
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value)) {
412
gchar *new_key = g_strdup (key);
413
GVariant *new_variant = dbus_g_value_build_g_variant (value);
416
g_warning ("Failed to convert GValue (%s) to GVariant", G_VALUE_TYPE_NAME (value));
418
if (g_variant_is_floating (new_variant)) {
419
g_variant_ref_sink (new_variant);
421
g_hash_table_replace (attributes, new_key, new_variant);
428
dbus_info_is_valid (GValueArray *info)
430
static GType expected_types[] = {
431
G_TYPE_STRING, /* description */
432
G_TYPE_STRING, /* extension key */
433
G_TYPE_INT, /* entry type */
434
G_TYPE_BOOLEAN, /* value validity */
435
G_TYPE_INVALID, /* current value, set in the first run */
436
G_TYPE_INVALID /* attributes, set in the first run */
443
if (expected_types[4] == G_TYPE_INVALID) {
444
expected_types[4] = G_TYPE_VALUE;
446
if (expected_types[5] == G_TYPE_INVALID) {
447
expected_types[5] = dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE);
453
if (info->n_values != G_N_ELEMENTS(expected_types)) {
457
for (iter = 0; iter < G_N_ELEMENTS(expected_types); ++iter) {
458
GValue *value = g_value_array_get_nth (info, iter);
463
if (!G_VALUE_HOLDS (value, expected_types[iter])) {
468
enum_value = g_value_get_int (g_value_array_get_nth (info, 2));
470
if (enum_value < MALIIT_STRING_TYPE || enum_value > MALIIT_INT_LIST_TYPE) {
478
* maliit_settings_entry_new_from_dbus_data: (skip)
479
* @info: (transfer none): A #GValueArray of DBus provenance containing entry information.
480
* @extension: (transfer none): A #MaliitAttributeExtensions for #MaliitAttributeSettingsEntry instance.
482
* Creates new settings entry. This is used internally only by
483
* #MaliitPluginSettings.
485
* Returns: (transfer full): The newly created #MaliitSettingsEntry.
487
MaliitSettingsEntry *
488
maliit_settings_entry_new_from_dbus_data (GValueArray *info,
489
MaliitAttributeExtension *extension)
491
const gchar *description;
492
const gchar *extension_key;
493
MaliitSettingsEntryType type;
496
GHashTable *attributes;
497
MaliitSettingsEntry *entry;
499
g_return_val_if_fail (MALIIT_IS_ATTRIBUTE_EXTENSION (extension), NULL);
500
g_return_val_if_fail (dbus_info_is_valid (info), NULL);
502
description = g_value_get_string (g_value_array_get_nth (info, 0));
503
extension_key = g_value_get_string (g_value_array_get_nth (info, 1));
504
type = (MaliitSettingsEntryType) g_value_get_int (g_value_array_get_nth (info, 2));
505
valid = g_value_get_boolean (g_value_array_get_nth (info, 3));
506
value = dbus_g_value_build_g_variant (g_value_get_boxed (g_value_array_get_nth (info, 4)));
508
if (g_variant_is_floating (value)) {
509
g_variant_ref_sink (value);
512
attributes = attributes_from_dbus_g_hash_table (g_value_get_boxed (g_value_array_get_nth (info, 5)));
513
entry = MALIIT_SETTINGS_ENTRY (g_object_new (MALIIT_TYPE_SETTINGS_ENTRY,
514
"extension", extension,
515
"description", description,
516
"extension-key", extension_key,
520
"attributes", attributes,
523
g_hash_table_unref (attributes);
524
g_variant_unref (value);
529
* maliit_settings_entry_get_description:
530
* @entry: (transfer none): The #MaliitSettingsEntry.
532
* Gets description of the entry.
534
* Returns: (transfer none): A description. Returned value should not be modified nor freed.
537
maliit_settings_entry_get_description (MaliitSettingsEntry *entry)
539
g_return_val_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry), NULL);
541
return entry->priv->description;
545
* maliit_settings_entry_get_key:
546
* @entry: (transfer none): The #MaliitSettingsEntry.
548
* Gets key of the entry.
550
* Returns: (transfer none): A key. Returned value should not be modified nor freed.
553
maliit_settings_entry_get_key (MaliitSettingsEntry *entry)
555
g_return_val_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry), NULL);
557
return entry->priv->extension_key;
561
* maliit_settings_entry_get_entry_type:
562
* @entry: (transfer none): The #MaliitSettingsEntry.
564
* Gets type of the entry.
568
MaliitSettingsEntryType
569
maliit_settings_entry_get_entry_type (MaliitSettingsEntry *entry)
571
g_return_val_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry), MALIIT_STRING_TYPE);
573
return entry->priv->type;
577
* maliit_settings_entry_is_current_value_valid:
578
* @entry: (transfer none): The #MaliitSettingsEntry.
580
* Gets whether current value of the entry is valid.
582
* Returns: %TRUE if valid, otherwise %FALSE
585
maliit_settings_entry_is_current_value_valid (MaliitSettingsEntry *entry)
587
g_return_val_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry), FALSE);
589
return entry->priv->valid;
593
* maliit_settings_entry_get_value:
594
* @entry: (transfer none): The #MaliitSettingsEntry.
596
* Gets value of the entry. Check its validity with
597
* maliit_settings_entry_is_current_value_valid() before using it.
599
* Returns: (transfer none): A value.
602
maliit_settings_entry_get_value (MaliitSettingsEntry *entry)
604
GHashTable *attributes;
605
MaliitSettingsEntryPrivate *priv;
607
g_return_val_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry), NULL);
610
attributes = maliit_attribute_extension_get_attributes (priv->extension);
612
return g_hash_table_lookup (attributes, priv->extension_key);
616
* maliit_settings_entry_set_value:
617
* @entry: (transfer none): The #MaliitSettingsEntry.
618
* @value: (transfer none): The #GVariant.
620
* Sets a new value of the entry. Before setting new value, validate
621
* it with maliit_settings_entry_is_value_valid().
624
maliit_settings_entry_set_value (MaliitSettingsEntry *entry,
627
MaliitSettingsEntryPrivate *priv;
629
g_return_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry));
632
maliit_attribute_extension_set_attribute (priv->extension,
638
* maliit_settings_entry_is_value_valid:
639
* @entry: (transfer none): The #MaliitSettingsEntry.
640
* @value: (transfer none): The #GVariant
642
* Checks whether the value is valid one for the entry.
644
* Returns: %TRUE if valid, otherwise %FALSE.
647
maliit_settings_entry_is_value_valid (MaliitSettingsEntry *entry,
650
MaliitSettingsEntryPrivate *priv;
652
g_return_val_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry), FALSE);
655
return maliit_validate_setting_value (priv->type, priv->attributes, value);
659
* maliit_settings_entry_get_attributes:
660
* @entry: (transfer none): The #MaliitSettingsEntry.
662
* Gets attributes of the entry. The keys of the attributes are
663
* MALIIT_SETTING_VALUE_DOMAIN(),
664
* MALIIT_SETTING_VALUE_DOMAIN_DESCRIPTIONS(),
665
* MALIIT_SETTING_VALUE_RANGE_MIN(), MALIIT_SETTING_VALUE_RANGE_MAX()
666
* and MALIIT_SETTING_DEFAULT_VALUE(). Note that these keys don't have
667
* to exist in attributes.
669
* Returns: (transfer none) (element-type utf8 GLib.Variant): Attributes. Returned value should not be modified nor freed.
672
maliit_settings_entry_get_attributes (MaliitSettingsEntry *entry)
674
g_return_val_if_fail (MALIIT_IS_SETTINGS_ENTRY (entry), NULL);
676
return entry->priv->attributes;