File indexing completed on 2024-05-12 05:36:19

0001 /*
0002     SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only
0005 
0006 */
0007 
0008 #include <QDebug>
0009 #include <QString>
0010 
0011 #include "gsettingsitem.h"
0012 
0013 QVariant GSettingsItem::value(const QString &key) const
0014 {
0015     if (!m_settings) {
0016         return QVariant();
0017     }
0018 
0019     GVariant *gvalue = g_settings_get_value(m_settings, key.toLatin1().data());
0020 
0021     QVariant toReturn;
0022 
0023     switch (g_variant_classify(gvalue)) {
0024     case G_VARIANT_CLASS_BOOLEAN:
0025         toReturn = QVariant(static_cast<bool>(g_variant_get_boolean(gvalue)));
0026         break;
0027     case G_VARIANT_CLASS_STRING:
0028         toReturn = QVariant(QString::fromUtf8(g_variant_get_string(gvalue, nullptr)));
0029         break;
0030     case G_VARIANT_CLASS_ARRAY:
0031         if (g_variant_is_of_type(gvalue, G_VARIANT_TYPE_STRING_ARRAY)) {
0032             GVariantIter iter;
0033             QStringList list;
0034             const gchar *str;
0035             g_variant_iter_init(&iter, gvalue);
0036             while (g_variant_iter_next(&iter, "&s", &str)) {
0037                 list.append(str);
0038             }
0039             return QVariant(list);
0040         }
0041         break;
0042     default:
0043         qWarning() << "Unhandled variant type in value()";
0044     }
0045 
0046     g_variant_unref(gvalue);
0047 
0048     return toReturn;
0049 }
0050 
0051 void GSettingsItem::set(const QString &key, const QVariant &val)
0052 {
0053     if (!m_settings) {
0054         return;
0055     }
0056 
0057     // It might be hard to detect the right GVariant type from
0058     // complex QVariant types such as string lists or more detailed
0059     // types such as integers (GVariant has different sizes),
0060     // therefore we get the current value for the key and convert
0061     // to QVariant using the GVariant type
0062     GVariant *oldValue = g_settings_get_value(m_settings, key.toLatin1().data());
0063     GVariant *newValue = nullptr;
0064 
0065     switch (g_variant_type_peek_string(g_variant_get_type(oldValue))[0]) {
0066     case G_VARIANT_CLASS_BOOLEAN:
0067         newValue = g_variant_new_boolean(val.toBool());
0068         break;
0069     case G_VARIANT_CLASS_STRING:
0070         newValue = g_variant_new_string(val.toString().toUtf8().constData());
0071         break;
0072     case G_VARIANT_CLASS_ARRAY:
0073         if (g_variant_is_of_type(oldValue, G_VARIANT_TYPE_STRING_ARRAY)) {
0074             const QStringList list = val.toStringList();
0075             GVariantBuilder builder;
0076             g_variant_builder_init(&builder, G_VARIANT_TYPE_STRING_ARRAY);
0077             for (const QString &string : list) {
0078                 g_variant_builder_add(&builder, "s", string.toUtf8().constData());
0079             }
0080 
0081             newValue = g_variant_builder_end(&builder);
0082             break;
0083         }
0084         qWarning() << "Unhandled variant array type in set()";
0085         break;
0086     default:
0087         qWarning() << "Unhandled variant type in set()";
0088     }
0089 
0090     if (newValue) {
0091         g_settings_set_value(m_settings, key.toLatin1().data(), newValue);
0092     }
0093 
0094     g_variant_unref(oldValue);
0095 }
0096 
0097 bool GSettingsItem::isValid() const
0098 {
0099     return m_settings;
0100 }
0101 
0102 GSettingsItem::GSettingsItem(const QString &key, QObject *parent)
0103     : QObject(parent)
0104 {
0105     const char schemaId[] = "org.maliit.keyboard.maliit";
0106 
0107     // g_settings_new_with_path asserts if the schema doesn't exist, check this manually to avoid an abort.
0108     auto *defaultSource = g_settings_schema_source_get_default();
0109     if (!defaultSource) {
0110         qWarning() << "No GSettings schemas are installed on the system";
0111         return;
0112     }
0113 
0114     auto *schema = g_settings_schema_source_lookup(defaultSource, schemaId, true /*recursive*/);
0115     if (!schema) {
0116         qWarning() << "Settings schema" << schemaId << "is not installed";
0117         return;
0118     }
0119 
0120     m_settings = g_settings_new_with_path(schemaId, key.toLatin1().data());
0121     g_settings_schema_unref(schema);
0122 
0123     g_signal_connect(m_settings, "changed", G_CALLBACK(GSettingsItem::settingChanged), this);
0124 }
0125 
0126 GSettingsItem::~GSettingsItem()
0127 {
0128     g_settings_sync();
0129     if (m_settings)
0130         g_object_unref(m_settings);
0131 }