File indexing completed on 2025-03-23 11:10:14
0001 // SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im> 0002 // SPDX-FileCopyrightText: 2021 Alexey Andreyev <aa13q@ya.ru> 0003 // 0004 // SPDX-License-Identifier: LicenseRef-KDE-Accepted-GPL 0005 0006 #include "contact-phone-number-mapper.h" 0007 0008 #include <KPeopleBackend/AbstractContact> 0009 #include <QDebug> 0010 #include <QThread> 0011 0012 #include "phone-number-utils.h" 0013 0014 ContactPhoneNumberMapper &ContactPhoneNumberMapper::instance(bool testMode) 0015 { 0016 static ContactPhoneNumberMapper instance(testMode); 0017 return instance; 0018 } 0019 0020 ContactPhoneNumberMapper::ContactPhoneNumberMapper(bool testMode) 0021 : QObject() 0022 , _model(new KPeople::PersonsModel(this)) 0023 { 0024 _cellCountry = _localeCountry; 0025 if (testMode) { 0026 // Start right away since we don't wait on the country code 0027 processRows(0, _model->rowCount() - 1); 0028 } 0029 0030 _localeCountry = phoneNumberUtils::localeCountryCode(); 0031 0032 // data updates 0033 // we only care about additional data, not remove one 0034 connect(_model, &QAbstractItemModel::rowsInserted, this, [this](const QModelIndex &, int first, int last) { 0035 if (_cellCountry.empty()) { 0036 // We can't process until we know the cell country info 0037 return; 0038 } 0039 processRows(first, last); 0040 }); 0041 processRows(0, _model->rowCount() - 1); 0042 } 0043 0044 void ContactPhoneNumberMapper::changeCountry(const QString &countryCode) 0045 { 0046 _cellCountry = countryCode.toStdString(); 0047 0048 _numberToUri.clear(); 0049 0050 // Once we know the country we can start processing the contacts 0051 processRows(0, _model->rowCount() - 1); 0052 } 0053 0054 void ContactPhoneNumberMapper::processRows(const int first, const int last) 0055 { 0056 QVector<QString> affectedNumbers; 0057 for (int i = first; i <= last; i++) { 0058 const auto index = _model->index(i); 0059 0060 // Yes, this code has to be illogical. PersonsModel::PersonVCardRole is actually supposed 0061 // to return an AbstractContact::Ptr, although the name suggests differneltly. Luckily we can get 0062 // the actual VCard from it. 0063 const auto phoneNumbers = _model->data(index, KPeople::PersonsModel::PersonVCardRole) 0064 .value<KPeople::AbstractContact::Ptr>() 0065 ->customProperty(KPeople::AbstractContact::AllPhoneNumbersProperty) 0066 .toStringList(); 0067 0068 const auto personUri = _model->data(index, KPeople::PersonsModel::PersonUriRole).toString(); 0069 0070 for (const QString &numberString : phoneNumbers) { 0071 const auto maybeNormalizedNumber = phoneNumberUtils::normalizeNumber(numberString.toStdString(), phoneNumberUtils::International, _cellCountry); 0072 0073 if (std::holds_alternative<std::string>(maybeNormalizedNumber)) { 0074 const auto &normalizedNumber = std::get<std::string>(maybeNormalizedNumber); 0075 _numberToUri[normalizedNumber] = personUri; 0076 affectedNumbers.append(QString::fromStdString(normalizedNumber)); 0077 } else { 0078 continue; 0079 } 0080 0081 if (_cellCountry != _localeCountry) { 0082 const auto maybeNormalizedNumberLocale = 0083 phoneNumberUtils::normalizeNumber(numberString.toStdString(), phoneNumberUtils::International, _localeCountry); 0084 0085 if (std::holds_alternative<std::string>(maybeNormalizedNumberLocale)) { 0086 const auto &normalizedNumber = std::get<std::string>(maybeNormalizedNumberLocale); 0087 _numberToUri[normalizedNumber] = personUri; 0088 affectedNumbers.append(QString::fromStdString(normalizedNumber)); 0089 } 0090 } 0091 } 0092 } 0093 0094 Q_EMIT contactsChanged(affectedNumbers); 0095 } 0096 0097 QString ContactPhoneNumberMapper::uriForNumber(const QString &phoneNumber) const 0098 { 0099 const auto maybeNormalizedNumber = phoneNumberUtils::normalizeNumber(phoneNumber.toStdString(), phoneNumberUtils::International, _cellCountry); 0100 0101 if (std::holds_alternative<std::string>(maybeNormalizedNumber)) { 0102 const auto &normalizedNumber = std::get<std::string>(maybeNormalizedNumber); 0103 if (_numberToUri.contains(normalizedNumber)) { 0104 return _numberToUri.at(normalizedNumber); 0105 } 0106 } else { 0107 return QString(); 0108 } 0109 0110 if (_cellCountry != _localeCountry) { 0111 const auto maybeNormalizedNumberLocale = phoneNumberUtils::normalizeNumber(phoneNumber.toStdString(), phoneNumberUtils::International, _localeCountry); 0112 0113 if (std::holds_alternative<std::string>(maybeNormalizedNumberLocale)) { 0114 const auto &normalizedNumber = std::get<std::string>(maybeNormalizedNumberLocale); 0115 if (_numberToUri.contains(normalizedNumber)) { 0116 return _numberToUri.at(normalizedNumber); 0117 } 0118 } 0119 } 0120 0121 return QString(); 0122 }