accounts-qt  1.2
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 
178  d_ptr(new AccountServicePrivate(account, service, this))
179 {
180 }
181 
186 {
187  delete d_ptr;
188 }
189 
194 {
195  Q_D(const AccountService);
196  AgAccount *account = ag_account_service_get_account(d->m_accountService);
197  AgAccountId account_id = account->id;
198 
199  return d->m_manager->account(account_id);
200 }
201 
206 {
207  Q_D(const AccountService);
208  AgService *service = ag_account_service_get_service(d->m_accountService);
209  return Service(service);
210 }
211 
216 {
217  Q_D(const AccountService);
218  return ag_account_service_get_enabled(d->m_accountService);
219 }
220 
224 QStringList AccountService::allKeys() const
225 {
226  Q_D(const AccountService);
227  QStringList allKeys;
228  AgAccountSettingIter iter;
229  const gchar *key;
230  const GValue *val;
231 
232  /* iterate the settings */
233  QByteArray tmp = d->prefix.toLatin1();
234  ag_account_service_settings_iter_init(d->m_accountService,
235  &iter, tmp.constData());
236  while (ag_account_service_settings_iter_next(&iter, &key, &val))
237  {
238  allKeys.append(ASCII(key));
239  }
240  return allKeys;
241 }
242 
247 void AccountService::beginGroup(const QString &prefix)
248 {
249  Q_D(AccountService);
250  d->prefix += prefix + slash;
251 }
252 
256 QStringList AccountService::childGroups() const
257 {
258  QStringList groups, all_keys;
259 
260  all_keys = allKeys();
261  foreach (QString key, all_keys)
262  {
263  if (key.contains(slash)) {
264  QString group = key.section(slash, 0, 0);
265  if (!groups.contains(group))
266  groups.append(group);
267  }
268  }
269  return groups;
270 }
271 
275 QStringList AccountService::childKeys() const
276 {
277  QStringList keys, all_keys;
278 
279  all_keys = allKeys();
280  foreach (QString key, all_keys)
281  {
282  if (!key.contains(slash))
283  keys.append(key);
284  }
285  return keys;
286 }
287 
293 {
294  Q_D(AccountService);
295  /* clear() must ignore the group: so, temporarily reset it and call
296  * remove("") */
297  QString saved_prefix = d->prefix;
298  d->prefix = QString();
299  remove(QString());
300  d->prefix = saved_prefix;
301 }
302 
307 bool AccountService::contains(const QString &key) const
308 {
309  return childKeys().contains(key);
310 }
311 
316 {
317  Q_D(AccountService);
318  d->prefix = d->prefix.section(slash, 0, -3,
319  QString::SectionIncludeTrailingSep);
320  if (d->prefix[0] == slash) d->prefix.remove(0, 1);
321 }
322 
326 QString AccountService::group() const
327 {
328  Q_D(const AccountService);
329  if (d->prefix.endsWith(slash))
330  return d->prefix.left(d->prefix.size() - 1);
331  return d->prefix;
332 }
333 
339 void AccountService::remove(const QString &key)
340 {
341  Q_D(AccountService);
342  if (key.isEmpty())
343  {
344  /* delete all keys in the group */
345  QStringList keys = allKeys();
346  foreach (QString key, keys)
347  {
348  if (!key.isEmpty())
349  remove(key);
350  }
351  }
352  else
353  {
354  QString full_key = d->prefix + key;
355  QByteArray tmpkey = full_key.toLatin1();
356  ag_account_service_set_value(d->m_accountService,
357  tmpkey.constData(),
358  NULL);
359  }
360 }
361 
367 void AccountService::setValue(const QString &key, const QVariant &value)
368 {
369  Q_D(AccountService);
370  TRACE();
371  GValue val= {0, {{0}}};
372 
373  if (!variantToGValue(value, &val)) {
374  return;
375  }
376 
377  QString full_key = d->prefix + key;
378  QByteArray tmpkey = full_key.toLatin1();
379  ag_account_service_set_value(d->m_accountService,
380  tmpkey.constData(),
381  &val);
382  g_value_unset(&val);
383 }
384 
385 void AccountService::setValue(const char *key, const QVariant &value)
386 {
387  setValue(ASCII(key), value);
388 }
389 
398 QVariant AccountService::value(const QString &key, SettingSource *source) const
399 {
400  Q_D(const AccountService);
401  GValue val= {0, {{0}}};
402  g_value_init(&val, G_TYPE_STRING);
403  QString full_key = d->prefix + key;
404  QByteArray ba = full_key.toLatin1();
405  AgSettingSource agSource =
406  ag_account_service_get_value(d->m_accountService,
407  ba.constData(), &val);
408  if (source != 0) {
409  switch (agSource) {
410  case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
411  case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
412  default: *source = NONE; break;
413  }
414  }
415 
416  QVariant variant;
417  if (agSource == AG_SETTING_SOURCE_NONE)
418  return variant;
419 
420  variant = UTF8(g_value_get_string(&val));
421  g_value_unset(&val);
422 
423  return variant;
424 }
425 
426 QVariant AccountService::value(const char *key, SettingSource *source) const
427 {
428  return value(ASCII(key), source);
429 }
430 
438 QStringList AccountService::changedFields() const
439 {
440  Q_D(const AccountService);
441 
442  gchar **changedFields =
443  ag_account_service_get_changed_fields(d->m_accountService);
444 
445  QStringList keyList;
446  if (changedFields == 0)
447  return keyList;
448 
449  gchar **keys = changedFields;
450  while (*keys != 0) {
451  keyList.append(QString(ASCII(*keys)));
452  keys++;
453  }
454 
455  g_strfreev(changedFields);
456  return keyList;
457 }
458 
469 {
470  Q_D(const AccountService);
471 
472  AgAuthData *agAuthData =
473  ag_account_service_get_auth_data(d->m_accountService);
474  return AuthData(agAuthData);
475 }