20
21
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
24
#include "phoneutils_p.h"
25
#include "phonenumberutils_p.h"
27
PhoneUtils::PhoneUtils(QObject *parent) :
32
bool PhoneUtils::comparePhoneNumbers(const QString &number1, const QString &number2)
34
if (isPhoneNumber(number1) && isPhoneNumber(number2)) {
35
return PhoneNumberUtils::compareLoosely(number1, number2);
37
return number1 == number2;
40
bool PhoneUtils::isPhoneNumber(const QString &identifier) {
41
// remove all non diable digits
42
QString finalNumber = QString(identifier).replace(QRegExp("[p+*#/(),;-]"),"");
43
finalNumber = finalNumber.replace(QRegExp("(\\s+)"), "");
44
// if empty, the number is invalid
45
if (finalNumber.isEmpty())
48
finalNumber = finalNumber.replace(QRegExp("(\\d+)"), "");
49
return finalNumber.isEmpty();
52
// TODO improve this normalization algorithm. More complex numbers
53
// like "+1 234 234-1234 w 12345678#" should be normalizd to "+12342341234"
54
QString PhoneUtils::normalizePhoneNumber(const QString &identifier) {
55
if (!isPhoneNumber(identifier)) {
56
// do not normalize non phone numbers
59
QRegExp regexp = QRegExp("(\\s+)");
60
QString finalNumber = QString(identifier).replace(regexp,"");
61
finalNumber = finalNumber.replace(QRegExp("[()/-]"),"");
27
#include <phonenumbers/phonenumbermatch.h>
28
#include <phonenumbers/phonenumbermatcher.h>
29
#include <phonenumbers/phonenumberutil.h>
33
#include <QTextStream>
36
QString PhoneUtils::mMcc = QString();
38
void PhoneUtils::setMcc(const QString &mcc)
43
QString PhoneUtils::countryCodeForMCC(const QString &mcc, bool useFallback)
45
static QMap<QString, QString> countryCodes;
46
if (countryCodes.isEmpty()) {
47
QFile countryCodesFile(":/countrycodes.txt");
48
if (!countryCodesFile.open(QFile::ReadOnly)) {
49
qCritical() << "Failed to open " << countryCodesFile.fileName();
55
QTextStream stream(&countryCodesFile);
56
while (!stream.atEnd()) {
57
QString line = stream.readLine();
58
QStringList tuple = line.split(":");
59
if (tuple.size() != 2) {
60
qCritical() << "Failed to parse line" << line;
66
countryCodes[tuple[0]] = tuple[1];
69
if (!countryCodes.contains(mcc) && useFallback) {
72
return countryCodes[mcc];
75
QString PhoneUtils::region()
77
QString countryCode = QLocale::system().name().split("_").last();
78
if (countryCode.size() < 2) {
79
// fallback to US if no valid country code was provided, otherwise libphonenumber
80
// will fail to parse any numbers
86
QString PhoneUtils::normalizePhoneNumber(const QString &phoneNumber)
88
static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
89
if (!isPhoneNumber(phoneNumber)) {
92
std::string number = phoneNumber.toStdString();
93
phonenumberUtil->NormalizeDiallableCharsOnly(&number);
94
return QString::fromStdString(number);
97
bool PhoneUtils::comparePhoneNumbers(const QString &phoneNumberA, const QString &phoneNumberB)
99
static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
100
// if any of the number isn't a phone number, just do a simple string comparison
101
if (!isPhoneNumber(phoneNumberA) || !isPhoneNumber(phoneNumberB)) {
102
return phoneNumberA == phoneNumberB;
104
i18n::phonenumbers::PhoneNumberUtil::MatchType match = phonenumberUtil->
105
IsNumberMatchWithTwoStrings(phoneNumberA.toStdString(),
106
phoneNumberB.toStdString());
107
return (match > i18n::phonenumbers::PhoneNumberUtil::NO_MATCH);
110
bool PhoneUtils::isPhoneNumber(const QString &phoneNumber)
112
static i18n::phonenumbers::PhoneNumberUtil *phonenumberUtil = i18n::phonenumbers::PhoneNumberUtil::GetInstance();
113
std::string formattedNumber;
114
i18n::phonenumbers::PhoneNumber number;
115
i18n::phonenumbers::PhoneNumberUtil::ErrorType error;
116
error = phonenumberUtil->Parse(phoneNumber.toStdString(), countryCodeForMCC(mMcc, true).toStdString(), &number);
119
case i18n::phonenumbers::PhoneNumberUtil::INVALID_COUNTRY_CODE_ERROR:
120
qWarning() << "Invalid country code for:" << phoneNumber;
122
case i18n::phonenumbers::PhoneNumberUtil::NOT_A_NUMBER:
123
qWarning() << "The phone number is not a valid number:" << phoneNumber;
125
case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_AFTER_IDD:
126
case i18n::phonenumbers::PhoneNumberUtil::TOO_SHORT_NSN:
127
case i18n::phonenumbers::PhoneNumberUtil::TOO_LONG_NSN:
128
qWarning() << "Invalid phone number" << phoneNumber;