File indexing completed on 2025-01-19 03:39:52
0001 /* 0002 This file is part of the KContacts framework. 0003 SPDX-FileCopyrightText: 2001 Cornelius Schumacher <schumacher@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "phonenumber.h" 0009 #include "parametermap_p.h" 0010 0011 #include <KLocalizedString> 0012 #include <krandom.h> 0013 0014 #include <QDataStream> 0015 #include <QSharedData> 0016 0017 using namespace KContacts; 0018 0019 static QString cleanupNumber(const QString &input) 0020 { 0021 return input.simplified(); 0022 } 0023 0024 class Q_DECL_HIDDEN PhoneNumber::Private : public QSharedData 0025 { 0026 public: 0027 Private(Type type) 0028 : mId(KRandom::randomString(8)) 0029 , mType(type) 0030 { 0031 } 0032 0033 Private(const Private &other) 0034 : QSharedData(other) 0035 { 0036 mId = other.mId; 0037 mType = other.mType; 0038 mNumber = other.mNumber; 0039 } 0040 0041 QString mId; 0042 QString mNumber; 0043 Type mType; 0044 ParameterMap mParamMap; 0045 }; 0046 0047 PhoneNumber::PhoneNumber() 0048 : d(new Private(Home)) 0049 { 0050 } 0051 0052 PhoneNumber::PhoneNumber(const QString &number, Type type) 0053 : d(new Private(type)) 0054 { 0055 d->mNumber = cleanupNumber(number); 0056 } 0057 0058 PhoneNumber::PhoneNumber(const PhoneNumber &other) 0059 : d(other.d) 0060 { 0061 } 0062 0063 PhoneNumber::~PhoneNumber() 0064 { 0065 } 0066 0067 bool PhoneNumber::operator==(const PhoneNumber &other) const 0068 { 0069 if (d->mId != other.d->mId) { 0070 return false; 0071 } 0072 0073 if (d->mNumber != other.d->mNumber) { 0074 return false; 0075 } 0076 0077 if (d->mType != other.d->mType) { 0078 return false; 0079 } 0080 0081 if (d->mParamMap != other.d->mParamMap) { 0082 return false; 0083 } 0084 0085 return true; 0086 } 0087 0088 bool PhoneNumber::operator!=(const PhoneNumber &other) const 0089 { 0090 return !(other == *this); 0091 } 0092 0093 PhoneNumber &PhoneNumber::operator=(const PhoneNumber &other) 0094 { 0095 if (this != &other) { 0096 d = other.d; 0097 } 0098 0099 return *this; 0100 } 0101 0102 bool PhoneNumber::isEmpty() const 0103 { 0104 return d->mNumber.isEmpty(); 0105 } 0106 0107 void PhoneNumber::setId(const QString &id) 0108 { 0109 d->mId = id; 0110 } 0111 0112 QString PhoneNumber::id() const 0113 { 0114 return d->mId; 0115 } 0116 0117 void PhoneNumber::setNumber(const QString &number) 0118 { 0119 d->mNumber = cleanupNumber(number); 0120 } 0121 0122 QString PhoneNumber::number() const 0123 { 0124 return d->mNumber; 0125 } 0126 0127 QString PhoneNumber::normalizedNumber() const 0128 { 0129 QString result; 0130 result.reserve(d->mNumber.size()); 0131 for (const auto &c : d->mNumber) { 0132 if (c.isDigit() || (c == QLatin1Char('+') && result.isEmpty())) { 0133 result.push_back(c); 0134 } 0135 } 0136 return result; 0137 } 0138 0139 void PhoneNumber::setType(Type type) 0140 { 0141 d->mType = type; 0142 } 0143 0144 PhoneNumber::Type PhoneNumber::type() const 0145 { 0146 return d->mType; 0147 } 0148 0149 QString PhoneNumber::typeLabel() const 0150 { 0151 return typeLabel(type()); 0152 } 0153 0154 PhoneNumber::TypeList PhoneNumber::typeList() 0155 { 0156 static TypeList list; 0157 0158 if (list.isEmpty()) { 0159 list << Home << Work << Msg << Pref << Voice << Fax << Cell << Video // 0160 << Bbs << Modem << Car << Isdn << Pcs << Pager << Undefined; 0161 } 0162 0163 return list; 0164 } 0165 0166 QString PhoneNumber::typeFlagLabel(TypeFlag type) 0167 { 0168 switch (type) { 0169 case Undefined: 0170 return i18nc("Undefined phone type", "Telephone number"); 0171 case Home: 0172 return i18nc("Home phone", "Home"); 0173 case Work: 0174 return i18nc("Work phone", "Work"); 0175 case Msg: 0176 return i18n("Messenger"); 0177 case Pref: 0178 return i18nc("Preferred phone", "Preferred"); 0179 case Voice: 0180 return i18n("Voice"); 0181 case Fax: 0182 return i18n("Fax"); 0183 case Cell: 0184 return i18nc("Mobile Phone", "Mobile"); 0185 case Video: 0186 return i18nc("Video phone", "Video"); 0187 case Bbs: 0188 return i18n("Mailbox"); 0189 case Modem: 0190 return i18n("Modem"); 0191 case Car: 0192 return i18nc("Car Phone", "Car"); 0193 case Isdn: 0194 return i18n("ISDN"); 0195 case Pcs: 0196 return i18n("PCS"); 0197 case Pager: 0198 return i18n("Pager"); 0199 default: 0200 return i18nc("another type of phone", "Other"); 0201 } 0202 } 0203 0204 QString PhoneNumber::typeLabel(Type type) 0205 { 0206 QString label; 0207 bool first = true; 0208 0209 // special cases 0210 // Pref stand alone -> Preferred Number 0211 // Home+Fax or Work+Fax -> combine as initial string 0212 if (type == Pref) { 0213 return i18n("Preferred Number"); 0214 } 0215 0216 if (type & Fax) { 0217 if (type & Home) { 0218 label = i18n("Home Fax"); 0219 first = false; 0220 type &= ~Fax; 0221 type &= ~Home; 0222 } else if (type & Work) { 0223 label = i18n("Work Fax"); 0224 first = false; 0225 type &= ~Fax; 0226 type &= ~Work; 0227 } 0228 } 0229 0230 const TypeList list = typeList(); 0231 for (const auto f : list) { 0232 // these are actually flags 0233 const TypeFlag flag = static_cast<TypeFlag>(static_cast<int>(f)); 0234 if (type & flag) { 0235 if (!first) { 0236 label.append(QLatin1Char('/')); 0237 } 0238 0239 label.append(typeFlagLabel(flag)); 0240 0241 if (first) { 0242 first = false; 0243 } 0244 } 0245 } 0246 0247 return label; 0248 } 0249 0250 bool PhoneNumber::isPreferred() const 0251 { 0252 return type() & Pref; 0253 } 0254 0255 bool PhoneNumber::supportsSms() const 0256 { 0257 return type() & Cell; 0258 } 0259 0260 QString PhoneNumber::toString() const 0261 { 0262 QString str = QLatin1String("PhoneNumber {\n"); 0263 str += QStringLiteral(" Id: %1\n").arg(d->mId); 0264 str += QStringLiteral(" Type: %1\n").arg(typeLabel(d->mType)); 0265 str = d->mParamMap.toString(); 0266 str += QStringLiteral(" Number: %1\n").arg(d->mNumber); 0267 str += QLatin1String("}\n"); 0268 0269 return str; 0270 } 0271 0272 void PhoneNumber::setParams(const ParameterMap ¶ms) 0273 { 0274 d->mParamMap = params; 0275 } 0276 0277 ParameterMap PhoneNumber::params() const 0278 { 0279 return d->mParamMap; 0280 } 0281 0282 QDataStream &KContacts::operator<<(QDataStream &s, const PhoneNumber &phone) 0283 { 0284 return s << phone.d->mId << static_cast<uint>(phone.d->mType) << phone.d->mNumber << phone.d->mParamMap; 0285 } 0286 0287 QDataStream &KContacts::operator>>(QDataStream &s, PhoneNumber &phone) 0288 { 0289 uint type; 0290 s >> phone.d->mId >> type >> phone.d->mNumber >> phone.d->mParamMap; 0291 phone.d->mType = PhoneNumber::Type(type); 0292 0293 return s; 0294 } 0295 0296 #include "moc_phonenumber.cpp"