accounts-qt  1.7
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 
229 {
230  Q_D(const AccountService);
231  return ag_account_service_get_enabled(d->m_accountService);
232 }
233 
237 QStringList AccountService::allKeys() const
238 {
239  Q_D(const AccountService);
240  QStringList allKeys;
241  AgAccountSettingIter iter;
242  const gchar *key;
243  GVariant *val;
244 
245  /* iterate the settings */
246  QByteArray tmp = d->prefix.toLatin1();
247  ag_account_service_settings_iter_init(d->m_accountService,
248  &iter, tmp.constData());
249  while (ag_account_settings_iter_get_next(&iter, &key, &val))
250  {
251  allKeys.append(ASCII(key));
252  }
253  return allKeys;
254 }
255 
260 void AccountService::beginGroup(const QString &prefix)
261 {
262  Q_D(AccountService);
263  d->prefix += prefix + slash;
264 }
265 
269 QStringList AccountService::childGroups() const
270 {
271  QStringList groups, all_keys;
272 
273  all_keys = allKeys();
274  Q_FOREACH (QString key, all_keys)
275  {
276  if (key.contains(slash)) {
277  QString group = key.section(slash, 0, 0);
278  if (!groups.contains(group))
279  groups.append(group);
280  }
281  }
282  return groups;
283 }
284 
288 QStringList AccountService::childKeys() const
289 {
290  QStringList keys, all_keys;
291 
292  all_keys = allKeys();
293  Q_FOREACH (QString key, all_keys)
294  {
295  if (!key.contains(slash))
296  keys.append(key);
297  }
298  return keys;
299 }
300 
306 {
307  Q_D(AccountService);
308  /* clear() must ignore the group: so, temporarily reset it and call
309  * remove("") */
310  QString saved_prefix = d->prefix;
311  d->prefix = QString();
312  remove(QString());
313  d->prefix = saved_prefix;
314 }
315 
320 bool AccountService::contains(const QString &key) const
321 {
322  return childKeys().contains(key);
323 }
324 
329 {
330  Q_D(AccountService);
331  d->prefix = d->prefix.section(slash, 0, -3,
332  QString::SectionIncludeTrailingSep);
333  if (d->prefix[0] == slash) d->prefix.remove(0, 1);
334 }
335 
339 QString AccountService::group() const
340 {
341  Q_D(const AccountService);
342  if (d->prefix.endsWith(slash))
343  return d->prefix.left(d->prefix.size() - 1);
344  return d->prefix;
345 }
346 
352 void AccountService::remove(const QString &key)
353 {
354  Q_D(AccountService);
355  if (key.isEmpty())
356  {
357  /* delete all keys in the group */
358  QStringList keys = allKeys();
359  Q_FOREACH (QString key, keys)
360  {
361  if (!key.isEmpty())
362  remove(key);
363  }
364  }
365  else
366  {
367  QString full_key = d->prefix + key;
368  QByteArray tmpkey = full_key.toLatin1();
369  ag_account_service_set_variant(d->m_accountService,
370  tmpkey.constData(),
371  NULL);
372  }
373 }
374 
380 void AccountService::setValue(const QString &key, const QVariant &value)
381 {
382  Q_D(AccountService);
383 
384  GVariant *variant = qVariantToGVariant(value);
385  if (variant == 0) {
386  return;
387  }
388 
389  QString full_key = d->prefix + key;
390  QByteArray tmpkey = full_key.toLatin1();
391  ag_account_service_set_variant(d->m_accountService,
392  tmpkey.constData(),
393  variant);
394 }
395 
396 void AccountService::setValue(const char *key, const QVariant &value)
397 {
398  setValue(ASCII(key), value);
399 }
400 
412 QVariant AccountService::value(const QString &key,
413  const QVariant &defaultValue,
414  SettingSource *source) const
415 {
416  Q_D(const AccountService);
417  QString full_key = d->prefix + key;
418  QByteArray ba = full_key.toLatin1();
419  AgSettingSource settingSource;
420  GVariant *variant =
421  ag_account_service_get_variant(d->m_accountService,
422  ba.constData(),
423  &settingSource);
424  if (source != 0) {
425  switch (settingSource) {
426  case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
427  case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
428  default: *source = NONE; break;
429  }
430  }
431 
432  return (variant != 0) ? gVariantToQVariant(variant) : defaultValue;
433 }
434 
443 QVariant AccountService::value(const QString &key, SettingSource *source) const
444 {
445  return value(key, QVariant(), source);
446 }
447 
448 QVariant AccountService::value(const char *key, SettingSource *source) const
449 {
450  return value(ASCII(key), source);
451 }
452 
460 QStringList AccountService::changedFields() const
461 {
462  Q_D(const AccountService);
463 
464  gchar **changedFields =
465  ag_account_service_get_changed_fields(d->m_accountService);
466 
467  QStringList keyList;
468  if (changedFields == 0)
469  return keyList;
470 
471  gchar **keys = changedFields;
472  while (*keys != 0) {
473  keyList.append(QString(ASCII(*keys)));
474  keys++;
475  }
476 
477  g_strfreev(changedFields);
478  return keyList;
479 }
480 
491 {
492  Q_D(const AccountService);
493 
494  AgAuthData *agAuthData =
495  ag_account_service_get_auth_data(d->m_accountService);
496  return AuthData(agAuthData);
497 }