~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to kde/src/lib/accountlistmodel.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
 *   Copyright (C) 2009-2014 by Savoir-Faire Linux                          *
 
3
 *   Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>          *
 
4
 *            Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
 
5
 *                                                                          *
 
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.     *
 
10
 *                                                                          *
 
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.                        *
 
15
 *                                                                          *
 
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
 ***************************************************************************/
 
19
 
 
20
//Parent
 
21
#include "accountlistmodel.h"
 
22
 
 
23
//SFLPhone
 
24
#include "sflphone_const.h"
 
25
 
 
26
//Qt
 
27
#include <QtCore/QObject>
 
28
 
 
29
//SFLPhone library
 
30
#include "dbus/configurationmanager.h"
 
31
#include "dbus/callmanager.h"
 
32
#include "visitors/accountlistcolorvisitor.h"
 
33
 
 
34
AccountListModel* AccountListModel::m_spAccountList   = nullptr;
 
35
Account*     AccountListModel::m_spPriorAccount   = nullptr     ;
 
36
 
 
37
QVariant AccountListNoCheckProxyModel::data(const QModelIndex& idx,int role ) const
 
38
{
 
39
   if (role == Qt::CheckStateRole) {
 
40
      return QVariant();
 
41
   }
 
42
   return AccountListModel::instance()->data(idx,role);
 
43
}
 
44
 
 
45
bool AccountListNoCheckProxyModel::setData( const QModelIndex& idx, const QVariant &value, int role)
 
46
{
 
47
   return AccountListModel::instance()->setData(idx,value,role);
 
48
}
 
49
 
 
50
Qt::ItemFlags AccountListNoCheckProxyModel::flags (const QModelIndex& idx) const
 
51
{
 
52
   const QModelIndex& src = AccountListModel::instance()->index(idx.row(),idx.column());
 
53
   if (!idx.row() || AccountListModel::instance()->data(src,Qt::CheckStateRole) == Qt::Unchecked)
 
54
      return Qt::NoItemFlags;
 
55
   return AccountListModel::instance()->flags(idx);
 
56
}
 
57
 
 
58
int AccountListNoCheckProxyModel::rowCount(const QModelIndex& parentIdx ) const
 
59
{
 
60
   return AccountListModel::instance()->rowCount(parentIdx);
 
61
}
 
62
 
 
63
///Constructors
 
64
///@param fill Whether to fill the list with accounts from configurationManager or not.
 
65
AccountListModel::AccountListModel() : QAbstractListModel(QCoreApplication::instance()),m_pColorVisitor(nullptr),m_pDefaultAccount(nullptr)
 
66
{
 
67
   setupRoleName();
 
68
}
 
69
 
 
70
///Prevent constructor loop
 
71
void AccountListModel::init()
 
72
{
 
73
   updateAccounts();
 
74
   CallManagerInterface& callManager = DBus::CallManager::instance();
 
75
   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
 
76
 
 
77
   connect(&configurationManager, SIGNAL(sipRegistrationStateChanged(QString,QString,int)),this,SLOT(accountChanged(QString,QString,int)));
 
78
   connect(&configurationManager, SIGNAL(accountsChanged())                            ,this,SLOT(updateAccounts())                   );
 
79
   connect(&callManager         , SIGNAL(voiceMailNotify(QString,int))                 ,this, SLOT(slotVoiceMailNotify(QString,int))  );
 
80
 
 
81
}
 
82
 
 
83
///Destructor
 
84
AccountListModel::~AccountListModel()
 
85
{
 
86
   while(m_lAccounts.size()) {
 
87
      Account* a = m_lAccounts[0];
 
88
      m_lAccounts.remove(0);
 
89
      delete a;
 
90
   }
 
91
}
 
92
 
 
93
void AccountListModel::setupRoleName()
 
