Added ability to format phone numbers in modern way.
This commit is contained in:
parent
e5b85bbaf1
commit
e4640590d0
2 changed files with 85 additions and 0 deletions
|
@ -307,6 +307,81 @@ QString CountriesInstance::countryISO2ByPhone(const QString &phone) {
|
||||||
return (i != listByCode.cend()) ? (*i)->iso2 : QString();
|
return (i != listByCode.cend()) ? (*i)->iso2 : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FormatResult CountriesInstance::format(FormatArgs args) {
|
||||||
|
// Ported from TDLib.
|
||||||
|
const auto &phoneNumber = args.phone;
|
||||||
|
|
||||||
|
const Info *bestCountryPtr = nullptr;
|
||||||
|
const CallingCodeInfo *bestCallingCodePtr = nullptr;
|
||||||
|
auto bestLength = size_t(0);
|
||||||
|
auto isPrefix = false;
|
||||||
|
for (const auto &country : list()) {
|
||||||
|
for (auto &callingCode : country.codes) {
|
||||||
|
if (phoneNumber.startsWith(callingCode.callingCode)) {
|
||||||
|
const auto codeSize = callingCode.callingCode.size();
|
||||||
|
for (const auto &prefix : callingCode.prefixes) {
|
||||||
|
if (prefix.startsWith(phoneNumber.midRef(codeSize))) {
|
||||||
|
isPrefix = true;
|
||||||
|
}
|
||||||
|
if ((codeSize + prefix.size()) > bestLength &&
|
||||||
|
phoneNumber.midRef(codeSize).startsWith(prefix)) {
|
||||||
|
bestCountryPtr = &country;
|
||||||
|
bestCallingCodePtr = &callingCode;
|
||||||
|
bestLength = codeSize + prefix.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (callingCode.callingCode.startsWith(phoneNumber)) {
|
||||||
|
isPrefix = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestCountryPtr == nullptr) {
|
||||||
|
return FormatResult{ .formatted = phoneNumber };
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto formattedPart = phoneNumber.mid(
|
||||||
|
bestCallingCodePtr->callingCode.size());
|
||||||
|
auto formattedResult = formattedPart;
|
||||||
|
auto maxMatchedDigits = size_t(0);
|
||||||
|
for (auto &pattern : bestCallingCodePtr->patterns) {
|
||||||
|
auto result = QString();
|
||||||
|
auto currentPatternPos = int(0);
|
||||||
|
auto isFailedMatch = false;
|
||||||
|
auto matchedDigits = size_t(0);
|
||||||
|
for (const auto &c : formattedPart) {
|
||||||
|
while ((currentPatternPos < pattern.size())
|
||||||
|
&& (pattern[currentPatternPos] != 'X')
|
||||||
|
&& !pattern[currentPatternPos].isDigit()) {
|
||||||
|
result += pattern[currentPatternPos++];
|
||||||
|
}
|
||||||
|
if (currentPatternPos == pattern.size()) {
|
||||||
|
result += ' ';
|
||||||
|
}
|
||||||
|
if ((currentPatternPos >= pattern.size())
|
||||||
|
|| (pattern[currentPatternPos] == 'X')) {
|
||||||
|
result += c;
|
||||||
|
currentPatternPos++;
|
||||||
|
} else {
|
||||||
|
if (c == pattern[currentPatternPos]) {
|
||||||
|
matchedDigits++;
|
||||||
|
result += c;
|
||||||
|
currentPatternPos++;
|
||||||
|
} else {
|
||||||
|
isFailedMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isFailedMatch && matchedDigits >= maxMatchedDigits) {
|
||||||
|
maxMatchedDigits = matchedDigits;
|
||||||
|
formattedResult = std::move(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FormatResult{ .formatted = formattedResult };
|
||||||
|
}
|
||||||
|
|
||||||
CountriesInstance &Instance() {
|
CountriesInstance &Instance() {
|
||||||
return SingleInstance;
|
return SingleInstance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,14 @@ struct Info {
|
||||||
bool isHidden = false;
|
bool isHidden = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FormatResult {
|
||||||
|
QString formatted;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FormatArgs {
|
||||||
|
QString phone;
|
||||||
|
};
|
||||||
|
|
||||||
class CountriesInstance final {
|
class CountriesInstance final {
|
||||||
public:
|
public:
|
||||||
using Map = QHash<QString, const Info *>;
|
using Map = QHash<QString, const Info *>;
|
||||||
|
@ -40,6 +48,8 @@ public:
|
||||||
[[nodiscard]] QString countryNameByISO2(const QString &iso);
|
[[nodiscard]] QString countryNameByISO2(const QString &iso);
|
||||||
[[nodiscard]] QString countryISO2ByPhone(const QString &phone);
|
[[nodiscard]] QString countryISO2ByPhone(const QString &phone);
|
||||||
|
|
||||||
|
[[nodiscard]] FormatResult format(FormatArgs args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Info> _list;
|
std::vector<Info> _list;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue