accounts-qt  1.6
account-service.cpp
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /*
3  * This file is part of libaccounts-qt
4  *
5  * Copyright (C) 2009-2010 Nokia Corporation.
6  *
7  * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * version 2.1 as published by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23 
24 #include "account-service.h"
25 #include "manager.h"
26 #include "utils.h"
27 #include <libaccounts-glib/ag-account.h>
28 #include <libaccounts-glib/ag-account-service.h>
29 #include <libaccounts-glib/ag-auth-data.h>
30 
31 namespace Accounts
32 {
33 
105 class AccountServicePrivate
106 {
107  Q_DECLARE_PUBLIC(AccountService)
108 
109 public:
110  AccountServicePrivate(Account *account,
111  const Service &service,
112  AccountService *accountService);
113  ~AccountServicePrivate();
114 
115 private:
116  static void onEnabled(AccountService *accountService, gboolean isEnabled);
117  static void onChanged(AccountService *accountService);
118 
119  ServiceList m_serviceList;
120  AgAccountService *m_accountService;
121  Manager *m_manager;
122  QString prefix;
123  mutable AccountService *q_ptr;
124 };
125 
126 } // namespace
127 
128 using namespace Accounts;
129 
130 static QChar slash = QChar::fromLatin1('/');
131 
132 AccountServicePrivate::AccountServicePrivate(Account *account,
133  const Service &service,
134  AccountService *accountService):
135  m_manager(account->manager()),
136  q_ptr(accountService)
137 {
138  m_accountService = ag_account_service_new(account->account(),
139  service.service());
140  g_signal_connect_swapped(m_accountService, "enabled",
141  G_CALLBACK(&onEnabled), accountService);
142  g_signal_connect_swapped(m_accountService, "changed",
143  G_CALLBACK(&onChanged), accountService);
144 }
145 
146 AccountServicePrivate::~AccountServicePrivate()
147 {
148  Q_Q(AccountService);
149  g_signal_handlers_disconnect_by_func(m_accountService,
150  (void *)&onEnabled, q);
151  g_signal_handlers_disconnect_by_func(m_accountService,
152  (void *)&onChanged, q);
153  g_object_unref(m_accountService);
154  m_accountService = 0;
155 }
156 
157 void AccountServicePrivate::onEnabled(AccountService *accountService,
158  gboolean isEnabled)
159 {
160  TRACE();
161 
162  Q_EMIT accountService->enabled(isEnabled);
163 }
164 
165 void AccountServicePrivate::onChanged(AccountService *accountService)
166 {
167  TRACE();
168 
169  Q_EMIT accountService->changed();
170 }
171 
177 AccountService::AccountService(Account *account, const Service &service):
178  QObject(0),
179  d_ptr(new AccountServicePrivate(account, service, this))
180 {
181 }
182 
189 AccountService::AccountService(Account *account, const Service &service,
190  QObject *parent):
191  QObject(parent),
192  d_ptr(new AccountServicePrivate(account, service, this))
193 {
194 }
195 
200 {
201  delete d_ptr;
202 }
203 
207 Account *AccountService::account() const
208 {
209  Q_D(const AccountService);
210  AgAccount *account = ag_account_service_get_account(d->m_accountService);
211  return new Account(account, d->m_manager);
212 }
213 
218 {
219  Q_D(const AccountService);
220  AgService *service = ag_account_service_get_service(d->m_accountService);
221  return Service(service);
222 }
223 
228 {
229  Q_D(const AccountService);
230  return ag_account_service_get_enabled(d->m_accountService);
231 }
232 
236 QStringList AccountService::allKeys() const
237 {
238  Q_D(const AccountService);
239  QStringList allKeys;
240  AgAccountSettingIter iter;
241  const gchar *key;
242  GVariant *val;
243 
244  /* iterate the settings */
245  QByteArray tmp = d->prefix.toLatin1();
246  ag_account_service_settings_iter_init(d->m_accountService,
247  &iter, tmp.constData());
248  while (ag_account_settings_iter_get_next(&iter, &key, &val))
249  {
250  allKeys.append(ASCII(key));
251  }
252  return allKeys;
253 }
254 
259 void AccountService::beginGroup(const QString &prefix)
260 {
261  Q_D(AccountService);
262  d->prefix += prefix + slash;
263 }
264 
268 QStringList AccountService::childGroups() const
269 {
270  QStringList groups, all_keys;
271 
272  all_keys = allKeys();
273  Q_FOREACH (QString key, all_keys)
274  {
275  if (key.contains(slash)) {
276  QString group = key.section(slash, 0, 0);
277  if (!groups.contains(group))
278  groups.append(group);
279  }
280  }
281  return groups;
282 }
283 
287 QStringList AccountService::childKeys() const
288 {
289  QStringList keys, all_keys;
290 
291  all_keys = allKeys();
292  Q_FOREACH (QString key, all_keys)
293  {
294  if (!key.contains(slash))
295  keys.append(key);
296  }
297  return keys;
298 }
299 
305 {
306  Q_D(AccountService);
307  /* clear() must ignore the group: so, temporarily reset it and call
308  * remove("") */
309  QString saved_prefix = d->prefix;
310  d->prefix = QString();
311  remove(QString());
312  d->prefix = saved_prefix;
313 }
314 
319 bool AccountService::contains(const QString &key) const
320 {
321  return childKeys().contains(key);
322 }
323 
328 {
329  Q_D(AccountService);
330  d->prefix = d->prefix.section(slash, 0, -3,
331  QString::SectionIncludeTrailingSep);
332  if (d->prefix[0] == slash) d->prefix.remove(0, 1);
333 }
334 
338 QString AccountService::group() const
339 {
340  Q_D(const AccountService);
341  if (d->prefix.endsWith(slash))
342  return d->prefix.left(d->prefix.size() - 1);
343  return d->prefix;
344 }
345 
351 void AccountService::remove(const QString &key)
352 {
353  Q_D(AccountService);
354  if (key.isEmpty())
355  {
356  /* delete all keys in the group */
357  QStringList keys = allKeys();
358  Q_FOREACH (QString key, keys)
359  {
360  if (!key.isEmpty())
361  remove(key);
362  }
363  }
364  else
365  {
366  QString full_key = d->prefix + key;
367  QByteArray tmpkey = full_key.toLatin1();
368  ag_account_service_set_variant(d->m_accountService,
369  tmpkey.constData(),
370  NULL);
371  }
372 }
373 
379 void AccountService::setValue(const QString &key, const QVariant &value)
380 {
381  Q_D(AccountService);
382 
383  GVariant *variant = qVariantToGVariant(value);
384  if (variant == 0) {
385  return;
386  }
387 
388  QString full_key = d->prefix + key;
389  QByteArray tmpkey = full_key.toLatin1();
390  ag_account_service_set_variant(d->m_accountService,
391  tmpkey.constData(),
392  variant);
393 }
394 
395 void AccountService::setValue(const char *key, const QVariant &value)
396 {
397  setValue(ASCII(key), value);
398 }
399 
411 QVariant AccountService::value(const QString &key,
412  const QVariant &defaultValue,
413  SettingSource *source) const
414 {
415  Q_D(const AccountService);
416  QString full_key = d->prefix + key;
417  QByteArray ba = full_key.toLatin1();
418  AgSettingSource settingSource;
419  GVariant *variant =
420  ag_account_service_get_variant(d->m_accountService,
421  ba.constData(),
422  &settingSource);
423  if (source != 0) {
424  switch (settingSource) {
425  case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
426  case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
427  default: *source = NONE; break;
428  }
429  }
430 
431  return (variant != 0) ? gVariantToQVariant(variant) : defaultValue;
432 }
433 
442 QVariant AccountService::value(const QString &key, SettingSource *source) const
443 {
444  return value(key, QVariant(), source);
445 }
446 
447 QVariant AccountService::value(const char *key, SettingSource *source) const
448 {
449  return value(ASCII(key), source);
450 }
451 
459 QStringList AccountService::changedFields() const
460 {
461  Q_D(const AccountService);
462 
463  gchar **changedFields =
464  ag_account_service_get_changed_fields(d->m_accountService);
465 
466  QStringList keyList;
467  if (changedFields == 0)
468  return keyList;
469 
470  gchar **keys = changedFields;
471  while (*keys != 0) {
472  keyList.append(QString(ASCII(*keys)));
473  keys++;
474  }
475 
476  g_strfreev(changedFields);
477  return keyList;
478 }
479 
490 {
491  Q_D(const AccountService);
492 
493  AgAuthData *agAuthData =
494  ag_account_service_get_auth_data(d->m_accountService);
495  return AuthData(agAuthData);
496 }