コード例 #1
0
ファイル: udxfile.cpp プロジェクト: DarkHobbit/doublecontact
bool UDXFile::importRecords(const QString &url, ContactList &list, bool append)
{
    if (!openFile(url, QIODevice::ReadOnly))
        return false;
    // Read XML
    QString err_msg;
    int err_line, err_col;
    if (!setContent(&file, &err_msg, &err_line, &err_col)) {
        _errors << QObject::tr("Can't read content from file %1\n%2\nline %3, col %4\n")
            .arg(url).arg(err_msg).arg(err_line).arg(err_col);
        closeFile();
        return false;
    }
    closeFile();
    // Root element
    QDomElement root = documentElement();
    if (root.nodeName()!="DataExchangeInfo") {
        _errors << QObject::tr("Root node is not 'DataExchangeInfo' at file\n%1").arg(url);
        return false;
    }
    // Codepage, version, expected record count
    QDomElement recInfo = root.firstChildElement("RecordInfo");
    if (recInfo.isNull()) {
        _errors << QObject::tr("Can't find 'RecordInfo' tag at file\n%1").arg(url);
        return false;
    }
    QString charSet = recInfo.firstChildElement("Encoding").text();
    if (charSet.isEmpty()) {
        _errors << QObject::tr("Warning: codepage not found, trying use UTF-8...");
        charSet = "UTF-8";
    }
    QString udxVer = recInfo.firstChildElement("UdxVersion").text();
    if (udxVer.isEmpty()) {
        _errors << QObject::tr("Warning: udx version not found, treat as 1.0...");
        udxVer = "1.0";
    }
    QDomElement vcfInfo = recInfo.firstChildElement("RecordOfvCard");
    QString vcVer = vcfInfo.firstChildElement("vCardVersion").text();
    int expCount = vcfInfo.firstChildElement("vCardRecord").text().toInt();
    // vCard set
    QDomElement vCard = root.firstChildElement("vCard");
    if (vCard.isNull()) {
        _errors << QObject::tr("Can't find 'vCard' records at file\n%1").arg(url);
        return false;
    }
    // QTextCodec* codec = QTextCodec::codecForName(charSet.toLocal8Bit()); TODO not works on windows
    ContactItem item;
    if (!append)
        list.clear();
    QDomElement vCardInfo = vCard.firstChildElement("vCardInfo");
    while (!vCardInfo.isNull()) {
        item.clear();
        item.originalFormat = "UDX";
        item.version = udxVer;
        item.subVersion = vcVer;
        item.id = vCardInfo.firstChildElement("Sequence").text();
        QDomElement fields = vCardInfo.firstChildElement("vCardField");
        if (fields.isNull())
            _errors << QObject::tr("Can't find 'vCardField' at sequence %1").arg(item.id);
        QDomElement field = fields.firstChildElement();
        while (!field.isNull()) {
            QString fldName = field.nodeName().toUpper();
            QString fldValue = field.text(); // codec->toUnicode(field.text().toLocal8Bit()); TODO not works on windows
            if (fldName=="N") {
                fldValue.replace("\\;", " ");
                // In ALL known me udx files part before first ; was EMPTY
                fldValue.remove(";");
                item.names = fldValue.split(" ");
                // If empty parts not in-middle, remove it
                item.dropFinalEmptyNames();
            }
            else if (fldName.startsWith("TEL")) {
                Phone phone;
                phone.number = fldValue;
                if (fldName=="TEL")
                    phone.tTypes << "CELL";
                else if (fldName=="TELHOME")
                    phone.tTypes << "HOME";
                else if (fldName=="TELWORK")
                    phone.tTypes << "WORK";
                else if (fldName=="TELFAX")
                    phone.tTypes << "FAX";
                else
                    _errors << QObject::tr("Unknown phone type: %1 (%2)").arg(phone.number).arg(item.names[0]);
                item.phones.push_back(phone);
            }
            else if (fldName=="ORGNAME")
                item.organization = fldValue;
            else if (fldName=="BDAY")
                item.birthday.value = QDateTime::fromString(fldValue, "yyyyMMdd"); // TODO Maybe, use DateItem::fromString
            else if (fldName=="EMAIL") {
                Email email;
                email.address = fldValue;
                email.emTypes << "pref";
                item.emails.push_back(email);
            }
            else
                _errors << QObject::tr("Unknown 'vCardfield' type: %1").arg(fldName);
            field = field.nextSiblingElement();
        }
        item.calculateFields();
        list.push_back(item);
        vCardInfo = vCardInfo.nextSiblingElement();
    }
    if (list.count()!=expCount)
        _errors << QObject::tr("%1 records read, %2 expected").arg(list.count()).arg(expCount);
    // Unknown tags statistics
    int totalUnknownTags = 0;
    foreach (const ContactItem& _item, list)
        totalUnknownTags += _item.unknownTags.count();
    if (totalUnknownTags)
        _errors << QObject::tr("%1 unknown tags found").arg(totalUnknownTags);
    // Ready
    return (!list.isEmpty());
}
コード例 #2
0
ファイル: udxfile.cpp プロジェクト: DarkHobbit/doublecontact
bool UDXFile::exportRecords(const QString &url, ContactList &list)
{
    QDomDocument::clear();
    QDomElement root = createElement("DataExchangeInfo");
    appendChild(root);
    // Original format also was UDX?
    bool wasUDX = false;
    if (!list.isEmpty())
        if (list[0].originalFormat=="UDX")
            wasUDX = true;
    // XML header
    QDomNode node = createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");
    insertBefore(node, firstChild());
    // UDX header
    QDomElement recInfo = addElement(root, "RecordInfo");
    addElement(recInfo, "VendorInfo", "VendorUDX");
    addElement(recInfo, "DeviceInfo", "DeviceUDX");
    if (wasUDX)
        addElement(recInfo, "UdxVersion", list[0].version);
    else
        addElement(recInfo, "UdxVersion", "1.0");
    addElement(recInfo, "UserAgent", "AgentUDX");
    addElement(recInfo, "UserInfo", "UserUDX");
    addElement(recInfo, "Encoding", "UTF-8");
    addElement(recInfo, "FileSize", "          "); // strongly 10 spaces! (~~)
    addElement(recInfo, "Date", QDate::currentDate().toString("dd.MM.yyyy"));
    addElement(recInfo, "Language","CHS"); // wtf, but this code was in real russian-language udx
    QDomElement vcfInfo = addElement(recInfo, "RecordOfvCard");
    if (wasUDX)
        addElement(vcfInfo, "vCardVersion", list[0].subVersion);
    else
        addElement(vcfInfo, "vCardVersion", "2.1");
    addElement(vcfInfo, "vCardRecord", QString::number(list.count()));
    addElement(vcfInfo, "vCardLength", "          "); // strongly 10 spaces! (~~)
    addElement(recInfo, "RecordOfvCalendar");
    addElement(recInfo, "RecordOfSMS");
    addElement(recInfo, "RecordOfMMS");
    addElement(recInfo, "RecordOfEmail");
    // Parent tag for all records
    QDomElement vCard = addElement(root, "vCard");
    // Add missing sequences to records
    int maxSeq = 0;
    if (wasUDX) { // wasUDX - simply add missing
        foreach (const ContactItem& item, list)
            if (item.id.toInt()>maxSeq)
                    maxSeq = item.id.toInt();
        QSet<int> seqs;
        for (int i=0; i<list.count(); i++) {
            ContactItem& item = list[i];
            int currentID = item.id.toInt();
            if (currentID<1) // simply missing
                item.id = QString::number(++maxSeq);
            if (seqs.contains(currentID)) { // duplicate?
                _errors << QObject::tr("Warning: contact %1, duplicate id %2 changed to %3")
                     .arg(item.visibleName).arg(currentID).arg(++maxSeq);
                item.id = QString::number(maxSeq);
            }
            seqs.insert(item.id.toInt());
        }
    }
    else { // if original wasn't UDX, completely renumerate all
        for (int i=0; i<list.count(); i++)