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/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 = nullptr;
157 }
158 
159 void AccountServicePrivate::onEnabled(AccountService *accountService,
160  gboolean isEnabled)
161 {
162  Q_EMIT accountService->enabled(isEnabled);
163 }
164 
165 void AccountServicePrivate::onChanged(AccountService *accountService)
166 {
167  Q_EMIT accountService->changed();
168 }
169 
175 AccountService::AccountService(Account *account, const Service &service):
176  QObject(nullptr),
177  d_ptr(new AccountServicePrivate(account, service, this))
178 {
179 }
180 
187 AccountService::AccountService(Account *account, const Service &service,
188  QObject *parent):
189  QObject(parent),
190  d_ptr(new AccountServicePrivate(account, service, this))
191 {
192 }
193 
198 {
199  delete d_ptr;
200 }
201 
205 Account *AccountService::account() const
206 {
207  Q_D(const AccountService);
208  return d->m_account;
209 }
210 
215 {
216  Q_D(const AccountService);
217  AgService *service = ag_account_service_get_service(d->m_accountService);
218  return Service(service);
219 }
220 
228 {
229  return isEnabled();
230 }
231 
236 {
237  Q_D(const AccountService);
238  return ag_account_service_get_enabled(d->m_accountService);
239 }
240 
244 QStringList AccountService::allKeys() const
245 {
246  Q_D(const AccountService);
247  QStringList allKeys;
248  AgAccountSettingIter iter;
249  const gchar *key;
250  GVariant *val;
251 
252  /* iterate the settings */
253  QByteArray tmp = d->prefix.toLatin1();
254  ag_account_service_settings_iter_init(d->m_accountService,
255  &iter, tmp.constData());
256  while (ag_account_settings_iter_get_next(&iter, &key, &val))
257  {
258  allKeys.append(ASCII(key));
259  }
260  return allKeys;
261 }
262 
267 void AccountService::beginGroup(const QString &prefix)
268 {
269  Q_D(AccountService);
270  d->prefix += prefix + slash;
271 }
272 
276 QStringList AccountService::childGroups() const
277 {
278  QStringList groups, all_keys;
279 
280  all_keys = allKeys();
281  Q_FOREACH (const QString &key, all_keys)
282  {
283  if (key.contains(slash)) {
284  QString group = key.section(slash, 0, 0);
285  if (!groups.contains(group))
286  groups.append(group);
287  }
288  }
289  return groups;
290 }
291 
295 QStringList AccountService::childKeys() const
296 {
297  QStringList keys, all_keys;
298 
299  all_keys = allKeys();
300  Q_FOREACH (const QString &key, all_keys)
301  {
302  if (!key.contains(slash))
303  keys.append(key);
304  }
305  return keys;
306 }
307 
313 {
314  Q_D(AccountService);
315  /* clear() must ignore the group: so, temporarily reset it and call
316  * remove("") */
317  QString saved_prefix = d->prefix;
318  d->prefix = QString();
319  remove(QString());
320  d->prefix = saved_prefix;
321 }
322 
327 bool AccountService::contains(const QString &key) const
328 {
329  return childKeys().contains(key);
330 }
331 
336 {
337  Q_D(AccountService);
338  d->prefix = d->prefix.section(slash, 0, -3,
339  QString::SectionIncludeTrailingSep);
340  if (d->prefix[0] == slash) d->prefix.remove(0, 1);
341 }
342 
346 QString AccountService::group() const
347 {
348  Q_D(const AccountService);
349  if (d->prefix.endsWith(slash))
350  return d->prefix.left(d->prefix.size() - 1);
351  return d->prefix;
352 }
353 
359 void AccountService::remove(const QString &key)
360 {
361  Q_D(AccountService);
362  if (key.isEmpty())
363  {
364  /* delete all keys in the group */
365  QStringList keys = allKeys();
366  Q_FOREACH (const QString &key, keys)
367  {
368  if (!key.isEmpty())
369  remove(key);
370  }
371  }
372  else
373  {
374  QString full_key = d->prefix + key;
375  QByteArray tmpkey = full_key.toLatin1();
376  ag_account_service_set_variant(d->m_accountService,
377  tmpkey.constData(),
378  NULL);
379  }
380 }
381 
387 void AccountService::setValue(const QString &key, const QVariant &value)
388 {
389  Q_D(AccountService);
390 
391  GVariant *variant = qVariantToGVariant(value);
392  if (variant == nullptr) {
393  return;
394  }
395 
396  QString full_key = d->prefix + key;
397  QByteArray tmpkey = full_key.toLatin1();
398  ag_account_service_set_variant(d->m_accountService,
399  tmpkey.constData(),
400  variant);
401 }
402 
403 void AccountService::setValue(const char *key, const QVariant &value)
404 {
405  setValue(ASCII(key), value);
406 }
407 
419 QVariant AccountService::value(const QString &key,
420  const QVariant &defaultValue,
421  SettingSource *source) const
422 {
423  Q_D(const AccountService);
424  QString full_key = d->prefix + key;
425  QByteArray ba = full_key.toLatin1();
426  AgSettingSource settingSource;
427  GVariant *variant =
428  ag_account_service_get_variant(d->m_accountService,
429  ba.constData(),
430  &settingSource);
431  if (source != nullptr) {
432  switch (settingSource) {
433  case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
434  case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
435  default: *source = NONE; break;
436  }
437  }
438 
439  return (variant != nullptr) ? gVariantToQVariant(variant) : defaultValue;
440 }
441 
450 QVariant AccountService::value(const QString &key, SettingSource *source) const
451 {
452  return value(key, QVariant(), source);
453 }
454 
455 QVariant AccountService::value(const char *key, SettingSource *source) const
456 {
457  return value(ASCII(key), source);
458 }
459 
467 QStringList AccountService::changedFields() const
468 {
469  Q_D(const AccountService);
470 
471  gchar **changedFields =
472  ag_account_service_get_changed_fields(d->m_accountService);
473 
474  QStringList keyList;
475  if (changedFields == nullptr)
476  return keyList;
477 
478  gchar **keys = changedFields;
479  while (*keys != nullptr) {
480  keyList.append(QString(ASCII(*keys)));
481  keys++;
482  }
483 
484  g_strfreev(changedFields);
485  return keyList;
486 }
487 
498 {
499  Q_D(const AccountService);
500 
501  AgAuthData *agAuthData =
502  ag_account_service_get_auth_data(d->m_accountService);
503  AuthData authData(agAuthData);
504  ag_auth_data_unref(agAuthData);
505  return authData;
506 }
Account settings for a specific service.
Service service() const
Return the Service.
virtual ~AccountService()
Destructor.
QStringList allKeys() const
Return all the keys in the current group.
void changed()
Emitted when some setting has changed on the account service.
QStringList childGroups() const
Return all the groups which are direct children of the current group.
Account * account() const
Return the Account.
bool contains(const QString &key) const
Check whether the given key is in the current group.
QVariant value(const QString &key, const QVariant &defaultValue, SettingSource *source=nullptr) const
Retrieves the value of an account setting, as a QVariant.
AuthData authData() const
Read the authentication data stored in the account (merging the service-specific settings with the gl...
void remove(const QString &key)
Remove the given key.
QStringList childKeys() const
Return all the keys which are direct children of the current group.
void beginGroup(const QString &prefix)
Enter a group.
bool isEnabled() const
Check whether the account service is enabled.
QStringList changedFields() const
This method should be called only in the context of a handler of the AccountService::changed() signal...
void clear()
Remove all the keys.
QString group() const
Return the name of the current group.
AccountService(Account *account, const Service &service)
Constructor.
bool enabled() const
Check whether the account service is enabled.
void endGroup()
Exit a group.
Information for account authentication.
Definition: auth-data.h:50
Representation of an account service.
Definition: service.h:49