File indexing completed on 2023-11-26 08:16:44
0001 /* 0002 Copyright (C) 2013 Martin Klapetek <mklapetek@kde.org> 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 Street, Fifth Floor, Boston, MA 02110-1301 USA 0017 */ 0018 0019 0020 #include "kpeopletranslationproxy.h" 0021 #include "KTp/types.h" 0022 #include "KTp/global-contact-manager.h" 0023 0024 #include <KPeople/PersonsModel> 0025 #include <KPeopleBackend/AbstractContact> 0026 0027 #include <KIconLoader> 0028 0029 #include <QPixmapCache> 0030 0031 using namespace KPeople; 0032 0033 0034 KPeopleTranslationProxy::KPeopleTranslationProxy(QObject *parent) 0035 : QSortFilterProxyModel(parent) 0036 { 0037 setDynamicSortFilter(true); 0038 } 0039 0040 KPeopleTranslationProxy::~KPeopleTranslationProxy() 0041 { 0042 } 0043 0044 QVariant KPeopleTranslationProxy::data(const QModelIndex &proxyIndex, int role) const 0045 { 0046 if (!proxyIndex.isValid()) { 0047 return QVariant(); 0048 } 0049 0050 // IMPersonsDataSource *imPlugin = qobject_cast<IMPersonsDataSource*>(PersonPluginManager::presencePlugin()); 0051 // 0052 // if (!imPlugin) { 0053 // qCWarning(KTP_MODELS) << "No imPlugin"; 0054 // return QVariant(); 0055 // } 0056 // 0057 const QModelIndex sourceIndex = mapToSource(proxyIndex); 0058 AbstractContact::Ptr contact = sourceIndex.data(KPeople::PersonsModel::PersonVCardRole).value<AbstractContact::Ptr>(); 0059 0060 switch (role) { 0061 case KTp::ContactPresenceTypeRole: 0062 return s_presenceStrings.key(contact->customProperty(S_KPEOPLE_PROPERTY_PRESENCE).toString()); 0063 case KTp::ContactPresenceIconRole: 0064 return KPeople::iconNameForPresenceString(contact->customProperty(S_KPEOPLE_PROPERTY_PRESENCE).toString()); 0065 // case KTp::ContactPresenceNameRole: 0066 // return sourceIndex.data(PersonsModel::PresenceDisplayRole); 0067 case Qt::DisplayRole: 0068 return sourceIndex.data(KPeople::PersonsModel::FormattedNameRole); 0069 case KTp::RowTypeRole: 0070 if (proxyIndex.parent().isValid() || sourceModel()->rowCount(sourceIndex) <= 1) { 0071 return KTp::ContactRowType; 0072 } else { 0073 return KTp::PersonRowType; 0074 } 0075 // //if the person has max 1 child, it's a fake person, so treat it as contact row 0076 // if (sourceIndex.parent().isValid() || sourceModel()->rowCount(sourceIndex) <= 1) { 0077 // return KTp::ContactRowType; 0078 // } else { 0079 // return KTp::PersonRowType; 0080 // } 0081 // case KTp::ContactAvatarPathRole: 0082 // return sourceIndex.data(PersonsModel::PhotosRole); 0083 case KTp::ContactAvatarPixmapRole: 0084 return sourceIndex.data(KPeople::PersonsModel::PhotoRole); 0085 case KTp::ContactUriRole: 0086 return contact->customProperty(S_KPEOPLE_PROPERTY_CONTACT_URI); 0087 case KTp::IdRole: 0088 return contact->customProperty(S_KPEOPLE_PROPERTY_CONTACT_ID); 0089 case KTp::ContactIsBlockedRole: 0090 return contact->customProperty(S_KPEOPLE_PROPERTY_IS_BLOCKED); 0091 // case KTp::HeaderTotalUsersRole: 0092 // return sourceModel()->rowCount(sourceIndex); 0093 case KTp::ContactGroupsRole: 0094 return sourceIndex.data(PersonsModel::GroupsRole); 0095 case KTp::PersonIdRole: 0096 return sourceIndex.data(PersonsModel::PersonUriRole); 0097 case KTp::ContactVCardRole: 0098 return sourceIndex.data(KPeople::PersonsModel::PersonVCardRole); 0099 } 0100 0101 AbstractContact::List contacts = sourceIndex.data(PersonsModel::ContactsVCardRole).value<AbstractContact::List>(); 0102 0103 int mostOnlineIndex = 0; 0104 0105 for (int i = 0; i < contacts.size(); i++) { 0106 if (KPeople::presenceSortPriority(contact->customProperty(S_KPEOPLE_PROPERTY_PRESENCE).toString()) 0107 < KPeople::presenceSortPriority(contacts.at(mostOnlineIndex)->customProperty(S_KPEOPLE_PROPERTY_PRESENCE).toString())) { 0108 0109 mostOnlineIndex = i; 0110 } 0111 } 0112 0113 AbstractContact::Ptr informationContact = contacts.isEmpty() ? contact : contacts.at(mostOnlineIndex); 0114 QVariant rValue = dataForKTpContact(informationContact->customProperty(S_KPEOPLE_PROPERTY_ACCOUNT_PATH).toString(), 0115 informationContact->customProperty(S_KPEOPLE_PROPERTY_CONTACT_ID).toString(), 0116 role); 0117 0118 if (rValue.isNull()) { 0119 return sourceIndex.data(role); 0120 } else { 0121 return rValue; 0122 } 0123 } 0124 0125 QVariant KPeopleTranslationProxy::dataForKTpContact(const QString &accountPath, const QString &contactId, int role) const 0126 { 0127 if (accountPath.isEmpty()) { 0128 return QVariant(); 0129 } 0130 if (role == KTp::AccountRole) { 0131 return QVariant::fromValue<Tp::AccountPtr>(KTp::contactManager()->accountForAccountPath(accountPath)); 0132 } 0133 0134 KTp::ContactPtr ktpContact = KTp::contactManager()->contactForContactId(accountPath, contactId); 0135 if (!ktpContact.isNull()) { 0136 switch (role) { 0137 case KTp::ContactRole: 0138 return QVariant::fromValue<KTp::ContactPtr>(ktpContact); 0139 break; 0140 case KTp::ContactPresenceMessageRole: 0141 return ktpContact->presence().statusMessage(); 0142 break; 0143 case KTp::ContactIsBlockedRole: 0144 return ktpContact->isBlocked(); 0145 break; 0146 case KTp::ContactCanTextChatRole: 0147 return true; 0148 break; 0149 case KTp::ContactCanAudioCallRole: 0150 return ktpContact->audioCallCapability(); 0151 break; 0152 case KTp::ContactCanVideoCallRole: 0153 return ktpContact->videoCallCapability(); 0154 break; 0155 case KTp::ContactCanFileTransferRole: 0156 return ktpContact->fileTransferCapability(); 0157 break; 0158 case KTp::ContactClientTypesRole: 0159 return ktpContact->clientTypes(); 0160 break; 0161 } 0162 } 0163 0164 return QVariant(); 0165 } 0166 0167 bool KPeopleTranslationProxy::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const 0168 { 0169 QModelIndex sourceIndex = sourceModel()->index(source_row, 0, source_parent); 0170 0171 //if no valid presence (not even "offline") .. reject the contact 0172 return !sourceIndex.data(KPeople::PersonsModel::PersonVCardRole).value<KPeople::AbstractContact::Ptr>()->customProperty(S_KPEOPLE_PROPERTY_PRESENCE).isNull(); 0173 } 0174 0175 QVariant KPeopleTranslationProxy::translatePresence(const QVariant &/*presenceName*/) const 0176 { 0177 return Tp::ConnectionPresenceTypeOffline; 0178 } 0179 0180 QPixmap KPeopleTranslationProxy::contactPixmap(const QModelIndex &index) const 0181 { 0182 QPixmap avatar; 0183 0184 int presenceType = index.data(KTp::ContactPresenceTypeRole).toInt(); 0185 //we need some ID to generate proper cache key for this contact 0186 //so we'll use the contact's uri 0187 const QString id = index.data(KTp::IdRole).toString(); 0188 0189 //key for the pixmap cache, so we can look up the avatar 0190 const QString keyCache = id + (presenceType == Tp::ConnectionPresenceTypeOffline ? QLatin1String("-offline") : QLatin1String("-online")); 0191 0192 //check pixmap cache for the avatar, if not present, load the avatar 0193 if (!QPixmapCache::find(keyCache, avatar)){ 0194 const QVariantList files = index.data(KTp::ContactAvatarPathRole).toList(); 0195 QString file; 0196 if (!files.isEmpty()) { 0197 file = files.first().toUrl().toLocalFile(); 0198 } 0199 0200 //QPixmap::load() checks for empty path 0201 avatar.load(file); 0202 0203 //if the above didn't succeed, we need to load the generic icon 0204 if (avatar.isNull()) { 0205 avatar = KIconLoader::global()->loadIcon(QLatin1String("im-user"), KIconLoader::NoGroup, 96); 0206 } 0207 0208 //if the contact is offline, gray it out 0209 if (presenceType == Tp::ConnectionPresenceTypeOffline) { 0210 QImage image = avatar.toImage(); 0211 const QImage alpha = image.alphaChannel(); 0212 for (int i = 0; i < image.width(); ++i) { 0213 for (int j = 0; j < image.height(); ++j) { 0214 int colour = qGray(image.pixel(i, j)); 0215 image.setPixel(i, j, qRgb(colour, colour, colour)); 0216 } 0217 } 0218 image.setAlphaChannel(alpha); 0219 avatar = avatar.fromImage(image); 0220 } 0221 0222 //insert the contact into pixmap cache for faster lookup 0223 QPixmapCache::insert(keyCache, avatar); 0224 } 0225 0226 return avatar; 0227 }