1
/****************************************************************************
2
* Copyright (C) 2009-2013 by Savoir-Faire Linux *
3
* Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com> *
4
* Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Lesser General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2.1 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14
* Lesser General Public License for more details. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
18
***************************************************************************/
21
#include "accountlist.h"
24
#include "sflphone_const.h"
27
#include "configurationmanager_interface_singleton.h"
28
#include "callmanager_interface_singleton.h"
30
AccountList* AccountList::m_spAccountList = nullptr;
31
QString AccountList::m_sPriorAccountId = "" ;
33
QVariant AccountListNoCheckProxyModel::data(const QModelIndex& index,int role ) const
35
if (role == Qt::CheckStateRole) {
38
return AccountList::getInstance()->data(index,role);
40
bool AccountListNoCheckProxyModel::setData( const QModelIndex& index, const QVariant &value, int role)
42
return AccountList::getInstance()->setData(index,value,role);
44
Qt::ItemFlags AccountListNoCheckProxyModel::flags (const QModelIndex& index) const
46
return AccountList::getInstance()->flags(index);
48
int AccountListNoCheckProxyModel::rowCount(const QModelIndex& parent ) const
50
return AccountList::getInstance()->rowCount(parent);
54
AccountList::AccountList(QStringList & _accountIds) : m_pColorVisitor(nullptr),m_pDefaultAccount(nullptr)
56
m_pAccounts = new QVector<Account*>();
57
for (int i = 0; i < _accountIds.size(); ++i) {
58
Account* a = Account::buildExistingAccountFromId(_accountIds[i]);
60
emit dataChanged(index(size()-1,0),index(size()-1,0));
61
connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
63
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
64
ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
66
connect(&callManager , SIGNAL(registrationStateChanged(QString,QString,int)) ,this,SLOT(accountChanged(QString,QString,int)));
67
connect(&configurationManager, SIGNAL(accountsChanged()) ,this,SLOT(updateAccounts()) );
71
///@param fill Whether to fill the list with accounts from configurationManager or not.
72
AccountList::AccountList(bool fill) : m_pColorVisitor(nullptr),m_pDefaultAccount(nullptr)
74
m_pAccounts = new QVector<Account *>();
77
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
78
ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
80
connect(&callManager , SIGNAL(registrationStateChanged(QString,QString,int)),this,SLOT(accountChanged(QString,QString,int)));
81
connect(&configurationManager, SIGNAL(accountsChanged()) ,this,SLOT(updateAccounts()) );
85
AccountList::~AccountList()
87
foreach(Account* a,*m_pAccounts) {
94
AccountList* AccountList::getInstance()
96
if (not m_spAccountList) {
97
m_spAccountList = new AccountList(true);
99
return m_spAccountList;
103
void AccountList::destroy()
106
delete m_spAccountList;
107
m_spAccountList = nullptr;
110
///Account status changed
111
void AccountList::accountChanged(const QString& account,const QString& state, int code)
114
qDebug() << "Account status changed";
115
Account* a = getAccountById(account);
117
ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
118
QStringList accountIds = configurationManager.getAccountList().value();
119
for (int i = 0; i < accountIds.size(); ++i) {
120
if (!getAccountById(accountIds[i])) {
121
Account* a = Account::buildExistingAccountFromId(accountIds[i]);
122
m_pAccounts->insert(i, a);
123
connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
124
emit dataChanged(index(i,0),index(size()-1));
127
foreach (Account* a, *m_pAccounts) {
128
// if (!dynamic_cast<Account*>(a)) { //If an account is being created while updating it may crash or remove it
129
int idx =accountIds.indexOf(a->getAccountId());
130
if (idx == -1 && (a->currentState() == READY || a->currentState() == REMOVED)) {
131
m_pAccounts->remove(idx);
132
emit dataChanged(index(idx - 1, 0), index(m_pAccounts->size()-1, 0));
134
a = getAccountById(account);
139
emit accountStateChanged(a,a->getStateName(state));
141
qDebug() << "Account not found";
144
///Tell the model something changed
145
void AccountList::accountChanged(Account* a)
147
int idx = (*m_pAccounts).indexOf(a);
149
emit dataChanged(index(idx, 0), index(idx, 0));
154
/*****************************************************************************
158
****************************************************************************/
161
void AccountList::update()
163
ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
165
for (int i = 0; i < m_pAccounts->size(); i++) {
166
current = (*m_pAccounts)[i];
167
if (!(*m_pAccounts)[i]->isNew() && (current->currentState() != NEW || current->currentState() != MODIFIED || current->currentState() != OUTDATED))
168
removeAccount(current);
170
//ask for the list of accounts ids to the configurationManager
171
QStringList accountIds = configurationManager.getAccountList().value();
172
for (int i = 0; i < accountIds.size(); ++i) {
173
Account* a = Account::buildExistingAccountFromId(accountIds[i]);
174
m_pAccounts->insert(i, a);
175
emit dataChanged(index(i,0),index(size()-1,0));
176
connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
181
void AccountList::updateAccounts()
183
qDebug() << "updateAccounts";
184
ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
185
QStringList accountIds = configurationManager.getAccountList().value();
186
//m_pAccounts->clear();
187
for (int i = 0; i < accountIds.size(); ++i) {
188
Account* acc = getAccountById(accountIds[i]);
190
qDebug() << "updateAccounts " << accountIds[i];
191
Account* a = Account::buildExistingAccountFromId(accountIds[i]);
193
connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
194
emit dataChanged(index(size()-1,0),index(size()-1,0));
197
acc->performAction(RELOAD);
200
emit accountListUpdated();
203
///Save accounts details and reload it
204
void AccountList::save()
206
ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
207
QStringList accountIds= QStringList(configurationManager.getAccountList().value());
209
//create or update each account from accountList
210
for (int i = 0; i < size(); i++) {
211
Account* current = (*this)[i];
214
current->performAction(AccountEditAction::SAVE);
215
currentId = QString(current->getAccountId());
218
//remove accounts that are in the configurationManager but not in the client
219
for (int i = 0; i < accountIds.size(); i++) {
220
if(!getAccountById(accountIds[i])) {
221
configurationManager.removeAccount(accountIds[i]);
225
configurationManager.setAccountsOrder(getOrderedList());
229
bool AccountList::accountUp( int index )
231
if(index > 0 && index <= rowCount()) {
232
Account* account = getAccountAt(index);
233
m_pAccounts->remove(index);
234
m_pAccounts->insert(index - 1, account);
235
emit dataChanged(this->index(index - 1, 0, QModelIndex()), this->index(index, 0, QModelIndex()));
242
bool AccountList::accountDown( int index )
244
if(index >= 0 && index < rowCount()) {
245
Account* account = getAccountAt(index);
246
m_pAccounts->remove(index);
247
m_pAccounts->insert(index + 1, account);
248
emit dataChanged(this->index(index, 0, QModelIndex()), this->index(index + 1, 0, QModelIndex()));
254
///Try to register all enabled accounts
255
void AccountList::registerAllAccounts()
257
ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
258
configurationManager.registerAllAccounts();
262
/*****************************************************************************
266
****************************************************************************/
269
const QVector<Account*>& AccountList::getAccounts()
274
///Get a single account
275
const Account* AccountList::getAccountAt (int i) const
277
return (*m_pAccounts)[i];
280
///Get a single account
281
Account* AccountList::getAccountAt (int i)
283
return (*m_pAccounts)[i];
286
///Get a serialized string of all accounts
287
QString AccountList::getOrderedList() const
290
for( int i = 0 ; i < size() ; i++) {
291
order += getAccountAt(i)->getAccountId() + '/';
296
///Get account using its ID
297
Account* AccountList::getAccountById(const QString & id) const
301
for (int i = 0; i < m_pAccounts->size(); ++i) {
302
if (!(*m_pAccounts)[i]->isNew() && (*m_pAccounts)[i]->getAccountId() == id)
303
return (*m_pAccounts)[i];
308
///Get account with a specific state
309
QVector<Account*> AccountList::getAccountsByState(const QString& state)
311
QVector<Account *> v;
312
for (int i = 0; i < m_pAccounts->size(); ++i) {
313
if ((*m_pAccounts)[i]->getAccountRegistrationStatus() == state)
314
v += (*m_pAccounts)[i];
319
///Get a list of all registerred account
320
QVector<Account*> AccountList::registeredAccounts() const
322
qDebug() << "registeredAccounts";
323
QVector<Account*> registeredAccounts;
325
for (int i = 0; i < m_pAccounts->count(); ++i) {
326
current = (*m_pAccounts)[i];
327
if(current->getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED) {
328
qDebug() << current->getAlias() << " : " << current;
329
registeredAccounts.append(current);
332
return registeredAccounts;
335
///Get the first registerred account (default account)
336
Account* AccountList::firstRegisteredAccount() const
339
for (int i = 0; i < m_pAccounts->count(); ++i) {
340
current = (*m_pAccounts)[i];
341
if(current && current->getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED && current->isAccountEnabled())
343
else if (current && (current->getAccountRegistrationStatus() == ACCOUNT_STATE_READY) && m_pAccounts->count() == 1)
345
else if (current && !(current->getAccountRegistrationStatus() == ACCOUNT_STATE_READY)) {
346
qDebug() << "Account " << ((current)?current->getAccountId():"") << " is not registered ("
347
<< ((current)?current->getAccountRegistrationStatus():"") << ") State:"
348
<< ((current)?current->getAccountRegistrationStatus():"");
354
///Get the account size
355
int AccountList::size() const
357
return m_pAccounts->size();
360
///Return the current account
361
Account* AccountList::getCurrentAccount()
363
Account* priorAccount = getInstance()->getAccountById(m_sPriorAccountId);
364
if(priorAccount && priorAccount->getAccountDetail(ACCOUNT_REGISTRATION_STATUS) == ACCOUNT_STATE_REGISTERED && priorAccount->isAccountEnabled() ) {
368
Account* a = getInstance()->firstRegisteredAccount();
370
return getInstance()->firstRegisteredAccount();
372
return getInstance()->getAccountById("IP2IP");
374
} //getCurrentAccount
376
///Return the previously used account ID
377
QString AccountList::getPriorAccoundId()
379
return m_sPriorAccountId;
382
///Get data from the model
383
QVariant AccountList::data ( const QModelIndex& index, int role) const
385
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount())
388
const Account * account = (*m_pAccounts)[index.row()];
389
if(index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
390
return QVariant(account->getAlias());
391
else if(index.column() == 0 && role == Qt::CheckStateRole) {
392
return QVariant(account->isEnabled() ? Qt::Checked : Qt::Unchecked);
394
else if (role == Qt::BackgroundRole) {
396
return m_pColorVisitor->getColor(account);
398
return QVariant(account->getStateColor());
400
else if(index.column() == 0 && role == Qt::DecorationRole && m_pColorVisitor) {
401
return m_pColorVisitor->getIcon(account);
407
Qt::ItemFlags AccountList::flags(const QModelIndex & index) const
409
if (index.column() == 0)
410
return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
411
return QAbstractItemModel::flags(index);
415
int AccountList::rowCount(const QModelIndex & /*parent*/) const
417
return m_pAccounts->size();
420
Account* AccountList::getAccountByModelIndex(QModelIndex item) const {
421
return (*m_pAccounts)[item.row()];
424
///Return the default account (used for contact lookup)
425
Account* AccountList::getDefaultAccount()
427
return m_pDefaultAccount;
430
///Generate an unique suffix to prevent multiple account from sharing alias
431
QString AccountList::getSimilarAliasIndex(QString alias)
434
foreach (Account* a, getInstance()->getAccounts()) {
435
if (a->getAccountAlias().left(alias.size()) == alias)
441
foreach (Account* a, getInstance()->getAccounts()) {
442
if (a->getAccountAlias() == alias+QString(" (%1)").arg(count)) {
450
return QString(" (%1)").arg(count);
455
/*****************************************************************************
459
****************************************************************************/
462
Account* AccountList::addAccount(const QString& alias)
464
Account* a = Account::buildNewAccountFromAlias(alias);
465
connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
468
emit dataChanged(index(m_pAccounts->size()-1,0), index(m_pAccounts->size()-1,0));
473
void AccountList::removeAccount(Account* account)
475
if (not account) return;
476
qDebug() << "Removing" << m_pAccounts;
477
int aindex = m_pAccounts->indexOf(account);
478
m_pAccounts->remove(aindex);
479
emit dataChanged(index(aindex,0), index(m_pAccounts->size()-1,0));
482
void AccountList::removeAccount( QModelIndex index )
484
removeAccount(getAccountByModelIndex(index));
487
///Set the previous account used
488
void AccountList::setPriorAccount(Account* account) {
489
bool changed = (account && m_sPriorAccountId != account->getAccountId()) || (!account && !m_sPriorAccountId.isEmpty());
490
m_sPriorAccountId = account?account->getAccountId() : QString();
492
emit priorAccountChanged(getCurrentAccount());
496
bool AccountList::setData(const QModelIndex& index, const QVariant &value, int role)
498
if (index.isValid() && index.column() == 0 && role == Qt::CheckStateRole) {
499
bool prevEnabled = (*m_pAccounts)[index.row()]->isEnabled();
500
(*m_pAccounts)[index.row()]->setEnabled(value.toBool());
501
emit dataChanged(index, index);
502
if (prevEnabled != value.toBool())
503
emit accountEnabledChanged((*m_pAccounts)[index.row()]);
504
emit dataChanged(index, index);
507
else if ( role == Qt::EditRole ) {
508
bool changed = value.toString() != data(index,Qt::EditRole);
510
(*m_pAccounts)[index.row()]->setAccountAlias(value.toString());
511
emit dataChanged(index, index);
517
///Set QAbstractItemModel BackgroundRole visitor
518
void AccountList::setColorVisitor(AccountListColorVisitor* visitor)
520
m_pColorVisitor = visitor;
523
///Set the default account (used for contact lookup)
524
void AccountList::setDefaultAccount(Account* a)
526
if (a != m_pDefaultAccount)
527
emit defaultAccountChanged(a);
528
m_pDefaultAccount = a;
532
/*****************************************************************************
536
****************************************************************************/
538
///Get the account from its index
539
const Account* AccountList::operator[] (int i) const
541
return (*m_pAccounts)[i];
544
///Get the account from its index
545
Account* AccountList::operator[] (int i)
547
return (*m_pAccounts)[i];