94
{
 
95
   QHash<int, QByteArray> roles = roleNames();
 
96
   roles.insert(Account::Role::Alias                    ,QByteArray("alias"                         ));
 
97
   roles.insert(Account::Role::Proto                    ,QByteArray("protocol"                      ));
 
98
   roles.insert(Account::Role::Hostname                 ,QByteArray("hostname"                      ));
 
99
   roles.insert(Account::Role::Username                 ,QByteArray("username"                      ));
 
100
   roles.insert(Account::Role::Mailbox                  ,QByteArray("mailbox"                       ));
 
101
   roles.insert(Account::Role::Proxy                    ,QByteArray("proxy"                         ));
 
102
   roles.insert(Account::Role::TlsPassword              ,QByteArray("tlsPassword"                   ));
 
103
   roles.insert(Account::Role::TlsCaListFile            ,QByteArray("tlsCaListFile"                 ));
 
104
   roles.insert(Account::Role::TlsCertificateFile       ,QByteArray("tlsCertificateFile"            ));
 
105
   roles.insert(Account::Role::TlsPrivateKeyFile        ,QByteArray("tlsPrivateKeyFile"             ));
 
106
   roles.insert(Account::Role::TlsCiphers               ,QByteArray("tlsCiphers"                    ));
 
107
   roles.insert(Account::Role::TlsServerName            ,QByteArray("tlsServerName"                 ));
 
108
   roles.insert(Account::Role::SipStunServer            ,QByteArray("sipStunServer"                 ));
 
109
   roles.insert(Account::Role::PublishedAddress         ,QByteArray("publishedAddress"              ));
 
110
   roles.insert(Account::Role::LocalInterface           ,QByteArray("localInterface"                ));
 
111
   roles.insert(Account::Role::RingtonePath             ,QByteArray("ringtonePath"                  ));
 
112
   roles.insert(Account::Role::TlsMethod                ,QByteArray("tlsMethod"                     ));
 
113
   roles.insert(Account::Role::RegistrationExpire       ,QByteArray("registrationExpire"            ));
 
114
   roles.insert(Account::Role::TlsNegotiationTimeoutSec ,QByteArray("tlsNegotiationTimeoutSec"      ));
 
115
   roles.insert(Account::Role::TlsNegotiationTimeoutMsec,QByteArray("tlsNegotiationTimeoutMsec"     ));
 
116
   roles.insert(Account::Role::LocalPort                ,QByteArray("localPort"                     ));
 
117
   roles.insert(Account::Role::TlsListenerPort          ,QByteArray("tlsListenerPort"               ));
 
118
   roles.insert(Account::Role::PublishedPort            ,QByteArray("publishedPort"                 ));
 
119
   roles.insert(Account::Role::Enabled                  ,QByteArray("enabled"                       ));
 
120
   roles.insert(Account::Role::AutoAnswer               ,QByteArray("autoAnswer"                    ));
 
121
   roles.insert(Account::Role::TlsVerifyServer          ,QByteArray("tlsVerifyServer"               ));
 
122
   roles.insert(Account::Role::TlsVerifyClient          ,QByteArray("tlsVerifyClient"               ));
 
123
   roles.insert(Account::Role::TlsRequireClientCertificate,QByteArray("tlsRequireClientCertificate" ));
 
124
   roles.insert(Account::Role::TlsEnable                ,QByteArray("tlsEnable"                     ));
 
125
   roles.insert(Account::Role::DisplaySasOnce           ,QByteArray("displaySasOnce"                ));
 
126
   roles.insert(Account::Role::SrtpRtpFallback          ,QByteArray("srtpRtpFallback"               ));
 
127
   roles.insert(Account::Role::ZrtpDisplaySas           ,QByteArray("zrtpDisplaySas"                ));
 
128
   roles.insert(Account::Role::ZrtpNotSuppWarning       ,QByteArray("zrtpNotSuppWarning"            ));
 
129
   roles.insert(Account::Role::ZrtpHelloHash            ,QByteArray("zrtpHelloHash"                 ));
 
130
   roles.insert(Account::Role::SipStunEnabled           ,QByteArray("sipStunEnabled"                ));
 
131
   roles.insert(Account::Role::PublishedSameAsLocal     ,QByteArray("publishedSameAsLocal"          ));
 
132
   roles.insert(Account::Role::RingtoneEnabled          ,QByteArray("ringtoneEnabled"               ));
 
133
   roles.insert(Account::Role::dTMFType                 ,QByteArray("dTMFType"                      ));
 
134
   roles.insert(Account::Role::Id                       ,QByteArray("id"                            ));
 
135
   roles.insert(Account::Role::Object                   ,QByteArray("object"                        ));
 
136
   roles.insert(Account::Role::TypeName                 ,QByteArray("typeName"                      ));
 
137
   roles.insert(Account::Role::PresenceStatus           ,QByteArray("presenceStatus"                ));
 
138
   roles.insert(Account::Role::PresenceMessage          ,QByteArray("presenceMessage"               ));
 
139
 
 
140
   setRoleNames(roles);
 
141
}
 
