accounts-qt  1.11
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  * Copyright (C) 2013 Canonical Ltd.
7  *
8  * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * version 2.1 as published by the Free Software Foundation.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  */
24 
25 #include "account-service.h"
26 #include "manager.h"
27 #include "utils.h"
28 #include <QPointer>
29 #include <libaccounts-glib/ag-account.h>
30 #include <libaccounts-glib/ag-account-service.h>
31 #include <libaccounts-glib/ag-auth-data.h>
32 
33 namespace Accounts
34 {
35 
107 class AccountServicePrivate
108 {
109  Q_DECLARE_PUBLIC(AccountService)
110 
111 public:
112  AccountServicePrivate(Account *account,
113  const Service &service,
114  AccountService *accountService);
115  ~AccountServicePrivate();
116 
117 private:
118  static void onEnabled(AccountService *accountService, gboolean isEnabled);
119  static void onChanged(AccountService *accountService);
120 
121  ServiceList m_serviceList;
122  AgAccountService *m_accountService;
123  QPointer<Account> m_account;
124  QString prefix;
125  mutable AccountService *q_ptr;
126 };
127 
128 } // namespace
129 
130 using namespace Accounts;
131 
132 static QChar slash = QChar::fromLatin1('/');
133 
134 AccountServicePrivate::AccountServicePrivate(Account *account,
135  const Service &service,
136  AccountService *accountService):
137  m_account(account),
138  q_ptr(accountService)
139 {
140  m_accountService = ag_account_service_new(account->account(),
141  service.service());
142  g_signal_connect_swapped(m_accountService, "enabled",
143  G_CALLBACK(&onEnabled), accountService);
144  g_signal_connect_swapped(m_accountService, "changed",
145  G_CALLBACK(&onChanged), accountService);
146 }
147 
148 AccountServicePrivate::~AccountServicePrivate()
149 {
150  Q_Q(AccountService);
151  g_signal_handlers_disconnect_by_func(m_accountService,
152  (void *)&onEnabled, q);
153  g_signal_handlers_disconnect_by_func(m_accountService,
154  (void *)&onChanged, q);
155  g_object_unref(m_accountService);
156  m_accountService = 0;
157 }
158 
159 void AccountServicePrivate::onEnabled(AccountService *accountService,
160  gboolean isEnabled)
161 {
162  TRACE();
163 
164  Q_EMIT accountService->enabled(isEnabled);
165 }
166 
167 void AccountServicePrivate::onChanged(AccountService *accountService)
168 {
169  TRACE();
170 
171  Q_EMIT accountService->changed();
172 }
173 
180  QObject(0),
181  d_ptr(new AccountServicePrivate(account, service, this))
182 {
183 }
184 
192  QObject *parent):
193  QObject(parent),
194  d_ptr(new AccountServicePrivate(account, service, this))
195 {
196 }
197 
202 {
203  delete d_ptr;
204 }
205 
210 {
211  Q_D(const AccountService);
212  return d->m_account;
213 }
214 
219 {
220  Q_D(const AccountService);
221  AgService *service = ag_account_service_get_service(d->m_accountService);
222  return Service(service);
223 }
224 
232 {
233  return isEnabled();
234 }
235 
240 {
241  Q_D(const AccountService);
242  return ag_account_service_get_enabled(d->m_accountService);
243 }
244 
248 QStringList AccountService::allKeys() const
249 {
250  Q_D(const AccountService);
251  QStringList allKeys;
252  AgAccountSettingIter iter;
253  const gchar *key;
254  GVariant *val;
255 
256  /* iterate the settings */
257  QByteArray tmp = d->prefix.toLatin1();
258  ag_account_service_settings_iter_init(d->m_accountService,
259  &iter, tmp.constData());
260  while (ag_account_settings_iter_get_next(&iter, &key, &val))
261  {
262  allKeys.append(ASCII(key));
263  }
264  return allKeys;
265 }
266 
271 void AccountService::beginGroup(const QString &prefix)
272 {
273  Q_D(AccountService);
274  d->prefix += prefix + slash;
275 }
276 
280 QStringList AccountService::childGroups() const
281 {
282  QStringList groups, all_keys;
283 
284  all_keys = allKeys();
285  Q_FOREACH (QString key, all_keys)
286  {
287  if (key.contains(slash)) {
288  QString group = key.section(slash, 0, 0);
289  if (!groups.contains(group))
290  groups.append(group);
291  }
292  }
293  return groups;
294 }
295 
299 QStringList AccountService::childKeys() const
300 {
301  QStringList keys, all_keys;
302 
303  all_keys = allKeys();
304  Q_FOREACH (QString key, all_keys)
305  {
306  if (!key.contains(slash))
307  keys.append(key);
308  }
309  return keys;
310 }
311 
317 {
318  Q_D(AccountService);
319  /* clear() must ignore the group: so, temporarily reset it and call
320  * remove("") */
321  QString saved_prefix = d->prefix;
322  d->prefix = QString();
323  remove(QString());
324  d->prefix = saved_prefix;
325 }
326 
331 bool AccountService::contains(const QString &key) const
332 {
333  return childKeys().contains(key);
334 }
335 
340 {
341  Q_D(AccountService);
342  d->prefix = d->prefix.section(slash, 0, -3,
343  QString::SectionIncludeTrailingSep);
344  if (d->prefix[0] == slash) d->prefix.remove(0, 1);
345 }
346 
350 QString AccountService::group() const
351 {
352  Q_D(const AccountService);
353  if (d->prefix.endsWith(slash))
354  return d->prefix.left(d->prefix.size() - 1);
355  return d->prefix;
356 }
357 
363 void AccountService::remove(const QString &key)
364 {
365  Q_D(AccountService);
366  if (key.isEmpty())
367  {
368  /* delete all keys in the group */
369  QStringList keys = allKeys();
370  Q_FOREACH (QString key, keys)
371  {
372  if (!key.isEmpty())
373  remove(key);
374  }
375  }
376  else
377  {
378  QString full_key = d->prefix + key;
379  QByteArray tmpkey = full_key.toLatin1();
380  ag_account_service_set_variant(d->m_accountService,
381  tmpkey.constData(),
382  NULL);
383  }
384 }
385 
391 void AccountService::setValue(const QString &key, const QVariant &value)
392 {
393  Q_D(AccountService);
394 
395  GVariant *variant = qVariantToGVariant(value);
396  if (variant == 0) {
397  return;
398  }
399 
400  QString full_key = d->prefix + key;
401  QByteArray tmpkey = full_key.toLatin1();
402  ag_account_service_set_variant(d->m_accountService,
403  tmpkey.constData(),
404  variant);
405 }
406 
407 void AccountService::setValue(const char *key, const QVariant &value)
408 {
409  setValue(ASCII(key), value);
410 }
411 
423 QVariant AccountService::value(const QString &key,
424  const QVariant &defaultValue,
425  SettingSource *source) const
426 {
427  Q_D(const AccountService);
428  QString full_key = d->prefix + key;
429  QByteArray ba = full_key.toLatin1();
430  AgSettingSource settingSource;
431  GVariant *variant =
432  ag_account_service_get_variant(d->m_accountService,
433  ba.constData(),
434  &settingSource);
435  if (source != 0) {
436  switch (settingSource) {
437  case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
438  case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
439  default: *source = NONE; break;
440  }
441  }
442 
443  return (variant != 0) ? gVariantToQVariant(variant) : defaultValue;
444 }
445 
454 QVariant AccountService::value(const QString &key, SettingSource *source) const
455 {
456  return value(key, QVariant(), source);
457 }
458 
459 QVariant AccountService::value(const char *key, SettingSource *source) const
460 {
461  return value(ASCII(key), source);
462 }
463 
471 QStringList AccountService::changedFields() const
472 {
473  Q_D(const AccountService);
474 
475  gchar **changedFields =
476  ag_account_service_get_changed_fields(d->m_accountService);
477 
478  QStringList keyList;
479  if (changedFields == 0)
480  return keyList;
481 
482  gchar **keys = changedFields;
483  while (*keys != 0) {
484  keyList.append(QString(ASCII(*keys)));
485  keys++;
486  }
487 
488  g_strfreev(changedFields);
489  return keyList;
490 }
491 
502 {
503  Q_D(const AccountService);
504 
505  AgAuthData *agAuthData =
506  ag_account_service_get_auth_data(d->m_accountService);
507  return AuthData(agAuthData);
508 }