/*! * Converts \a contacts into a list of corresponding QVersitDocuments, using the format given by * \a versitType. * * Returns true on success. If any of the contacts could not be exported, false is returned and * errorMap() will return a list describing the errors that occurred. The successfully exported * documents will still be available via documents(). * * \sa documents(), errorMap() */ bool QVersitContactExporter::exportContacts( const QList<QContact>& contacts, QVersitDocument::VersitType versitType) { int contactIndex = 0; d->mDocuments.clear(); d->mErrors.clear(); bool ok = true; foreach (const QContact& contact, contacts) { if (contact.isEmpty()) { d->mErrors[contactIndex] = EmptyContactError; ok = false; continue; } QVersitDocument versitDocument; versitDocument.setType(versitType); versitDocument.setComponentType(QLatin1String("VCARD")); d->exportContact(contact, versitDocument); d->mDocuments.append(versitDocument); contactIndex++; } return ok; }
/*! * Converts \a document into a corresponding list of QOrganizerItems. After calling this, the * converted organizer items can be retrieved by calling items(). * * Returns true on success. The document should contain at least one subdocument. In the * importing process, each subdocument roughly corresponds to a QOrganizerItem. If any of the * subdocuments cannot be imported as organizer items (eg. they don't conform to the iCalendar * format), false is returned and errorMap() will return a list describing the errors that occurred. * The successfully imported items will still be available via items(). * * \sa items(), errorMap() */ bool QVersitOrganizerImporter::importDocument(const QVersitDocument& document) { d->mItems.clear(); d->mErrors.clear(); bool ok = true; if (document.type() != QVersitDocument::ICalendar20Type || document.componentType() != QLatin1String("VCALENDAR")) { d->mErrors.insert(-1, QVersitOrganizerImporter::InvalidDocumentError); return false; } const QList<QVersitDocument> subDocuments = document.subDocuments(); if (subDocuments.isEmpty()) { d->mErrors.insert(-1, QVersitOrganizerImporter::EmptyDocumentError); return false; } int documentIndex = 0; foreach (const QVersitDocument& subDocument, subDocuments) { QOrganizerItem item; QVersitOrganizerImporter::Error error; if (d->importDocument(document, subDocument, &item, &error)) { d->mItems.append(item); } else { // importDocument can return false with no error if it's a non-document component if (error != QVersitOrganizerImporter::NoError) { d->mErrors.insert(documentIndex, error); ok = false; } } documentIndex++; }
void MT_CntVersitMyCardPlugin::exportOwnContact() { //create contact QContact phonecontact; QContactName contactName; contactName.setFirstName("Jo"); contactName.setLastName("Black"); phonecontact.saveDetail(&contactName); QContactPhoneNumber number; number.setContexts("Home"); number.setSubTypes("Mobile"); number.setNumber("+02644424429"); phonecontact.saveDetail(&number); //set MyCard detail QContactDetail myCard(MYCARD_DEFINTION_NAME); phonecontact.saveDetail(&myCard); //export QList<QContact> list; list.append(phonecontact); QVersitContactExporter exporter; QVERIFY(exporter.exportContacts(list, QVersitDocument::VCard21Type)); QList<QVersitDocument> documents = exporter.documents(); //X-SELF property is exported if MyCard QVersitDocument document = documents.first(); QVersitProperty property; property.setName(QLatin1String("X-SELF")); property.setValue("0"); bool propertyFound = document.properties().contains(property); QVERIFY(propertyFound); }
QDebug operator<<(QDebug dbg, const QVersitDocument& document) { dbg.nospace() << "QVersitDocument(" << document.type() << ", " << document.componentType() << ')'; foreach (const QVersitProperty& property, document.properties()) { dbg.space() << '\n' << property; } foreach (const QVersitDocument& nested, document.subDocuments()) { dbg.space() << '\n' << nested; } return dbg.maybeSpace(); }
void tst_QVersitProperty::testEmbeddedDocument() { QVersitDocument document; QVersitProperty property; property.setName(QLatin1String("X-tension")); document.addProperty(property); mVersitProperty->setValue(QVariant::fromValue(document)); QList<QVersitProperty> embeddedDocumentProperties = mVersitProperty->value<QVersitDocument>().properties(); QCOMPARE(embeddedDocumentProperties.count(),1); QCOMPARE(embeddedDocumentProperties[0].name(),QLatin1String("X-TENSION")); }
void tst_QVersitWriter::testWritingVersions() { mWriter->setDevice(mOutputDevice); mOutputDevice->open(QBuffer::ReadWrite); QVersitDocument document; QVersitProperty property; property.setName(QString(QString::fromLatin1("FN"))); property.setValue(QString::fromLatin1("John")); document.addProperty(property); QByteArray vCard30( "BEGIN:VCARD\r\n" "VERSION:3.0\r\n" "FN:John\r\n" "END:VCARD\r\n"); QByteArray vCard21( "BEGIN:VCARD\r\n" "VERSION:2.1\r\n" "FN:John\r\n" "END:VCARD\r\n"); // Given no type or componentType, it should be vCard 3.0 QVERIFY(mWriter->startWriting(document)); mWriter->waitForFinished(); QCOMPARE(mOutputDevice->buffer(), vCard30); // document type should override the guess document.setType(QVersitDocument::VCard21Type); mOutputDevice->buffer().clear(); mOutputDevice->seek(0); QVERIFY(mWriter->startWriting(document)); mWriter->waitForFinished(); QCOMPARE(mOutputDevice->buffer(), vCard21); // param to startWriting should override document type mOutputDevice->buffer().clear(); mOutputDevice->seek(0); QVERIFY(mWriter->startWriting(document, QVersitDocument::VCard30Type)); mWriter->waitForFinished(); QCOMPARE(mOutputDevice->buffer(), vCard30); }
/*! * Finds a property in the \a document with the given \a propertyName, adds it to \a toBeRemoved, * and returns it. */ QVersitProperty VersitUtils::takeProperty(const QVersitDocument& document, const QString& propertyName, QList<QVersitProperty>* toBeRemoved) { foreach (const QVersitProperty& currentProperty, document.properties()) { if (currentProperty.name() == propertyName) { *toBeRemoved << currentProperty; return currentProperty; } } return QVersitProperty(); }
void tst_QVersitContactPlugins::testImporterPlugins() { QVersitContactImporter importer("Test"); QVersitDocument document; document.setComponentType("VCARD"); QVersitProperty property; property.setName("FN"); property.setValue("Bob"); document.addProperty(property); QVERIFY(importer.importDocuments(QList<QVersitDocument>() << document)); QCOMPARE(importer.contacts().size(), 1); QList<QContactDetail> details(importer.contacts().first().details("TestDetail")); QCOMPARE(details.size(), 5); // The plugins have had their index set such that they should be executed in reverse order // Check that they are all loaded, and run in the correct order QCOMPARE(details.at(0).value<int>("Plugin"), 5); QCOMPARE(details.at(1).value<int>("Plugin"), 4); QCOMPARE(details.at(2).value<int>("Plugin"), 3); QCOMPARE(details.at(3).value<int>("Plugin"), 2); QCOMPARE(details.at(4).value<int>("Plugin"), 1); }
/*! * Generates a QContact from \a versitDocument. */ bool QVersitContactImporterPrivate::importContact( const QVersitDocument& document, int contactIndex, QContact* contact, QVersitContactImporter::Error* error) { if (document.componentType() != QStringLiteral("VCARD") && document.type() != QVersitDocument::VCard21Type && document.type() != QVersitDocument::VCard30Type) { *error = QVersitContactImporter::InvalidDocumentError; return false; } const QList<QVersitProperty> properties = document.properties(); if (properties.size() == 0) { *error = QVersitContactImporter::EmptyDocumentError; return false; } // First, do the properties with PREF set so they appear first in the contact details foreach (const QVersitProperty& property, properties) { QStringList typeParameters = property.parameters().values(QStringLiteral("TYPE")); if (typeParameters.contains(QStringLiteral("PREF"), Qt::CaseInsensitive)) importProperty(document, property, contactIndex, contact); }
/*! * Converts \a items into a QVersitDocument, using the format given by \a versitType. * Returns true on success. If any of the items could not be exported, false is returned and * errorMap() will return a list describing the errors that occurred. The successfully exported * components will still be available via document(). * * \sa document(), errorMap() */ bool QVersitOrganizerExporter::exportItems( const QList<QOrganizerItem>& items, QVersitDocument::VersitType versitType) { int itemIndex = 0; d->mErrors.clear(); d->mResult.clear(); d->mResult.setType(versitType); d->mResult.setComponentType(QLatin1String("VCALENDAR")); bool ok = true; QList<QVersitDocument> results; foreach (const QOrganizerItem& item, items) { QVersitDocument document; document.setType(versitType); QVersitOrganizerExporter::Error error; if (d->exportItem(item, &document, &error)) { results.append(document); } else { d->mErrors.insert(itemIndex, error); ok = false; } itemIndex++; }
void importExample() { //! [Import example] QVersitContactImporter importer; QVersitDocument document; QVersitProperty property; property.setName(QString::fromAscii("N")); property.setValue("Citizen;John;Q;;"); document.addProperty(property); property.setName(QString::fromAscii("X-UNKNOWN-PROPERTY")); property.setValue("some value"); document.addProperty(property); if (importer.importDocuments(QList<QVersitDocument>() << document)) { QList<QContact> contactList = importer.contacts(); // contactList.first() now contains the "N" property as a QContactName // propertyHandler.mUnknownProperties contains the list of unknown properties } //! [Import example] }
/*! * Encodes the \a document and writes it to the device. A "VERSION:" line is added iff \a * encodeVersion is true. */ bool QVersitDocumentWriter::encodeVersitDocument(const QVersitDocument& document, bool encodeVersion) { mSuccessful = true; if (document.componentType().isEmpty()) { // for compatibility with code for Qt Mobility 1.0, which didn't have componentType writeString(QStringLiteral("BEGIN:VCARD")); } else { writeString(QStringLiteral("BEGIN:") + document.componentType()); } writeCrlf(); if (encodeVersion) { switch (mType) { case QVersitDocument::VCard21Type: writeString(QStringLiteral("VERSION:2.1")); writeCrlf(); break; case QVersitDocument::VCard30Type: writeString(QStringLiteral("VERSION:3.0")); writeCrlf(); break; case QVersitDocument::VCard40Type: writeString(QStringLiteral("VERSION:4.0")); writeCrlf(); break; case QVersitDocument::ICalendar20Type: writeString(QStringLiteral("VERSION:2.0")); writeCrlf(); break; default: ; // don't print version } } foreach (const QVersitProperty& property, document.properties()) { encodeVersitProperty(property); } foreach (const QVersitDocument& document, document.subDocuments()) { encodeVersitDocument(document, false); } if (document.componentType().isEmpty()) { writeString(QStringLiteral("END:VCARD")); } else { writeString(QStringLiteral("END:") + document.componentType()); } writeCrlf(); // This has been set by the methods called from this function return mSuccessful; }
/*! Returns the hash value for \a key. */ uint qHash(const QVersitDocument &key) { int hash = QT_PREPEND_NAMESPACE(qHash)(key.type()); hash += QT_PREPEND_NAMESPACE(qHash)(key.componentType()); hash += key.properties().length() + key.subDocuments().length(); foreach (const QVersitProperty& property, key.properties()) { hash += qHash(property); } foreach (const QVersitDocument& nested, key.subDocuments()) { hash += qHash(nested); } return hash; }
<< (int)QVersitOrganizerExporter::UnderspecifiedOccurrenceError; } void tst_QVersitOrganizerExporter::testExportEventDetails() { QFETCH(QList<QOrganizerItemDetail>, details); QFETCH(QList<QVersitProperty>, expectedProperties); QVersitOrganizerExporter exporter; QOrganizerEvent item; foreach (QOrganizerItemDetail detail, details) { item.saveDetail(&detail); } QVERIFY(exporter.exportItems(QList<QOrganizerItem>() << item)); QVERIFY(exporter.errorMap().isEmpty()); QVersitDocument document = exporter.document(); QList<QVersitDocument> subDocuments = document.subDocuments(); QCOMPARE(subDocuments.size(), 1); foreach(const QVersitProperty& expectedProperty, expectedProperties) { QList<QVersitProperty> actualProperties = findPropertiesByName(subDocuments.first(), expectedProperty.name()); if (!actualProperties.contains(expectedProperty)) { qDebug() << "Actual:" << actualProperties; qDebug() << "Expected to find:" << expectedProperty; QVERIFY(false); } } } void tst_QVersitOrganizerExporter::testExportEventDetails_data()
/*! * Export QT Contact into Versit Document. */ void QVersitContactExporterPrivate::exportContact( const QContact& contact, QVersitDocument& document) { QList<QContactDetail> allDetails = contact.details(); foreach (const QContactDetail& detail, allDetails) { // If the custom detail handler handles it, we don't have to. if (mDetailHandler && mDetailHandler->preProcessDetail(contact, detail, &document)) continue; QList<QVersitProperty> removedProperties; QList<QVersitProperty> generatedProperties; QSet<QString> processedFields; if (detail.definitionName() == QContactName::DefinitionName) { encodeName(detail, document, &removedProperties, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactPhoneNumber::DefinitionName) { encodePhoneNumber(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactEmailAddress::DefinitionName) { encodeEmail(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactAddress::DefinitionName) { encodeAddress(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactGuid::DefinitionName) { encodeUid(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactUrl::DefinitionName) { encodeUrl(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactTimestamp::DefinitionName) { encodeRev(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactBirthday::DefinitionName) { encodeBirthDay(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactGeoLocation::DefinitionName) { encodeGeoLocation(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactNote::DefinitionName) { encodeNote(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactOrganization::DefinitionName) { encodeOrganization(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactRingtone::DefinitionName) { encodeRingtone(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactThumbnail::DefinitionName) { encodeThumbnail(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactAvatar::DefinitionName){ encodeAvatar(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactAnniversary::DefinitionName) { encodeAnniversary(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactNickname::DefinitionName) { encodeNickname(detail, document, &removedProperties, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactTag::DefinitionName) { encodeTag(detail, document, &removedProperties, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactGender::DefinitionName) { encodeGender(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactOnlineAccount::DefinitionName) { encodeOnlineAccount(detail, &generatedProperties, &processedFields); } else if (detail.definitionName() == QContactFamily::DefinitionName) { encodeFamily(detail, &generatedProperties, &processedFields); } // run plugin handlers foreach (QVersitContactExporterDetailHandlerV2* handler, mPluginDetailHandlers) { handler->detailProcessed(contact, detail, document, &processedFields, &removedProperties, &generatedProperties); } // run the v2 handler, if set if (mDetailHandler2 && mDetailHandlerVersion > 1) { mDetailHandler2->detailProcessed(contact, detail, document, &processedFields, &removedProperties, &generatedProperties); } foreach(const QVersitProperty& property, removedProperties) { document.removeProperty(property); }