1 /*
2 * Copyright © 2014 Red Hat, Inc. All rights reserved.
3 * Copyright © 2014 Ding-Yi Chen <dchen@redhat.com>
4 *
5 * This file is part of the ibus-chewing Project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program 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
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22 #include <ibus.h>
23 #include <glib.h>
24 #include "MakerDialogUtil.h"
25 #include "GSettingsBackend.h"
26
mkdg_g_variant_type_string(GType gType)27 const gchar *mkdg_g_variant_type_string(GType gType)
28 {
29 switch (gType) {
30 case G_TYPE_BOOLEAN:
31 return (const gchar *) G_VARIANT_TYPE_BOOLEAN;
32 case G_TYPE_UINT:
33 return (const gchar *) G_VARIANT_TYPE_UINT32;
34 case G_TYPE_UINT64:
35 return (const gchar *) G_VARIANT_TYPE_UINT64;
36 case G_TYPE_INT:
37 return (const gchar *) G_VARIANT_TYPE_INT32;
38 case G_TYPE_INT64:
39 return (const gchar *) G_VARIANT_TYPE_INT64;
40 case G_TYPE_STRING:
41 return (const gchar *) G_VARIANT_TYPE_STRING;
42 default:
43 break;
44 }
45 return NULL;
46 }
47
mkdg_g_settings_attr_append(gchar * buf,gint bufferSize,const gchar * attr,const gchar * value)48 gchar *mkdg_g_settings_attr_append(gchar * buf, gint bufferSize,
49 const gchar * attr, const gchar * value)
50 {
51 if (STRING_IS_EMPTY(attr))
52 return buf;
53 if (!STRING_IS_EMPTY(buf))
54 g_strlcat(buf, " ", bufferSize);
55
56 return buf;
57 }
58
mkdg_g_variant_to_string(GVariant * gVar)59 gchar *mkdg_g_variant_to_string(GVariant * gVar)
60 {
61 static gchar result[MAKER_DIALOG_VALUE_LENGTH];
62 result[0] = '\0';
63 const GVariantType *gVType = g_variant_get_type(gVar);
64 if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_BOOLEAN)) {
65 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH,
66 g_variant_get_boolean(gVar) ? "1" : "0");
67 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_UINT16)) {
68 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%" G_GUINT16_FORMAT,
69 g_variant_get_uint16(gVar));
70 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_UINT32)) {
71 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%" G_GUINT32_FORMAT,
72 g_variant_get_uint32(gVar));
73 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_UINT64)) {
74 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%" G_GUINT64_FORMAT,
75 g_variant_get_uint64(gVar));
76 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_INT16)) {
77 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%" G_GINT16_FORMAT,
78 g_variant_get_int16(gVar));
79 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_INT32)) {
80 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%" G_GINT32_FORMAT,
81 g_variant_get_int32(gVar));
82 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_INT64)) {
83 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%" G_GINT64_FORMAT,
84 g_variant_get_int64(gVar));
85 } else if (g_variant_type_is_subtype_of(gVType, G_VARIANT_TYPE_STRING)) {
86 g_snprintf(result, MAKER_DIALOG_VALUE_LENGTH, "%s",
87 g_variant_get_string(gVar, NULL));
88 }
89 return result;
90 }
91
92 /*============================================
93 * Class routines
94 */
95
96 #define KEY_BUFFER_SIZE 300
97
98 /*=== Start Schema Writing ===*/
mkdg_g_settings_write_schema_spec(FILE * file,MkdgPropertySpec * spec)99 gboolean mkdg_g_settings_write_schema_spec(FILE * file,
100 MkdgPropertySpec * spec)
101 {
102 if (spec->propertyFlags & MKDG_PROPERTY_FLAG_NO_BACKEND){
103 return TRUE;
104 }
105 gchar attrBuf[KEY_BUFFER_SIZE];
106 const gchar *typeString = mkdg_g_variant_type_string(spec->valueType);
107 g_strlcpy(attrBuf, "", KEY_BUFFER_SIZE);
108 mkdg_xml_attr_append(attrBuf, KEY_BUFFER_SIZE, "name", spec->key);
109 mkdg_xml_attr_append(attrBuf, KEY_BUFFER_SIZE, "type", typeString);
110 mkdg_xml_tags_write(file, "key",
111 MKDG_XML_TAG_TYPE_BEGIN_ONLY, attrBuf, NULL);
112 /* tag default */
113 g_strlcpy(attrBuf, "", KEY_BUFFER_SIZE);
114 if (spec->propertyFlags & MKDG_PROPERTY_FLAG_HAS_TRANSLATION) {
115 mkdg_xml_attr_append(attrBuf, KEY_BUFFER_SIZE, "l10n", "messages");
116 if (!STRING_IS_EMPTY(spec->translationContext)) {
117 mkdg_xml_attr_append(attrBuf, KEY_BUFFER_SIZE, "context",
118 spec->translationContext);
119 }
120 }
121
122 gchar *valueStr = NULL;
123 switch (spec->valueType) {
124 case G_TYPE_BOOLEAN:
125 valueStr =
126 g_strdup_printf("%s",
127 (STRING_EQUALS(spec->defaultValue, "0")) ?
128 "false" : "true");
129 break;
130 case G_TYPE_STRING:
131 valueStr = g_strdup_printf("\"%s\"", spec->defaultValue);
132 break;
133 default:
134 valueStr = g_strdup_printf("%s", spec->defaultValue);
135 break;
136 }
137 mkdg_xml_tags_write(file, "default",
138 MKDG_XML_TAG_TYPE_SHORT, attrBuf, valueStr);
139 g_free(valueStr);
140 mkdg_xml_tags_write(file, "summary",
141 MKDG_XML_TAG_TYPE_SHORT, NULL, spec->label);
142 mkdg_xml_tags_write(file, "description",
143 MKDG_XML_TAG_TYPE_LONG, NULL, spec->tooltip);
144 mkdg_xml_tags_write(file, "key",
145 MKDG_XML_TAG_TYPE_END_ONLY, NULL, NULL);
146 return TRUE;
147 }
148
mkdg_g_settings_write_schema_from_spec_array(const gchar * schemaId,const gchar * basePath,FILE * file,MkdgPropertySpec specs[],const gchar * gettextDomain)149 gboolean mkdg_g_settings_write_schema_from_spec_array(const gchar *
150 schemaId,
151 const gchar *
152 basePath,
153 FILE * file,
154 MkdgPropertySpec
155 specs[],
156 const gchar *
157 gettextDomain)
158 {
159 mkdg_log(DEBUG,
160 "mkdg_g_settings_write_schema_from_spec_array(%s,%s,-,-,-,%s)",
161 schemaId, basePath, gettextDomain);
162 gchar attrBuf[KEY_BUFFER_SIZE];
163 gchar path[KEY_BUFFER_SIZE];
164 g_snprintf(path, KEY_BUFFER_SIZE, "%s", basePath);
165
166 /* Header */
167 mkdg_xml_tags_write(file, "schemalist",
168 MKDG_XML_TAG_TYPE_BEGIN_ONLY, NULL, NULL);
169 g_strlcpy(attrBuf, "", KEY_BUFFER_SIZE);
170 mkdg_xml_attr_append(attrBuf, KEY_BUFFER_SIZE, "id", schemaId);
171 mkdg_xml_attr_append(attrBuf, KEY_BUFFER_SIZE, "path", path);
172 mkdg_xml_attr_append(attrBuf, KEY_BUFFER_SIZE,
173 "gettext-domain", gettextDomain);
174 mkdg_xml_tags_write(file, "schema",
175 MKDG_XML_TAG_TYPE_BEGIN_ONLY, attrBuf, NULL);
176 /* Body */
177 gint i;
178 for (i = 0; (&specs[i])->valueType != G_TYPE_INVALID; i++) {
179 mkdg_g_settings_write_schema_spec(file, &specs[i]);
180 }
181
182 /* Footer */
183 mkdg_xml_tags_write(file, "schema",
184 MKDG_XML_TAG_TYPE_END_ONLY, NULL, NULL);
185 mkdg_xml_tags_write(file, "schemalist",
186 MKDG_XML_TAG_TYPE_END_ONLY, NULL, NULL);
187 return TRUE;
188 }
189
190 /*=== End Schema Writing ===*/
191
mkdg_g_settings_read_value(GSettings * settings,GValue * value,const gchar * key)192 GValue *mkdg_g_settings_read_value(GSettings * settings,
193 GValue * value, const gchar * key)
194 {
195 GVariant *confValue = g_settings_get_value(settings, key);
196 mkdg_log(DEBUG, "mkdg_g_settings_read_value(-,-,%s)", key);
197 if (confValue == NULL) {
198 mkdg_log(ERROR, "mkdg_g_settings_read_value(-,-,%s)", key);
199 return NULL;
200 }
201 mkdg_g_variant_to_g_value(confValue, value);
202 return value;
203 }
204
205
206 /*============================================
207 * Interface routines
208 */
mkdg_g_settings_backend_get_key(MkdgBackend * backend,const gchar * section,const gchar * key,gpointer userData)209 gchar *mkdg_g_settings_backend_get_key(MkdgBackend * backend,
210 const gchar * section,
211 const gchar * key,
212 gpointer userData)
213 {
214 return (gchar *) key;
215 }
216
mkdg_g_settings_backend_read_value(MkdgBackend * backend,GValue * value,const gchar * section,const gchar * key,gpointer userData)217 GValue *mkdg_g_settings_backend_read_value(MkdgBackend * backend,
218 GValue * value,
219 const gchar * section,
220 const gchar * key,
221 gpointer userData)
222 {
223 GSettings *config = (GSettings *) backend->config;
224 return mkdg_g_settings_read_value(config, value, key);
225 }
226
227
mkdg_g_settings_backend_write_value(MkdgBackend * backend,GValue * value,const gchar * section,const gchar * key,gpointer userData)228 gboolean mkdg_g_settings_backend_write_value(MkdgBackend *
229 backend,
230 GValue *
231 value,
232 const gchar *
233 section,
234 const gchar *
235 key, gpointer userData)
236 {
237 GSettings *config = (GSettings *) backend->config;
238 GVariant *confValue =
239 g_variant_ref_sink(mkdg_g_value_to_g_variant(value));
240 mkdg_log(DEBUG, "mkdg_g_settings_write_value(-,%s,%s) %s",
241 mkdg_g_value_to_string(value), key,
242 mkdg_g_variant_to_string(confValue));
243 gboolean result = g_settings_set_value(config, key, confValue);
244 g_settings_sync();
245 if (!result) {
246 mkdg_log(ERROR,
247 "mkdg_g_settings_backend_write_value(-,%s,%s,%s,-): Fail g_settings_set_value",
248 mkdg_g_value_to_string(value), section, key);
249 }
250 g_variant_unref(confValue);
251 return result;
252 }
253
mkdg_g_settings_backend_new(const gchar * schemaId,const gchar * basePath,gpointer auxData)254 MkdgBackend *mkdg_g_settings_backend_new(const gchar *
255 schemaId,
256 const gchar *
257 basePath, gpointer auxData)
258 {
259 GSettings *client = g_settings_new(schemaId);
260 MkdgBackend *result =
261 mkdg_backend_new(GSETTINGS_BACKEND_ID, (gpointer) client, basePath,
262 auxData);
263
264 result->getKeyFunc = mkdg_g_settings_backend_get_key;
265 result->readFunc = mkdg_g_settings_backend_read_value;
266 result->writeFunc = mkdg_g_settings_backend_write_value;
267 return result;
268 }
269