142
 
 
143
///Singleton
 
144
AccountListModel* AccountListModel::instance()
 
145
{
 
146
   if (not m_spAccountList) {
 
147
      m_spAccountList = new AccountListModel();
 
148
      m_spAccountList->init();
 
149
   }
 
150
   return m_spAccountList;
 
151
}
 
152
 
 
153
///Static destructor
 
154
void AccountListModel::destroy()
 
155
{
 
156
   if (m_spAccountList)
 
157
      delete m_spAccountList;
 
158
   m_spAccountList = nullptr;
 
159
}
 
160
 
 
161
///Account status changed
 
162
void AccountListModel::accountChanged(const QString& account,const QString& state, int code)
 
163
{
 
164
   Account* a = getAccountById(account);
 
165
 
 
166
   if (!a || (a && a->registrationStatus() != state )) {
 
167
      if (state != "OK") //Do not polute the log
 
168
         qDebug() << "Account" << account << "status changed to" << state;
 
169
   }
 
170
   if (!a) {
 
171
      ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
 
172
      QStringList accountIds = configurationManager.getAccountList().value();
 
173
      for (int i = 0; i < accountIds.size(); ++i) {
 
174
         if ((!getAccountById(accountIds[i])) && m_lDeletedAccounts.indexOf(accountIds[i]) == -1) {
 
175
            Account* acc = Account::buildExistingAccountFromId(accountIds[i]);
 
176
            m_lAccounts.insert(i, acc);
 
177
            connect(acc,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
 
178
            emit dataChanged(index(i,0),index(size()-1));
 
179
            emit layoutChanged();
 
180
         }
 
181
      }
 
182
      foreach (Account* acc, m_lAccounts) {
 
183
         const int idx =accountIds.indexOf(acc->id());
 
184
         if (idx == -1 && (acc->state() == Account::AccountEditState::READY || acc->state() == Account::AccountEditState::REMOVED)) {
 
185
            m_lAccounts.remove(idx);
 
186
            emit dataChanged(index(idx - 1, 0), index(m_lAccounts.size()-1, 0));
 
187
            emit layoutChanged();
 
188
         }
 
189
      }
 
190
   }
 
191
   else {
 
192
      const bool isRegistered = a->isRegistered();
 
193
      a->updateState();
 
194
      emit a->stateChanged(a->toHumanStateName());
 
195
      const QModelIndex idx = a->index();
 
196
      emit dataChanged(idx, idx);
 
197
      const bool regStateChanged = isRegistered != a->isRegistered();
 
198
      if (regStateChanged && (code == 502 || code == 503)) {
 
199
         emit badGateway();
 
200
      }
 
201
      else if (regStateChanged)
 
202
         emit accountRegistrationChanged(a,a->isRegistered());
 
203
 
 
204
      //Keep the error message
 
205
      a->setLastErrorMessage(state);
 
206
      a->setLastErrorCode(code);
 
207
 
 
208
      emit accountStateChanged(a,a->toHumanStateName());
 
209
   }
 
210
 
 
211
}
 
212
 
 
213
///Tell the model something changed
 
214
void AccountListModel::accountChanged(Account* a)
 
215
{
 
216
   int idx = m_lAccounts.indexOf(a);
 
217
   if (idx != -1) {
 
218
      emit dataChanged(index(idx, 0), index(idx, 0));
 
219
   }
 
220
}
 
221
 
 
222
 
 
223
/*****************************************************************************
 
224
 *                                                                           *
 
225
 *                                  Mutator                                  *
 
226
 *                                                                           *
 
227
 ****************************************************************************/
 
228
 
 
229
 
 
230
///When a new voice mail is available
 
231
void AccountListModel::slotVoiceMailNotify(const QString &accountID, int count)
 
232
{
 
233
   Account* a = getAccountById(accountID);
 
234
   if (a) {
 
235
      a->setVoiceMailCount(count);
 
236
      emit voiceMailNotify(a,count);
 
237
   }
 
238
}
 
239
 
 
240
///Update accounts
 
241
void AccountListModel::update()
 
242
{
 
243
   ConfigurationManagerInterface & configurationManager = DBus::ConfigurationManager::instance();
 
244
   QList<Account*> tmp;
 
245
   for (int i = 0; i < m_lAccounts.size(); i++)
 
246
      tmp << m_lAccounts[i];
 
247
 
 
248
   for (int i = 0; i < tmp.size(); i++) {
 
249
      Account* current = tmp[i];
 
250
      if (!current->isNew() && (current->state() != Account::AccountEditState::NEW
 
251
         && current->state() != Account::AccountEditState::MODIFIED
 
252
         && current->state() != Account::AccountEditState::OUTDATED))
 
253
         removeAccount(current);
 
254
   }
 
255
   //ask for the list of accounts ids to the configurationManager
 
256
   const QStringList accountIds = configurationManager.getAccountList().value();
 
257
   for (int i = 0; i < accountIds.size(); ++i) {
 
258
      if (m_lDeletedAccounts.indexOf(accountIds[i]) == -1) {
 
259
         Account* a = Account::buildExistingAccountFromId(accountIds[i]);
 
260
         m_lAccounts.insert(i, a);
 
261
         emit dataChanged(index(i,0),index(size()-1,0));
 
262
         connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
 
263
         emit layoutChanged();
 
264
      }
 
265
   }
 
266
} //update
 
267
 
 
268
///Update accounts
 
269
void AccountListModel::updateAccounts()
 
270
{
 
271
   qDebug() << "Updating all accounts";
 
272
   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
 
273
   QStringList accountIds = configurationManager.getAccountList().value();
 
274
   //m_lAccounts.clear();
 
275
   for (int i = 0; i < accountIds.size(); ++i) {
 
276
      Account* acc = getAccountById(accountIds[i]);
 
277
      if (!acc) {
 
278
         Account* a = Account::buildExistingAccountFromId(accountIds[i]);
 
279
         m_lAccounts += a;
 
280
         connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
 
281
         emit dataChanged(index(size()-1,0),index(size()-1,0));
 
282
      }
 
283
      else {
 
284
         acc->performAction(Account::AccountEditAction::RELOAD);
 
285
      }
 
286
   }
 
287
   emit accountListUpdated();
 
288
} //updateAccounts
 
289
 
 
290
///Save accounts details and reload it
 
291
void AccountListModel::save()
 
292
{
 
293
   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
 
294
   const QStringList accountIds = QStringList(configurationManager.getAccountList().value());
 
295
 
 
296
   //create or update each account from accountList
 
297
   for (int i = 0; i < size(); i++) {
 
298
      Account* current = (*this)[i];
 
299
      current->performAction(Account::AccountEditAction::SAVE);
 
300
   }
 
301
 
 
302
   //remove accounts that are in the configurationManager but not in the client
 
303
   for (int i = 0; i < accountIds.size(); i++) {
 
304
      if(!getAccountById(accountIds[i])) {
 
305
         configurationManager.removeAccount(accountIds[i]);
 
306
      }
 
307
   }
 
308
 
 
309
   //Set account order
 
310
   QString order;
 
311
   for( int i = 0 ; i < size() ; i++)
 
312
      order += m_lAccounts[i]->id() + '/';
 
313
   configurationManager.setAccountsOrder(order);
 
314
   m_lDeletedAccounts.clear();
 
315
}
 
316
 
 
317
///Move account up
 
318
bool AccountListModel::accountUp( int idx )
 
319
{
 
320
   if(idx > 0 && idx <= rowCount()) {
 
321
      Account* account = m_lAccounts[idx];
 
322
      m_lAccounts.remove(idx);
 
323
      m_lAccounts.insert(idx - 1, account);
 
324
      emit dataChanged(this->index(idx - 1, 0, QModelIndex()), this->index(idx, 0, QModelIndex()));
 
325
      emit layoutChanged();
 
326
      return true;
 
327
   }
 
328
   return false;
 
329
}
 
330
 
 
331
///Move account down
 
332
bool AccountListModel::accountDown( int idx )
 
333
{
 
334
   if(idx >= 0 && idx < rowCount()) {
 
335
      Account* account = m_lAccounts[idx];
 
336
      m_lAccounts.remove(idx);
 
337
      m_lAccounts.insert(idx + 1, account);
 
338
      emit dataChanged(this->index(idx, 0, QModelIndex()), this->index(idx + 1, 0, QModelIndex()));
 
339
      emit layoutChanged();
 
340
      return true;
 
341
   }
 
342
   return false;
 
343
}
 
344
 
 
345
///Try to register all enabled accounts
 
346
void AccountListModel::registerAllAccounts()
 
347
{
 
348
   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
 
349
   configurationManager.registerAllAccounts();
 
350
}
 
351
 
 
352
///Cancel all modifications
 
353
void AccountListModel::cancel() {
 
354
   foreach (Account* a, getAccounts()) {
 
355
      if (a->state() == Account::AccountEditState::MODIFIED || a->state() == Account::AccountEditState::OUTDATED)
 
356
         a->performAction(Account::AccountEditAction::CANCEL);
 
357
   }
 
358
   m_lDeletedAccounts.clear();
 
359
}
 
360
 
 
361
 
 
362
/*****************************************************************************
 
363
 *                                                                           *
 
364
 *                                  Getters                                  *
 
365
 *                                                                           *
 
366
 ****************************************************************************/
 
367
 
 
368
///Get all accounts
 
369
const QVector<Account*>& AccountListModel::getAccounts()
 
370
{
 
371
   return m_lAccounts;
 
372
}
 
373
 
 
374
///Sometime, it may be useful to reverse map a phone number to an account using the hostname
 
375
QList<Account*> AccountListModel::getAccountsByHostNames ( const QString& hostname ) const
 
376
{
 
377
   QList<Account*> toReturn;
 
378
   for (int i = 0; i < m_lAccounts.size(); i++) {
 
379
      Account* acc = m_lAccounts[i];
 
380
      if (acc->hostname() == hostname)
 
381
         toReturn << acc;
 
382
   }
 
383
   return toReturn;
 
384
}
 
385
 
 
386
///Get account using its ID
 
387
Account* AccountListModel::getAccountById(const QString& id) const
 
388
{
 
389
   Q_ASSERT(!id.isEmpty());
 
390
   for (int i = 0; i < m_lAccounts.size(); i++) {
 
391
      Account* acc = m_lAccounts[i];
 
392
      if (acc && !acc->isNew() && acc->id() == id)
 
393
         return acc;
 
394
   }
 
395
   return nullptr;
 
396
}
 
397
 
 
398
///Get account with a specific state
 
399
QVector<Account*> AccountListModel::getAccountsByState(const QString& state)
 
400
{
 
401
   QVector<Account *> v;
 
402
   for (int i = 0; i < m_lAccounts.size(); i++) {
 
403
      Account* acc = m_lAccounts[i];
 
404
      if (acc->registrationStatus() == state)
 
405
         v += acc;
 
406
   }
 
407
   return v;
 
408
}
 
409
 
 
410
///Get the first registerred account (default account)
 
411
Account* AccountListModel::firstRegisteredAccount() const
 
412
{
 
413
   for (int i = 0; i < m_lAccounts.count(); ++i) {
 
414
      Account* current = m_lAccounts[i];
 
415
      if(current && current->registrationStatus() == Account::State::REGISTERED && current->isEnabled())
 
416
         return current;
 
417
      else if (current && (current->registrationStatus() == Account::State::READY) && m_lAccounts.count() == 1)
 
418
         return current;
 
419
//       else if (current && !(current->accountRegistrationStatus()() == ACCOUNT_STATE_READY)) {
 
420
//          qDebug() << "Account " << ((current)?current->accountId():"") << " is not registered ("
 
421
//          << ((current)?current->accountRegistrationStatus()():"") << ") State:"
 
422
//          << ((current)?current->accountRegistrationStatus()():"");
 
423
//       }
 
424
   }
 
425
   return nullptr;
 
426
}
 
427
 
 
428
///Get the account size
 
429
int AccountListModel::size() const
 
430
{
 
431
   return m_lAccounts.size();
 
432
}
 
433
 
 
434
///Return the current account
 
435
Account* AccountListModel::currentAccount()
 
436
{
 
437
   Account* priorAccount = m_spPriorAccount;
 
438
   if(priorAccount && priorAccount->registrationStatus() == Account::State::REGISTERED && priorAccount->isEnabled() ) {
 
439
      return priorAccount;
 
440
   }
 
441
   else {
 
442
      Account* a = instance()->firstRegisteredAccount();
 
443
      if (!a)
 
444
         a = instance()->getAccountById("IP2IP");
 
445
      instance()->setPriorAccount(a);
 
446
      return a;
 
447
   }
 
448
} //getCurrentAccount
 
449
 
 
450
///Get data from the model
 
451
QVariant AccountListModel::data ( const QModelIndex& idx, int role) const
 
452
{
 
453
   if (!idx.isValid() || idx.row() < 0 || idx.row() >= rowCount())
 
454
      return QVariant();
 
455
 
 
456
   const Account* account = m_lAccounts[idx.row()];
 
457
   if(idx.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
 
458
      return QVariant(account->alias());
 
459
   else if(idx.column() == 0 && role == Qt::CheckStateRole)
 
460
      return QVariant(account->isEnabled() ? Qt::Checked : Qt::Unchecked);
 
461
   else if (role == Qt::BackgroundRole)
 
462
      return (m_pColorVisitor)?m_pColorVisitor->getColor(account):account->stateColor();
 
463
   else if(idx.column() == 0 && role == Qt::DecorationRole && m_pColorVisitor)
 
464
      return m_pColorVisitor->getIcon(account);
 
465
   else
 
466
      return account->roleData(role);
 
467
} //data
 
468
 
 
469
///Flags for "idx"
 
470
Qt::ItemFlags AccountListModel::flags(const QModelIndex& idx) const
 
471
{
 
472
   if (idx.column() == 0)
 
473
      return QAbstractItemModel::flags(idx) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
 
474
   return QAbstractItemModel::flags(idx);
 
475
}
 
476
 
 
477
///Number of account
 
478
int AccountListModel::rowCount(const QModelIndex& parentIdx) const
 
479
{
 
480
   Q_UNUSED(parentIdx);
 
481
   return m_lAccounts.size();
 
482
}
 
483
 
 
484
Account* AccountListModel::getAccountByModelIndex(const QModelIndex& item) const
 
485
{
 
486
   if (!item.isValid())
 
487
      return nullptr;
 
488
   return m_lAccounts[item.row()];
 
489
}
 
490
 
 
491
AccountListColorVisitor* AccountListModel::colorVisitor()
 
492
{
 
493
   return m_pColorVisitor;
 
494
}
 
495
 
 
496
///Return the default account (used for contact lookup)
 
497
Account* AccountListModel::getDefaultAccount() const
 
498
{
 
499
   return m_pDefaultAccount;
 
500
}
 
501
 
 
502
///Generate an unique suffix to prevent multiple account from sharing alias
 
503
QString AccountListModel::getSimilarAliasIndex(const QString& alias)
 
504
{
 
505
   int count = 0;
 
506
   foreach (Account* a, instance()->getAccounts()) {
 
507
      if (a->alias().left(alias.size()) == alias)
 
508
         count++;
 
509
   }
 
510
   bool found = true;
 
511
   do {
 
512
      found = false;
 
513
      foreach (Account* a, instance()->getAccounts()) {
 
514
         if (a->alias() == alias+QString(" (%1)").arg(count)) {
 
515
            count++;
 
516
            found = false;
 
517
            break;
 
518
         }
 
519
      }
 
520
   } while(found);
 
521
   if (count)
 
522
      return QString(" (%1)").arg(count);
 
523
   return QString();
 
524
}
 
525
 
 
526
 
 
527
/*****************************************************************************
 
528
 *                                                                           *
 
529
 *                                  Setters                                  *
 
530
 *                                                                           *
 
531
 ****************************************************************************/
 
532
 
 
533
///Add an account
 
534
Account* AccountListModel::addAccount(const QString& alias)
 
535
{
 
536
   Account* a = Account::buildNewAccountFromAlias(alias);
 
537
   connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
 
538
   m_lAccounts += a;
 
539
 
 
540
   emit dataChanged(index(m_lAccounts.size()-1,0), index(m_lAccounts.size()-1,0));
 
541
   return a;
 
542
}
 
543
 
 
544
///Remove an account
 
545
void AccountListModel::removeAccount(Account* account)
 
546
{
 
547
   if (not account) return;
 
548
   qDebug() << "Removing" << account->alias() << account->id();
 
549
   const int aindex = m_lAccounts.indexOf(account);
 
550
   m_lAccounts.remove(aindex);
 
551
   m_lDeletedAccounts << account->id();
 
552
   if (currentAccount() == account)
 
553
      setPriorAccount(getAccountById("IP2IP"));
 
554
   emit dataChanged(index(aindex,0), index(m_lAccounts.size()-1,0));
 
555
   emit layoutChanged();
 
556
   //delete account;
 
557
}
 
558
 
 
559
void AccountListModel::removeAccount( QModelIndex idx )
 
560
{
 
561
   removeAccount(getAccountByModelIndex(idx));
 
562
}
 
563
 
 
564
///Set the previous account used
 
565
void AccountListModel::setPriorAccount(const Account* account) {
 
566
   const bool changed = (account && m_spPriorAccount != account) || (!account && m_spPriorAccount);
 
567
   m_spPriorAccount = const_cast<Account*>(account);
 
568
   if (changed)
 
569
      emit priorAccountChanged(currentAccount());
 
570
}
 
571
 
 
572
///Set model data
 
573
bool AccountListModel::setData(const QModelIndex& idx, const QVariant& value, int role)
 
574
{
 
575
   if (idx.isValid() && idx.column() == 0 && role == Qt::CheckStateRole) {
 
576
      const bool prevEnabled = m_lAccounts[idx.row()]->isEnabled();
 
577
      m_lAccounts[idx.row()]->setEnabled(value.toBool());
 
578
      emit dataChanged(idx, idx);
 
579
      if (prevEnabled != value.toBool())
 
580
         emit accountEnabledChanged(m_lAccounts[idx.row()]);
 
581
      emit dataChanged(idx, idx);
 
582
      return true;
 
583
   }
 
584
   else if ( role == Qt::EditRole ) {
 
585
      if (value.toString() != data(idx,Qt::EditRole)) {
 
586
         m_lAccounts[idx.row()]->setAlias(value.toString());
 
587
         emit dataChanged(idx, idx);
 
588
      }
 
589
   }
 
590
   return false;
 
591
}
 
592
 
 
593
///Set QAbstractItemModel BackgroundRole visitor
 
594
void AccountListModel::setColorVisitor(AccountListColorVisitor* visitor)
 
595
{
 
596
   m_pColorVisitor = visitor;
 
597
}
 
598
 
 
599
///Set the default account (used for contact lookup)
 
600
void AccountListModel::setDefaultAccount(Account* a)
 
601
{
 
602
   if (a != m_pDefaultAccount)
 
603
      emit defaultAccountChanged(a);
 
604
   m_pDefaultAccount = a;
 
605
}
 
606
 
 
607
 
 
608
/*****************************************************************************
 
609
 *                                                                           *
 
610
 *                                 Operator                                  *
 
611
 *                                                                           *
 
612
 ****************************************************************************/
 
613
 
 
614
///Get the account from its index
 
615
const Account* AccountListModel::operator[] (int i) const
 
616
{
 
617
   return m_lAccounts[i];
 
618
}
 
619
 
 
620
///Get the account from its index
 
621
Account* AccountListModel::operator[] (int i)
 
622
{
 
623
   return m_lAccounts[i];
 
624
}
 
625
 
 
626
///Get accoutn by id
 
627
Account* AccountListModel::operator[] (const QString& i) {
 
628
   return getAccountById(i);
 
629
}