File indexing completed on 2023-11-26 08:16:44
0001 /* 0002 * Copyright (C) 2012 David Edmundson <kde@davidedmundson.co.uk> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public 0015 * License along with this library; if not, write to the Free Software 0016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 0017 */ 0018 0019 #include "contacts-list-model.h" 0020 0021 #include <TelepathyQt/Account> 0022 #include <TelepathyQt/Contact> 0023 #include <TelepathyQt/ContactCapabilities> 0024 #include <TelepathyQt/Connection> 0025 #include <TelepathyQt/ContactManager> 0026 #include <TelepathyQt/AccountSet> 0027 #include "debug.h" 0028 #include <QPixmap> 0029 0030 #include "contact.h" 0031 #include "presence.h" 0032 #include "types.h" 0033 0034 class KTp::ContactsListModel::Private 0035 { 0036 public: 0037 Private(): 0038 initialized(false) 0039 { 0040 } 0041 0042 QList<Tp::ContactPtr> contacts; 0043 KTp::GlobalContactManager *contactManager; 0044 bool initialized; 0045 }; 0046 0047 0048 KTp::ContactsListModel::ContactsListModel(QObject *parent) : 0049 QAbstractListModel(parent), 0050 d(new KTp::ContactsListModel::Private()) 0051 { 0052 d->contactManager = nullptr; 0053 } 0054 0055 KTp::ContactsListModel::~ContactsListModel() 0056 { 0057 delete d; 0058 } 0059 0060 void KTp::ContactsListModel::setAccountManager(const Tp::AccountManagerPtr &accountManager) 0061 { 0062 d->contactManager = new KTp::GlobalContactManager(accountManager, this); 0063 connect(d->contactManager, SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts)), SLOT(onContactsChanged(Tp::Contacts,Tp::Contacts))); 0064 0065 // If there are no enabled account or no account is online, emit the signal 0066 // directly, because onContactsChanged won't be called 0067 const QList<Tp::AccountPtr> accounts = accountManager->enabledAccounts()->accounts(); 0068 if (accounts.isEmpty()) { 0069 d->initialized = true; 0070 Q_EMIT modelInitialized(true); 0071 } else { 0072 Q_FOREACH (const Tp::AccountPtr &account, accounts) { 0073 if (account->isOnline()) { 0074 return; 0075 } 0076 } 0077 0078 d->initialized = true; 0079 Q_EMIT modelInitialized(true); 0080 } 0081 } 0082 0083 int KTp::ContactsListModel::rowCount(const QModelIndex &parent) const 0084 { 0085 if (!parent.isValid()) { 0086 return d->contacts.size(); 0087 } else { 0088 return 0; 0089 } 0090 } 0091 0092 QVariant KTp::ContactsListModel::data(const QModelIndex &index, int role) const 0093 { 0094 int row = index.row(); 0095 0096 if (row >=0 && row < d->contacts.size()) { 0097 const KTp::ContactPtr contact = KTp::ContactPtr::qObjectCast(d->contacts[row]); 0098 Q_ASSERT_X(!contact.isNull(), "KTp::ContactListModel::data()", 0099 "Failed to cast Tp::ContactPtr to KTp::ContactPtr. Are you using KTp::ContactFactory?"); 0100 0101 switch (role) { 0102 case KTp::RowTypeRole: 0103 return KTp::ContactRowType; 0104 case Qt::DisplayRole: 0105 return contact->alias(); 0106 case KTp::IdRole: 0107 return contact->id(); 0108 0109 case KTp::ContactRole: 0110 return QVariant::fromValue(contact); 0111 case KTp::AccountRole: 0112 return QVariant::fromValue(d->contactManager->accountForContact(contact)); 0113 0114 case KTp::ContactClientTypesRole: 0115 return contact->clientTypes(); 0116 case KTp::ContactAvatarPathRole: 0117 return contact->avatarData().fileName; 0118 case KTp::ContactAvatarPixmapRole: 0119 return contact->avatarPixmap(); 0120 case KTp::ContactGroupsRole: 0121 return contact->groups(); 0122 0123 case KTp::ContactPresenceNameRole: 0124 return contact->presence().displayString(); 0125 case KTp::ContactPresenceMessageRole: 0126 return contact->presence().statusMessage(); 0127 case KTp::ContactPresenceTypeRole: 0128 return contact->presence().type(); 0129 case KTp::ContactPresenceIconRole: 0130 return contact->presence().iconName(); 0131 0132 case KTp::ContactSubscriptionStateRole: 0133 return contact->subscriptionState(); 0134 case KTp::ContactPublishStateRole: 0135 return contact->publishState(); 0136 case KTp::ContactIsBlockedRole: 0137 return contact->isBlocked(); 0138 0139 case KTp::ContactCanTextChatRole: 0140 return contact->textChatCapability(); 0141 case KTp::ContactCanFileTransferRole: 0142 return contact->fileTransferCapability(); 0143 case KTp::ContactCanAudioCallRole: 0144 return contact->audioCallCapability(); 0145 case KTp::ContactCanVideoCallRole: 0146 return contact->videoCallCapability(); 0147 case KTp::ContactTubesRole: 0148 return QStringList() << contact->streamTubeServicesCapability() 0149 << contact->dbusTubeServicesCapability(); 0150 default: 0151 break; 0152 } 0153 } 0154 return QVariant(); 0155 } 0156 0157 void KTp::ContactsListModel::onContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed) 0158 { 0159 //add contacts. 0160 0161 Q_FOREACH(const Tp::ContactPtr &contact_uncasted, added) { 0162 KTp::ContactPtr contact = KTp::ContactPtr::qObjectCast(contact_uncasted); 0163 0164 connect(contact.data(), 0165 SIGNAL(aliasChanged(QString)), 0166 SLOT(onChanged())); 0167 connect(contact.data(), 0168 SIGNAL(avatarTokenChanged(QString)), 0169 SLOT(onChanged())); 0170 connect(contact.data(), 0171 SIGNAL(avatarDataChanged(Tp::AvatarData)), 0172 SLOT(onChanged())); 0173 connect(contact.data(), 0174 SIGNAL(presenceChanged(Tp::Presence)), 0175 SLOT(onChanged())); 0176 connect(contact->manager()->connection()->selfContact().data(), 0177 SIGNAL(capabilitiesChanged(Tp::ContactCapabilities)), 0178 SLOT(onChanged())); 0179 connect(contact.data(), 0180 SIGNAL(capabilitiesChanged(Tp::ContactCapabilities)), 0181 SLOT(onChanged())); 0182 connect(contact.data(), 0183 SIGNAL(locationUpdated(Tp::LocationInfo)), 0184 SLOT(onChanged())); 0185 connect(contact.data(), 0186 SIGNAL(infoFieldsChanged(Tp::Contact::InfoFields)), 0187 SLOT(onChanged())); 0188 connect(contact.data(), 0189 SIGNAL(subscriptionStateChanged(Tp::Contact::PresenceState)), 0190 SLOT(onChanged())); 0191 connect(contact.data(), 0192 SIGNAL(publishStateChanged(Tp::Contact::PresenceState,QString)), 0193 SLOT(onChanged())); 0194 connect(contact.data(), 0195 SIGNAL(blockStatusChanged(bool)), 0196 SLOT(onChanged())); 0197 connect(contact.data(), 0198 SIGNAL(clientTypesChanged(QStringList)), 0199 SLOT(onChanged())); 0200 connect(contact.data(), 0201 SIGNAL(addedToGroup(QString)), 0202 SLOT(onChanged())); 0203 connect(contact.data(), 0204 SIGNAL(removedFromGroup(QString)), 0205 SLOT(onChanged())); 0206 0207 connect(contact.data(), 0208 SIGNAL(invalidated()), 0209 SLOT(onConnectionDropped())); 0210 } 0211 0212 if (added.size() > 0) { 0213 beginInsertRows(QModelIndex(), d->contacts.size(), d->contacts.size() + added.size() -1); 0214 d->contacts.append(added.values()); 0215 endInsertRows(); 0216 } 0217 0218 //remove contacts 0219 Q_FOREACH(const Tp::ContactPtr &contact, removed) { 0220 int row = d->contacts.indexOf(contact); 0221 if (row >= 0) { //if contact found in list 0222 beginRemoveRows(QModelIndex(), row, row); 0223 d->contacts.removeOne(contact); 0224 endRemoveRows(); 0225 } 0226 } 0227 0228 if (!d->initialized) { 0229 Q_EMIT modelInitialized(true); 0230 d->initialized = true; 0231 } 0232 } 0233 0234 void KTp::ContactsListModel::onChanged() 0235 { 0236 KTp::ContactPtr contact(qobject_cast<KTp::Contact*>(sender())); 0237 int row = d->contacts.indexOf(contact); 0238 if (row > 0) { 0239 QModelIndex index = createIndex(row, 0); 0240 dataChanged(index, index); 0241 } 0242 } 0243 0244 void KTp::ContactsListModel::onConnectionDropped() 0245 { 0246 KTp::ContactPtr contact(qobject_cast<KTp::Contact*>(sender())); 0247 onContactsChanged(Tp::Contacts(), Tp::Contacts() << contact); 0248 } 0249