File indexing completed on 2025-01-19 04:46:32
0001 /* 0002 SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "importwindowcontact.h" 0008 #include "importexportwindowscontactplugin_debug.h" 0009 #include <KLocalizedString> 0010 #include <KMessageBox> 0011 #include <QDomDocument> 0012 #include <QFile> 0013 0014 // https://docs.microsoft.com/en-us/previous-versions//ms735869(v=vs.85) 0015 0016 ImportWindowContact::ImportWindowContact() = default; 0017 0018 ImportWindowContact::~ImportWindowContact() = default; 0019 0020 KContacts::Addressee::List ImportWindowContact::importFile(const QString &fileName) 0021 { 0022 KContacts::Addressee::List lst; 0023 QFile file(fileName); 0024 if (!file.open(QIODevice::ReadOnly)) { 0025 if (!mAutoTest) { 0026 const QString msg = i18n("<qt>Unable to open <b>%1</b> for reading.</qt>", fileName); 0027 KMessageBox::error(mParentWidget, msg); 0028 } else { 0029 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << "Impossible to open file: " << fileName; 0030 } 0031 return lst; 0032 } 0033 QDomDocument doc; 0034 if (loadDomElement(doc, &file)) { 0035 QDomElement list = doc.documentElement(); 0036 if (list.isNull()) { 0037 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << "No list defined in file"; 0038 } else { 0039 KContacts::Addressee contact; 0040 if (mAutoTest) { 0041 contact.setUid(QStringLiteral("foo")); 0042 } 0043 for (QDomElement e = list.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { 0044 const QString tag = e.tagName(); 0045 if (tag == QLatin1StringView("c:EmailAddressCollection")) { 0046 KContacts::Email::List lstEmails; 0047 for (QDomElement emails = e.firstChildElement(); !emails.isNull(); emails = emails.nextSiblingElement()) { 0048 const QString emailsTag = emails.tagName(); 0049 if (emailsTag == QLatin1StringView("c:EmailAddress")) { 0050 KContacts::Email email; 0051 for (QDomElement addresses = emails.firstChildElement(); !addresses.isNull(); addresses = addresses.nextSiblingElement()) { 0052 const QString addressesTag = addresses.tagName(); 0053 if (addressesTag == QLatin1StringView("c:Type")) { 0054 } else if (addressesTag == QLatin1StringView("c:Address")) { 0055 email.setEmail(addresses.text()); 0056 } else { 0057 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " address tag not supported yet " << addressesTag; 0058 } 0059 } 0060 if (email.isValid()) { 0061 lstEmails << email; 0062 } 0063 } 0064 contact.setEmailList(lstEmails); 0065 } 0066 } else if (tag == QLatin1StringView("c:NameCollection")) { 0067 for (QDomElement name = e.firstChildElement(); !name.isNull(); name = name.nextSiblingElement()) { 0068 const QString nameTag = name.tagName(); 0069 if (nameTag == QLatin1StringView("c:Name")) { 0070 for (QDomElement nameInfo = name.firstChildElement(); !nameInfo.isNull(); nameInfo = nameInfo.nextSiblingElement()) { 0071 const QString nameInfoTag = nameInfo.tagName(); 0072 if (nameInfoTag == QLatin1StringView("c:FormattedName")) { 0073 contact.setName(nameInfo.text()); 0074 } else if (nameInfoTag == QLatin1StringView("c:GivenName")) { 0075 contact.setGivenName(nameInfo.text()); 0076 } else if (nameInfoTag == QLatin1StringView("c:FamilyName")) { 0077 contact.setFamilyName(nameInfo.text()); 0078 } else if (nameInfoTag == QLatin1StringView("c:FormattedName")) { 0079 contact.setFormattedName(nameInfo.text()); 0080 } else if (nameInfoTag == QLatin1StringView("c:Title")) { 0081 contact.setTitle(nameInfo.text()); 0082 } else if (nameInfoTag == QLatin1StringView("c:NickName")) { 0083 contact.setNickName(nameInfo.text()); 0084 } else if (nameInfoTag == QLatin1StringView("c:Prefix")) { 0085 contact.setPrefix(nameInfo.text()); 0086 } else if (nameInfoTag == QLatin1StringView("c:Suffix")) { 0087 contact.setSuffix(nameInfo.text()); 0088 } else { 0089 // TODO middlename/generation 0090 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " name tag not supported yet " << nameInfoTag; 0091 } 0092 } 0093 } else { 0094 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " name tag unknown:" << nameTag; 0095 } 0096 } 0097 } else if (tag == QLatin1StringView("c:PhoneNumberCollection")) { 0098 for (QDomElement number = e.firstChildElement(); !number.isNull(); number = number.nextSiblingElement()) { 0099 const QString numberTag = number.tagName(); 0100 if (numberTag == QLatin1StringView("c:PhoneNumber")) { 0101 KContacts::PhoneNumber phoneNumber; 0102 for (QDomElement numberInfo = number.firstChildElement(); !numberInfo.isNull(); numberInfo = numberInfo.nextSiblingElement()) { 0103 const QString numberInfoTag = numberInfo.tagName(); 0104 if (numberInfoTag == QLatin1StringView("c:Number")) { 0105 phoneNumber.setNumber(numberInfo.text()); 0106 } else { 0107 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " number info tag not supported yet:" << numberInfoTag; 0108 } 0109 } 0110 if (!phoneNumber.isEmpty()) { 0111 contact.insertPhoneNumber(phoneNumber); 0112 } 0113 } else { 0114 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " number tag unknown:" << numberTag; 0115 } 0116 } 0117 } else if (tag == QLatin1StringView("c:IMAddressCollection")) { 0118 for (QDomElement im = e.firstChildElement(); !im.isNull(); im = im.nextSiblingElement()) { 0119 const QString imTag = im.tagName(); 0120 if (imTag == QLatin1StringView("c:IMAddress")) { 0121 KContacts::Impp impp; 0122 for (QDomElement imInfo = im.firstChildElement(); !imInfo.isNull(); imInfo = imInfo.nextSiblingElement()) { 0123 const QString imInfoTag = imInfo.tagName(); 0124 if (imInfoTag == QLatin1StringView("c:Value")) { 0125 impp.setAddress(QUrl(imInfo.text())); 0126 } else { 0127 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " im info tag not supported yet " << imInfoTag; 0128 } 0129 } 0130 if (impp.isValid()) { 0131 contact.insertImpp(impp); 0132 } 0133 } else { 0134 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " im tag unknown:" << imTag; 0135 } 0136 } 0137 } else if (tag == QLatin1StringView("c:PhotoCollection")) { 0138 for (QDomElement photo = e.firstChildElement(); !photo.isNull(); photo = photo.nextSiblingElement()) { 0139 const QString photoTag = photo.tagName(); 0140 if (photoTag == QLatin1StringView("c:Photo")) { 0141 KContacts::Picture picture; 0142 for (QDomElement photoInfo = photo.firstChildElement(); !photoInfo.isNull(); photoInfo = photoInfo.nextSiblingElement()) { 0143 const QString photoInfoTag = photoInfo.tagName(); 0144 if (photoInfoTag == QLatin1StringView("c:Value")) { 0145 const QString contentType = photoInfo.attribute(QStringLiteral("c:ContentType")); 0146 picture.setRawData(photoInfo.text().toUtf8(), contentType); 0147 } else if (photoInfoTag == QLatin1StringView("c:Url")) { 0148 picture.setUrl(photoInfo.text()); 0149 } else { 0150 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " photo info tag not supported yet " << photoInfoTag; 0151 } 0152 } 0153 if (!picture.isEmpty()) { 0154 contact.setPhoto(picture); 0155 } 0156 } else { 0157 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " photo tag unknown:" << photoTag; 0158 } 0159 } 0160 } else if (tag == QLatin1StringView("c:PhysicalAddressCollection")) { 0161 for (QDomElement address = e.firstChildElement(); !address.isNull(); address = address.nextSiblingElement()) { 0162 const QString addressTag = address.tagName(); 0163 if (addressTag == QLatin1StringView("c:PhysicalAddress")) { 0164 KContacts::Address addressType; 0165 for (QDomElement addressInfo = address.firstChildElement(); !addressInfo.isNull(); addressInfo = addressInfo.nextSiblingElement()) { 0166 const QString addressInfoTag = addressInfo.tagName(); 0167 if (addressInfoTag == QLatin1StringView("c:AddressLabel")) { 0168 addressType.setLabel(addressInfo.text()); 0169 } else if (addressInfoTag == QLatin1StringView("c:Street")) { 0170 addressType.setStreet(addressInfo.text()); 0171 } else if (addressInfoTag == QLatin1StringView("c:Locality")) { 0172 addressType.setLocality(addressInfo.text()); 0173 } else if (addressInfoTag == QLatin1StringView("c:Region")) { 0174 addressType.setRegion(addressInfo.text()); 0175 } else if (addressInfoTag == QLatin1StringView("c:Country")) { 0176 addressType.setCountry(addressInfo.text()); 0177 } else if (addressInfoTag == QLatin1StringView("c:PostalCode")) { 0178 addressType.setPostalCode(addressInfo.text()); 0179 } else if (addressInfoTag == QLatin1StringView("c:POBox")) { 0180 addressType.setPostOfficeBox(addressInfo.text()); 0181 } else { 0182 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " address info tag not supported yet " << addressInfoTag; 0183 } 0184 } 0185 if (!addressType.isEmpty()) { 0186 contact.insertAddress(addressType); 0187 } 0188 } else { 0189 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " address tag unknown:" << addressTag; 0190 } 0191 } 0192 } else if (tag == QLatin1StringView("c:PositionCollection")) { 0193 for (QDomElement position = e.firstChildElement(); !position.isNull(); position = position.nextSiblingElement()) { 0194 const QString positionTag = position.tagName(); 0195 if (positionTag == QLatin1StringView("c:Position")) { 0196 for (QDomElement positionInfo = position.firstChildElement(); !positionInfo.isNull(); 0197 positionInfo = positionInfo.nextSiblingElement()) { 0198 const QString positionInfoTag = positionInfo.tagName(); 0199 if (positionInfoTag == QLatin1StringView("c:Organization")) { 0200 contact.setOrganization(positionInfo.text()); 0201 } else if (positionInfoTag == QLatin1StringView("c:Department")) { 0202 contact.setDepartment(positionInfo.text()); 0203 } else if (positionInfoTag == QLatin1StringView("c:Office")) { 0204 contact.setOffice(positionInfo.text()); 0205 } else if (positionInfoTag == QLatin1StringView("c:Profession")) { 0206 contact.setProfession(positionInfo.text()); 0207 } else if (positionInfoTag == QLatin1StringView("c:Role")) { 0208 contact.setRole(positionInfo.text()); 0209 } else { 0210 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " position info tag not supported yet " << positionInfoTag; 0211 } 0212 } 0213 } else { 0214 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " position tag unknown:" << positionTag; 0215 } 0216 } 0217 } else if (tag == QLatin1StringView("c:Gender")) { // TODO verify it 0218 KContacts::Gender gender; 0219 const QString genderStr = e.text(); 0220 if (genderStr == QLatin1StringView("Male")) { 0221 gender.setGender(QStringLiteral("H")); 0222 } else if (genderStr == QLatin1StringView("Female")) { 0223 gender.setGender(QStringLiteral("F")); 0224 } else { 0225 // Don't provide gender 0226 continue; 0227 } 0228 contact.setGender(gender); 0229 } else if (tag == QLatin1StringView("c:Notes")) { // TODO verify it 0230 contact.setNote(e.text()); 0231 } else if (tag == QLatin1StringView("c:UrlCollection")) { // TODO verify it 0232 for (QDomElement url = e.firstChildElement(); !url.isNull(); url = url.nextSiblingElement()) { 0233 const QString urlTag = url.tagName(); 0234 if (urlTag == QLatin1StringView("c:Url")) { 0235 for (QDomElement urlInfo = url.firstChildElement(); !urlInfo.isNull(); urlInfo = urlInfo.nextSiblingElement()) { 0236 const QString urlInfoTag = urlInfo.tagName(); 0237 if (urlInfoTag == QLatin1StringView("c:Value")) { 0238 KContacts::ResourceLocatorUrl resourceLocalUrl; 0239 resourceLocalUrl.setUrl(QUrl::fromUserInput(urlInfo.text())); 0240 contact.insertExtraUrl(resourceLocalUrl); 0241 } else { 0242 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " url info tag not supported yet " << urlInfoTag; 0243 } 0244 } 0245 } else { 0246 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << " url tag unknown:" << urlTag; 0247 } 0248 } 0249 } else { 0250 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) << "unknown tag " << tag; 0251 } 0252 } 0253 lst << contact; 0254 } 0255 } 0256 return lst; 0257 } 0258 0259 bool ImportWindowContact::loadDomElement(QDomDocument &doc, QFile *file) 0260 { 0261 QString errorMsg; 0262 int errorRow; 0263 int errorCol; 0264 if (!doc.setContent(file, &errorMsg, &errorRow, &errorCol)) { 0265 qCWarning(IMPORTEXPORTWINDOWSCONTACTPLUGIN_LOG) 0266 << "Unable to load document.Parse error in line " << errorRow << ", col " << errorCol << ": " << errorMsg; 0267 return false; 0268 } 0269 return true; 0270 } 0271 0272 void ImportWindowContact::setParentWidget(QWidget *parentWidget) 0273 { 0274 mParentWidget = parentWidget; 0275 } 0276 0277 void ImportWindowContact::setAutoTests(bool b) 0278 { 0279 mAutoTest = b; 0280 }