accounts-qt  1.13
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 Canonical Ltd.
00007  *
00008  * Contact: Alberto Mardegan <alberto.mardegan@nokia.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     TRACE();
00163 
00164     Q_EMIT accountService->enabled(isEnabled);
00165 }
00166 
00167 void AccountServicePrivate::onChanged(AccountService *accountService)
00168 {
00169     TRACE();
00170 
00171     Q_EMIT accountService->changed();
00172 }
00173 
00179 AccountService::AccountService(Account *account, const Service &service):
00180     QObject(0),
00181     d_ptr(new AccountServicePrivate(account, service, this))
00182 {
00183 }
00184 
00191 AccountService::AccountService(Account *account, const Service &service,
00192                                QObject *parent):
00193     QObject(parent),
00194     d_ptr(new AccountServicePrivate(account, service, this))
00195 {
00196 }
00197 
00201 AccountService::~AccountService()
00202 {
00203     delete d_ptr;
00204 }
00205 
00209 Account *AccountService::account() const
00210 {
00211     Q_D(const AccountService);
00212     return d->m_account;
00213 }
00214 
00218 Service AccountService::service() const
00219 {
00220     Q_D(const AccountService);
00221     AgService *service = ag_account_service_get_service(d->m_accountService);
00222     return Service(service);
00223 }
00224 
00231 bool AccountService::enabled() const
00232 {
00233     return isEnabled();
00234 }
00235 
00239 bool AccountService::isEnabled() const
00240 {
00241     Q_D(const AccountService);
00242     return ag_account_service_get_enabled(d->m_accountService);
00243 }
00244 
00248 QStringList AccountService::allKeys() const
00249 {
00250     Q_D(const AccountService);
00251     QStringList allKeys;
00252     AgAccountSettingIter iter;
00253     const gchar *key;
00254     GVariant *val;
00255 
00256     /* iterate the settings */
00257     QByteArray tmp = d->prefix.toLatin1();
00258     ag_account_service_settings_iter_init(d->m_accountService,
00259                                           &iter, tmp.constData());
00260     while (ag_account_settings_iter_get_next(&iter, &key, &val))
00261     {
00262         allKeys.append(ASCII(key));
00263     }
00264     return allKeys;
00265 }
00266 
00271 void AccountService::beginGroup(const QString &prefix)
00272 {
00273     Q_D(AccountService);
00274     d->prefix += prefix + slash;
00275 }
00276 
00280 QStringList AccountService::childGroups() const
00281 {
00282     QStringList groups, all_keys;
00283 
00284     all_keys = allKeys();
00285     Q_FOREACH (QString key, all_keys)
00286     {
00287         if (key.contains(slash)) {
00288             QString group = key.section(slash, 0, 0);
00289             if (!groups.contains(group))
00290                 groups.append(group);
00291         }
00292     }
00293     return groups;
00294 }
00295 
00299 QStringList AccountService::childKeys() const
00300 {
00301     QStringList keys, all_keys;
00302 
00303     all_keys = allKeys();
00304     Q_FOREACH (QString key, all_keys)
00305     {
00306         if (!key.contains(slash))
00307             keys.append(key);
00308     }
00309     return keys;
00310 }
00311 
00316 void AccountService::clear()
00317 {
00318     Q_D(AccountService);
00319     /* clear() must ignore the group: so, temporarily reset it and call
00320      * remove("") */
00321     QString saved_prefix = d->prefix;
00322     d->prefix = QString();
00323     remove(QString());
00324     d->prefix = saved_prefix;
00325 }
00326 
00331 bool AccountService::contains(const QString &key) const
00332 {
00333     return childKeys().contains(key);
00334 }
00335 
00339 void AccountService::endGroup()
00340 {
00341     Q_D(AccountService);
00342     d->prefix = d->prefix.section(slash, 0, -3,
00343                                   QString::SectionIncludeTrailingSep);
00344     if (d->prefix[0] == slash) d->prefix.remove(0, 1);
00345 }
00346 
00350 QString AccountService::group() const
00351 {
00352     Q_D(const AccountService);
00353     if (d->prefix.endsWith(slash))
00354         return d->prefix.left(d->prefix.size() - 1);
00355     return d->prefix;
00356 }
00357 
00363 void AccountService::remove(const QString &key)
00364 {
00365     Q_D(AccountService);
00366     if (key.isEmpty())
00367     {
00368         /* delete all keys in the group */
00369         QStringList keys = allKeys();
00370         Q_FOREACH (QString key, keys)
00371         {
00372             if (!key.isEmpty())
00373                 remove(key);
00374         }
00375     }
00376     else
00377     {
00378         QString full_key = d->prefix + key;
00379         QByteArray tmpkey = full_key.toLatin1();
00380         ag_account_service_set_variant(d->m_accountService,
00381                                        tmpkey.constData(),
00382                                        NULL);
00383     }
00384 }
00385 
00391 void AccountService::setValue(const QString &key, const QVariant &value)
00392 {
00393     Q_D(AccountService);
00394 
00395     GVariant *variant = qVariantToGVariant(value);
00396     if (variant == 0) {
00397         return;
00398     }
00399 
00400     QString full_key = d->prefix + key;
00401     QByteArray tmpkey = full_key.toLatin1();
00402     ag_account_service_set_variant(d->m_accountService,
00403                                    tmpkey.constData(),
00404                                    variant);
00405 }
00406 
00407 void AccountService::setValue(const char *key, const QVariant &value)
00408 {
00409     setValue(ASCII(key), value);
00410 }
00411 
00423 QVariant AccountService::value(const QString &key,
00424                                const QVariant &defaultValue,
00425                                SettingSource *source) const
00426 {
00427     Q_D(const AccountService);
00428     QString full_key = d->prefix + key;
00429     QByteArray ba = full_key.toLatin1();
00430     AgSettingSource settingSource;
00431     GVariant *variant =
00432         ag_account_service_get_variant(d->m_accountService,
00433                                        ba.constData(),
00434                                        &settingSource);
00435     if (source != 0) {
00436         switch (settingSource) {
00437         case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
00438         case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
00439         default: *source = NONE; break;
00440         }
00441     }
00442 
00443     return (variant != 0) ? gVariantToQVariant(variant) : defaultValue;
00444 }
00445 
00454 QVariant AccountService::value(const QString &key, SettingSource *source) const
00455 {
00456     return value(key, QVariant(), source);
00457 }
00458 
00459 QVariant AccountService::value(const char *key, SettingSource *source) const
00460 {
00461     return value(ASCII(key), source);
00462 }
00463 
00471 QStringList AccountService::changedFields() const
00472 {
00473     Q_D(const AccountService);
00474 
00475     gchar **changedFields =
00476         ag_account_service_get_changed_fields(d->m_accountService);
00477 
00478     QStringList keyList;
00479     if (changedFields == 0)
00480         return keyList;
00481 
00482     gchar **keys = changedFields;
00483     while (*keys != 0) {
00484         keyList.append(QString(ASCII(*keys)));
00485         keys++;
00486     }
00487 
00488     g_strfreev(changedFields);
00489     return keyList;
00490 }
00491 
00501 AuthData AccountService::authData() const
00502 {
00503     Q_D(const AccountService);
00504 
00505     AgAuthData *agAuthData =
00506         ag_account_service_get_auth_data(d->m_accountService);
00507     AuthData authData(agAuthData);
00508     ag_auth_data_unref(agAuthData);
00509     return authData;
00510 }