accounts-qt  1.16
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-2016 Canonical Ltd.
7  *
8  * Contact: Alberto Mardegan <alberto.mardegan@canonical.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.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  QPointer<Account> m_account;
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_account(account),
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 = nullptr;
155 }
156 
157 void AccountServicePrivate::onEnabled(AccountService *accountService,
158  gboolean isEnabled)
159 {
160  Q_EMIT accountService->enabled(isEnabled);
161 }
162 
163 void AccountServicePrivate::onChanged(AccountService *accountService)
164 {
165  Q_EMIT accountService->changed();
166 }
167 
173 AccountService::AccountService(Account *account, const Service &service):
174  QObject(nullptr),
175  d_ptr(new AccountServicePrivate(account, service, this))
176 {
177 }
178 
185 AccountService::AccountService(Account *account, const Service &service,
186  QObject *parent):
187  QObject(parent),
188  d_ptr(new AccountServicePrivate(account, service, this))
189 {
190 }
191 
196 {
197  delete d_ptr;
198 }
199 
203 Account *AccountService::account() const
204 {
205  Q_D(const AccountService);
206  return d->m_account;
207 }
208 
213 {
214  Q_D(const AccountService);
215  AgService *service = ag_account_service_get_service(d->m_accountService);
216  return Service(service);
217 }
218 
226 {
227  return isEnabled();
228 }
229 
234 {
235  Q_D(const AccountService);
236  return ag_account_service_get_enabled(d->m_accountService);
237 }
238 
242 QStringList AccountService::allKeys() const
243 {
244  Q_D(const AccountService);
245  QStringList allKeys;
246  AgAccountSettingIter iter;
247  const gchar *key;
248  GVariant *val;
249 
250  /* iterate the settings */
251  QByteArray tmp = d->prefix.toLatin1();
252  ag_account_service_settings_iter_init(d->m_accountService,
253  &iter, tmp.constData());
254  while (ag_account_settings_iter_get_next(&iter, &key, &val))
255  {
256  allKeys.append(ASCII(key));
257  }
258  return allKeys;
259 }
260 
265 void AccountService::beginGroup(const QString &prefix)
266 {
267  Q_D(AccountService);
268  d->prefix += prefix + slash;
269 }
270 
274 QStringList AccountService::childGroups() const
275 {
276  QStringList groups, all_keys;
277 
278  all_keys = allKeys();
279  Q_FOREACH (const QString &key, all_keys)
280  {
281  if (key.contains(slash)) {
282  QString group = key.section(slash, 0, 0);
283  if (!groups.contains(group))
284  groups.append(group);
285  }
286  }
287  return groups;
288 }
289 
293 QStringList AccountService::childKeys() const
294 {
295  QStringList keys, all_keys;
296 
297  all_keys = allKeys();
298  Q_FOREACH (const QString &key, all_keys)
299  {
300  if (!key.contains(slash))
301  keys.append(key);
302  }
303  return keys;
304 }
305 
311 {
312  Q_D(AccountService);
313  /* clear() must ignore the group: so, temporarily reset it and call
314  * remove("") */
315  QString saved_prefix = d->prefix;
316  d->prefix = QString();
317  remove(QString());
318  d->prefix = saved_prefix;
319 }
320 
325 bool AccountService::contains(const QString &key) const
326 {
327  return childKeys().contains(key);
328 }
329 
334 {
335  Q_D(AccountService);
336  d->prefix = d->prefix.section(slash, 0, -3,
337  QString::SectionIncludeTrailingSep);
338  if (!d->prefix.isEmpty() && d->prefix[0] == slash) d->prefix.remove(0, 1);
339 }
340 
344 QString AccountService::group() const
345 {
346  Q_D(const AccountService);
347  if (d->prefix.endsWith(slash))
348  return d->prefix.left(d->prefix.size() - 1);
349  return d->prefix;
350 }
351 
357 void AccountService::remove(const QString &key)
358 {
359  Q_D(AccountService);
360  if (key.isEmpty())
361  {
362  /* delete all keys in the group */
363  QStringList keys = allKeys();
364  Q_FOREACH (const QString &key, keys)
365  {
366  if (!key.isEmpty())
367  remove(key);
368  }
369  }
370  else
371  {
372  QString full_key = d->prefix + key;
373  QByteArray tmpkey = full_key.toLatin1();
374  ag_account_service_set_variant(d->m_accountService,
375  tmpkey.constData(),
376  NULL);
377  }
378 }
379 
385 void AccountService::setValue(const QString &key, const QVariant &value)
386 {
387  Q_D(AccountService);
388 
389  GVariant *variant = qVariantToGVariant(value);
390  if (variant == nullptr) {
391  return;
392  }
393 
394  QString full_key = d->prefix + key;
395  QByteArray tmpkey = full_key.toLatin1();
396  ag_account_service_set_variant(d->m_accountService,
397  tmpkey.constData(),
398  variant);
399 }
400 
401 void AccountService::setValue(const char *key, const QVariant &value)
402 {
403  setValue(ASCII(key), value);
404 }
405 
417 QVariant AccountService::value(const QString &key,
418  const QVariant &defaultValue,
419  SettingSource *source) const
420 {
421  Q_D(const AccountService);
422  QString full_key = d->prefix + key;
423  QByteArray ba = full_key.toLatin1();
424  AgSettingSource settingSource;
425  GVariant *variant =
426  ag_account_service_get_variant(d->m_accountService,
427  ba.constData(),
428  &settingSource);
429  if (source != nullptr) {
430  switch (settingSource) {
431  case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
432  case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
433  default: *source = NONE; break;
434  }
435  }
436 
437  return (variant != nullptr) ? gVariantToQVariant(variant) : defaultValue;
438 }
439 
448 QVariant AccountService::value(const QString &key, SettingSource *source) const
449 {
450  return value(key, QVariant(), source);
451 }
452 
453 QVariant AccountService::value(const char *key, SettingSource *source) const
454 {
455  return value(ASCII(key), source);
456 }
457 
465 QStringList AccountService::changedFields() const
466 {
467  Q_D(const AccountService);
468 
469  gchar **changedFields =
470  ag_account_service_get_changed_fields(d->m_accountService);
471 
472  QStringList keyList;
473  if (changedFields == nullptr)
474  return keyList;
475 
476  gchar **keys = changedFields;
477  while (*keys != nullptr) {
478  keyList.append(QString(ASCII(*keys)));
479  keys++;
480  }
481 
482  g_strfreev(changedFields);
483  return keyList;
484 }
485 
496 {
497  Q_D(const AccountService);
498 
499  AgAuthData *agAuthData =
500  ag_account_service_get_auth_data(d->m_accountService);
501  AuthData authData(agAuthData);
502  ag_auth_data_unref(agAuthData);
503  return authData;
504 }
QStringList allKeys() const
Return all the keys in the current group.
AuthData authData() const
Read the authentication data stored in the account (merging the service-specific settings with the gl...
void clear()
Remove all the keys.
Account settings for a specific service.
QStringList childGroups() const
Return all the groups which are direct children of the current group.
bool isEnabled() const
Check whether the account service is enabled.
QVariant value(const QString &key, const QVariant &defaultValue, SettingSource *source=nullptr) const
Retrieves the value of an account setting, as a QVariant.
void remove(const QString &key)
Remove the given key.
QStringList changedFields() const
This method should be called only in the context of a handler of the AccountService::changed() signal...
void endGroup()
Exit a group.
Service service() const
Return the Service.
QStringList childKeys() const
Return all the keys which are direct children of the current group.
virtual ~AccountService()
Destructor.
QString group() const
Return the name of the current group.
bool enabled() const
Check whether the account service is enabled.
Representation of an account service.
Definition: service.h:48
Information for account authentication.
Definition: auth-data.h:49
void beginGroup(const QString &prefix)
Enter a group.
void changed()
Emitted when some setting has changed on the account service.
Account * account() const
Return the Account.
bool contains(const QString &key) const
Check whether the given key is in the current group.
AccountService(Account *account, const Service &service)
Constructor.