accounts-qt  1.15
account-service.cpp
00001 /* vi: set et sw=4 ts=4 cino=t0,(0: */
00002 /*
00003  * This file is part of libaccounts-qt
00004  *
00005  * Copyright (C) 2009-2010 Nokia Corporation.
00006  * Copyright (C) 2013-2016 Canonical Ltd.
00007  *
00008  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public License
00012  * version 2.1 as published by the Free Software Foundation.
00013  *
00014  * This library is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00022  * 02110-1301 USA
00023  */
00024 
00025 #include "account-service.h"
00026 #include "manager.h"
00027 #include "utils.h"
00028 #include <QPointer>
00029 #include <libaccounts-glib/ag-account.h>
00030 #include <libaccounts-glib/ag-account-service.h>
00031 #include <libaccounts-glib/ag-auth-data.h>
00032 
00033 namespace Accounts
00034 {
00035 
00107 class AccountServicePrivate
00108 {
00109     Q_DECLARE_PUBLIC(AccountService)
00110 
00111 public:
00112     AccountServicePrivate(Account *account,
00113                           const Service &service,
00114                           AccountService *accountService);
00115     ~AccountServicePrivate();
00116 
00117 private:
00118     static void onEnabled(AccountService *accountService, gboolean isEnabled);
00119     static void onChanged(AccountService *accountService);
00120 
00121     ServiceList m_serviceList;
00122     AgAccountService *m_accountService;
00123     QPointer<Account> m_account;
00124     QString prefix;
00125     mutable AccountService *q_ptr;
00126 };
00127 
00128 } // namespace
00129 
00130 using namespace Accounts;
00131 
00132 static QChar slash = QChar::fromLatin1('/');
00133 
00134 AccountServicePrivate::AccountServicePrivate(Account *account,
00135                                              const Service &service,
00136                                              AccountService *accountService):
00137     m_account(account),
00138     q_ptr(accountService)
00139 {
00140     m_accountService = ag_account_service_new(account->account(),
00141                                               service.service());
00142     g_signal_connect_swapped(m_accountService, "enabled",
00143                              G_CALLBACK(&onEnabled), accountService);
00144     g_signal_connect_swapped(m_accountService, "changed",
00145                              G_CALLBACK(&onChanged), accountService);
00146 }
00147 
00148 AccountServicePrivate::~AccountServicePrivate()
00149 {
00150     Q_Q(AccountService);
00151     g_signal_handlers_disconnect_by_func(m_accountService,
00152                                          (void *)&onEnabled, q);
00153     g_signal_handlers_disconnect_by_func(m_accountService,
00154                                          (void *)&onChanged, q);
00155     g_object_unref(m_accountService);
00156     m_accountService = 0;
00157 }
00158 
00159 void AccountServicePrivate::onEnabled(AccountService *accountService,
00160                                       gboolean isEnabled)
00161 {
00162     Q_EMIT accountService->enabled(isEnabled);
00163 }
00164 
00165 void AccountServicePrivate::onChanged(AccountService *accountService)
00166 {
00167     Q_EMIT accountService->changed();
00168 }
00169 
00175 AccountService::AccountService(Account *account, const Service &service):
00176     QObject(0),
00177     d_ptr(new AccountServicePrivate(account, service, this))
00178 {
00179 }
00180 
00187 AccountService::AccountService(Account *account, const Service &service,
00188                                QObject *parent):
00189     QObject(parent),
00190     d_ptr(new AccountServicePrivate(account, service, this))
00191 {
00192 }
00193 
00197 AccountService::~AccountService()
00198 {
00199     delete d_ptr;
00200 }
00201 
00205 Account *AccountService::account() const
00206 {
00207     Q_D(const AccountService);
00208     return d->m_account;
00209 }
00210 
00214 Service AccountService::service() const
00215 {
00216     Q_D(const AccountService);
00217     AgService *service = ag_account_service_get_service(d->m_accountService);
00218     return Service(service);
00219 }
00220 
00227 bool AccountService::enabled() const
00228 {
00229     return isEnabled();
00230 }
00231 
00235 bool AccountService::isEnabled() const
00236 {
00237     Q_D(const AccountService);
00238     return ag_account_service_get_enabled(d->m_accountService);
00239 }
00240 
00244 QStringList AccountService::allKeys() const
00245 {
00246     Q_D(const AccountService);
00247     QStringList allKeys;
00248     AgAccountSettingIter iter;
00249     const gchar *key;
00250     GVariant *val;
00251 
00252     /* iterate the settings */
00253     QByteArray tmp = d->prefix.toLatin1();
00254     ag_account_service_settings_iter_init(d->m_accountService,
00255                                           &iter, tmp.constData());
00256     while (ag_account_settings_iter_get_next(&iter, &key, &val))
00257     {
00258         allKeys.append(ASCII(key));
00259     }
00260     return allKeys;
00261 }
00262 
00267 void AccountService::beginGroup(const QString &prefix)
00268 {
00269     Q_D(AccountService);
00270     d->prefix += prefix + slash;
00271 }
00272 
00276 QStringList AccountService::childGroups() const
00277 {
00278     QStringList groups, all_keys;
00279 
00280     all_keys = allKeys();
00281     Q_FOREACH (const QString &key, all_keys)
00282     {
00283         if (key.contains(slash)) {
00284             QString group = key.section(slash, 0, 0);
00285             if (!groups.contains(group))
00286                 groups.append(group);
00287         }
00288     }
00289     return groups;
00290 }
00291 
00295 QStringList AccountService::childKeys() const
00296 {
00297     QStringList keys, all_keys;
00298 
00299     all_keys = allKeys();
00300     Q_FOREACH (const QString &key, all_keys)
00301     {
00302         if (!key.contains(slash))
00303             keys.append(key);
00304     }
00305     return keys;
00306 }
00307 
00312 void AccountService::clear()
00313 {
00314     Q_D(AccountService);
00315     /* clear() must ignore the group: so, temporarily reset it and call
00316      * remove("") */
00317     QString saved_prefix = d->prefix;
00318     d->prefix = QString();
00319     remove(QString());
00320     d->prefix = saved_prefix;
00321 }
00322 
00327 bool AccountService::contains(const QString &key) const
00328 {
00329     return childKeys().contains(key);
00330 }
00331 
00335 void AccountService::endGroup()
00336 {
00337     Q_D(AccountService);
00338     d->prefix = d->prefix.section(slash, 0, -3,
00339                                   QString::SectionIncludeTrailingSep);
00340     if (d->prefix[0] == slash) d->prefix.remove(0, 1);
00341 }
00342 
00346 QString AccountService::group() const
00347 {
00348     Q_D(const AccountService);
00349     if (d->prefix.endsWith(slash))
00350         return d->prefix.left(d->prefix.size() - 1);
00351     return d->prefix;
00352 }
00353 
00359 void AccountService::remove(const QString &key)
00360 {
00361     Q_D(AccountService);
00362     if (key.isEmpty())
00363     {
00364         /* delete all keys in the group */
00365         QStringList keys = allKeys();
00366         Q_FOREACH (const QString &key, keys)
00367         {
00368             if (!key.isEmpty())
00369                 remove(key);
00370         }
00371     }
00372     else
00373     {
00374         QString full_key = d->prefix + key;
00375         QByteArray tmpkey = full_key.toLatin1();
00376         ag_account_service_set_variant(d->m_accountService,
00377                                        tmpkey.constData(),
00378                                        NULL);
00379     }
00380 }
00381 
00387 void AccountService::setValue(const QString &key, const QVariant &value)
00388 {
00389     Q_D(AccountService);
00390 
00391     GVariant *variant = qVariantToGVariant(value);
00392     if (variant == 0) {
00393         return;
00394     }
00395 
00396     QString full_key = d->prefix + key;
00397     QByteArray tmpkey = full_key.toLatin1();
00398     ag_account_service_set_variant(d->m_accountService,
00399                                    tmpkey.constData(),
00400                                    variant);
00401 }
00402 
00403 void AccountService::setValue(const char *key, const QVariant &value)
00404 {
00405     setValue(ASCII(key), value);
00406 }
00407 
00419 QVariant AccountService::value(const QString &key,
00420                                const QVariant &defaultValue,
00421                                SettingSource *source) const
00422 {
00423     Q_D(const AccountService);
00424     QString full_key = d->prefix + key;
00425     QByteArray ba = full_key.toLatin1();
00426     AgSettingSource settingSource;
00427     GVariant *variant =
00428         ag_account_service_get_variant(d->m_accountService,
00429                                        ba.constData(),
00430                                        &settingSource);
00431     if (source != 0) {
00432         switch (settingSource) {
00433         case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
00434         case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
00435         default: *source = NONE; break;
00436         }
00437     }
00438 
00439     return (variant != 0) ? gVariantToQVariant(variant) : defaultValue;
00440 }
00441 
00450 QVariant AccountService::value(const QString &key, SettingSource *source) const
00451 {
00452     return value(key, QVariant(), source);
00453 }
00454 
00455 QVariant AccountService::value(const char *key, SettingSource *source) const
00456 {
00457     return value(ASCII(key), source);
00458 }
00459 
00467 QStringList AccountService::changedFields() const
00468 {
00469     Q_D(const AccountService);
00470 
00471     gchar **changedFields =
00472         ag_account_service_get_changed_fields(d->m_accountService);
00473 
00474     QStringList keyList;
00475     if (changedFields == 0)
00476         return keyList;
00477 
00478     gchar **keys = changedFields;
00479     while (*keys != 0) {
00480         keyList.append(QString(ASCII(*keys)));
00481         keys++;
00482     }
00483 
00484     g_strfreev(changedFields);
00485     return keyList;
00486 }
00487 
00497 AuthData AccountService::authData() const
00498 {
00499     Q_D(const AccountService);
00500 
00501     AgAuthData *agAuthData =
00502         ag_account_service_get_auth_data(d->m_accountService);
00503     AuthData authData(agAuthData);
00504     ag_auth_data_unref(agAuthData);
00505     return authData;
00506 }