void ContactConnection::addContact(QContact contact) { mEngine->setNotifySimulator(false); QContactManager::Error error; QContactChangeSet changeSet; // if the created contact would get a too high id, delete // the contacts that the simulator knows nothing about QContactMemoryEngineData *edata = QContactMemoryEngineData::data(mEngine); if (edata->m_nextContactId + 1 > contact.localId()) { for (QContactLocalId id = contact.localId(); id <= edata->m_nextContactId; ++id) mEngine->removeContact(id, changeSet, &error); } // make sure the inserted contact gets the same id as in the simulator edata->m_nextContactId = contact.localId() - 1; // add (set localid to 0 first, otherwise the engine thinks we want to update a contact) QContactId newId = contact.id(); newId.setLocalId(0); contact.setId(newId); mEngine->saveContact(&contact, changeSet, &error); mEngine->setNotifySimulator(true); }
QContactManager::Error GContactsBackend::modifyContact(const QString &aID, QContact &aContact) { FUNCTION_CALL_TRACE; Q_ASSERT (iMgr); LOG_DEBUG("Modifying a Contact with ID" << aID); QContactManager::Error modificationStatus = QContactManager::UnspecifiedError; QContact oldContactData; getContact(QContactId::fromString(aID), oldContactData); aContact.setId(oldContactData.id()); oldContactData = aContact; bool modificationOk = iMgr->saveContact(&oldContactData); modificationStatus = iMgr->error(); if(!modificationOk) { // either contact exists or something wrong with one of the detailed definitions LOG_WARNING("Contact Modification Failed"); } // no else return modificationStatus; }
bool CntSimStorePrivate::read(int index, int numSlots, QContactManager::Error *error) { if (IsActive()) { *error = QContactManager::LockedError; return false; } // ON store requires different read approach. // fetch ON contacts synchronously since there are usually only couple of them if (m_storeInfo.m_storeName == KParameterValueSimStoreNameOn) { TRequestStatus status; QList<QContact> fetchedContacts; for (int i = index; i <= numSlots; i++) { RMobileONStore::TMobileONEntryV1 onEntry; onEntry.iIndex = i; RMobileONStore::TMobileONEntryV1Pckg onEntryPkg(onEntry); m_etelOnStore.Read(status, onEntryPkg); User::WaitForRequest(status); if (status.Int() == KErrNone) { QContact c; c.setType(QContactType::TypeContact); QContactName name; name.setCustomLabel(QString::fromUtf16(onEntry.iText.Ptr(), onEntry.iText.Length())); c.saveDetail(&name); QContactPhoneNumber number; number.setNumber(QString::fromUtf16(onEntry.iNumber.iTelNumber.Ptr(), onEntry.iNumber.iTelNumber.Length())); c.saveDetail(&number); QScopedPointer<QContactId> contactId(new QContactId()); contactId->setLocalId(i); contactId->setManagerUri(m_managerUri); c.setId(*contactId); fetchedContacts.append(c); } } emit m_simStore.readComplete(fetchedContacts, QContactManager::NoError); *error = QContactManager::NoError; return true; } // start reading m_buffer.Zero(); m_buffer.ReAlloc(KOneSimContactBufferSize*numSlots); m_etelStore.Read(iStatus, index, numSlots, m_buffer); SetActive(); m_state = ReadState; *error = QContactManager::NoError; return true; }
QContactManager::Error ContactsBackend::modifyContact(const QString &aID, const QString &aContact) { FUNCTION_CALL_TRACE; LOG_DEBUG("Modifying a Contact with ID" << aID); QContactManager::Error modificationStatus = QContactManager::UnspecifiedError; if (iMgr == NULL) { LOG_WARNING("Contacts backend not available"); } else { QContact oldContactData; #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) getContact(QContactId::fromString (aID), oldContactData); #else getContact(aID.toUInt(), oldContactData); #endif QStringList contactStringList; contactStringList.append(aContact); QContact newContactData = convertVCardListToQContactList(contactStringList).first(); newContactData.setId(oldContactData.id()); oldContactData = newContactData; bool modificationOk = iMgr->saveContact(&oldContactData); modificationStatus = iMgr->error(); if(!modificationOk) { // either contact exists or something wrong with one of the detailed definitions LOG_WARNING("Contact Modification Failed"); } // no else } return modificationStatus; }
/*! Parses SIM contacts in TLV format. * * \param rawData SIM contacts in TLV format. * \return List of contacts. */ QList<QContact> CntSimStorePrivate::decodeSimContactsL(TDes8& rawData) const { PbkPrintToLog(_L("CntSymbianSimEngine::decodeSimContactsL() - IN")); QList<QContact> fetchedContacts; QContact currentContact; TBuf16<KDataClientBuf> buffer; TPtrC16 bufPtr(buffer); TUint8 tagValue(0); CPhoneBookBuffer::TPhBkTagType dataType; bool isAdditionalNumber = false; CPhoneBookBuffer* pbBuffer = new(ELeave) CPhoneBookBuffer(); CleanupStack::PushL(pbBuffer); pbBuffer->Set(&rawData); pbBuffer->StartRead(); while (pbBuffer->GetTagAndType(tagValue, dataType) == KErrNone) { switch (tagValue) { case RMobilePhoneBookStore::ETagPBAdnIndex: { //save contact's id (SIM card index) and manager's name TUint16 index; if (pbBuffer->GetValue(index) == KErrNone) { QScopedPointer<QContactId> contactId(new QContactId()); contactId->setLocalId(index); contactId->setManagerUri(m_managerUri); currentContact.setId(*contactId); } isAdditionalNumber = false; break; } case RMobilePhoneBookStore::ETagPBTonNpi: { // Note, that TON info can be incorporated into the phone number by Etel // implementation (TSY). E.g. this is the case with Nokia TSY. // Here general case is implemented. // Check number type, we are only interested if it's international or not. // We assume here that ETagPBTonNpi always comes after ETagPBNumber, not before. TUint8 tonNpi; if (pbBuffer->GetValue(tonNpi) == KErrNone) { TUint8 intFlag = (tonNpi & KEtsiTonPosition) >> 4; if (intFlag == 1) { //international number format, append "+" to the last //saved number QList<QContactDetail> phoneNumbers = currentContact.details( QContactPhoneNumber::DefinitionName); if (phoneNumbers.count() > 0) { QContactPhoneNumber lastNumber = static_cast<QContactPhoneNumber>( phoneNumbers.at(phoneNumbers.count() - 1)); QString number = lastNumber.number(); number.insert(0, "+"); lastNumber.setNumber(number); if (m_storeInfo.m_readOnlyAccess) m_engine.setReadOnlyAccessConstraint(&lastNumber); currentContact.saveDetail(&lastNumber); } } } // We have rearched to the end of the number, // invalidate additional number flag. isAdditionalNumber = false; break; } case RMobilePhoneBookStore::ETagPBText: { if (pbBuffer->GetValue(bufPtr) == KErrNone) { if (isAdditionalNumber) { // For additional number bufPtr contains number alpha string, // this is ignored currently } else { // Contact name otherwise QContactName name; QString nameString = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length()); name.setCustomLabel(nameString); if (m_storeInfo.m_readOnlyAccess) m_engine.setReadOnlyAccessConstraint(&name); currentContact.saveDetail(&name); QContactManager::Error error(QContactManager::NoError); m_engine.setContactDisplayLabel(¤tContact, m_engine.synthesizedDisplayLabel(currentContact, &error)); } } break; } case RMobilePhoneBookStore::ETagPBSecondName: { if (pbBuffer->GetValue(bufPtr) == KErrNone) { QContactNickname nickName; QString name = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length()); nickName.setNickname(name); if (m_storeInfo.m_readOnlyAccess) m_engine.setReadOnlyAccessConstraint(&nickName); currentContact.saveDetail(&nickName); } break; } case RMobilePhoneBookStore::ETagPBNumber: { if (pbBuffer->GetValue(bufPtr) == KErrNone) { QContactPhoneNumber phoneNumber; QString number = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length()); phoneNumber.setNumber(number); if (m_storeInfo.m_readOnlyAccess) m_engine.setReadOnlyAccessConstraint(&phoneNumber); currentContact.saveDetail(&phoneNumber); } break; } case RMobilePhoneBookStore::ETagPBAnrStart: { // This tag should precede every additional number entry isAdditionalNumber = true; break; } case RMobilePhoneBookStore::ETagPBEmailAddress: { if (pbBuffer->GetValue(bufPtr) == KErrNone) { QContactEmailAddress email; QString emailAddress = QString::fromUtf16(bufPtr.Ptr(), bufPtr.Length()); email.setEmailAddress(emailAddress); if (m_storeInfo.m_readOnlyAccess) m_engine.setReadOnlyAccessConstraint(&email); currentContact.saveDetail(&email); } break; } case RMobilePhoneBookStore::ETagPBNewEntry: { // This signals the end of the entry and is a special case // which will be handled below. break; } default: { // An unsupported field type - just skip this value pbBuffer->SkipValue(dataType); break; } } //switch // save contact to the array of contact to be returned if the whole entry was extracted if ((tagValue == RMobilePhoneBookStore::ETagPBNewEntry && currentContact.localId() > 0) || (pbBuffer->RemainingReadLength() == 0 && currentContact.localId() > 0)) { fetchedContacts.append(currentContact); //clear current contact currentContact.clearDetails(); QScopedPointer<QContactId> contactId(new QContactId()); contactId->setLocalId(0); contactId->setManagerUri(QString()); currentContact.setId(*contactId); } } //while
void SeasideCache::reset() { for (int i = 0; i < FilterTypesCount; ++i) { m_contacts[i].clear(); m_populated[i] = false; m_models[i] = 0; } m_cache.clear(); m_cacheIndices.clear(); for (uint i = 0; i < sizeof(contactsData) / sizeof(Contact); ++i) { QContact contact; // This is specific to the qtcontacts-sqlite backend: const QString idStr(QString::fromLatin1("qtcontacts:org.nemomobile.contacts.sqlite::sql-%1")); contact.setId(QContactId::fromString(idStr.arg(i + 1))); QContactName name; name.setFirstName(QString::fromLatin1(contactsData[i].firstName)); name.setMiddleName(QString::fromUtf8(contactsData[i].middleName)); name.setLastName(QString::fromLatin1(contactsData[i].lastName)); contact.saveDetail(&name); if (contactsData[i].avatar) { QContactAvatar avatar; avatar.setImageUrl(QUrl(QLatin1String(contactsData[i].avatar))); contact.saveDetail(&avatar); } QContactStatusFlags statusFlags; if (contactsData[i].email) { QContactEmailAddress email; email.setEmailAddress(QLatin1String(contactsData[i].email)); contact.saveDetail(&email); statusFlags.setFlag(QContactStatusFlags::HasEmailAddress, true); } if (contactsData[i].phoneNumber) { QContactPhoneNumber phoneNumber; phoneNumber.setNumber(QLatin1String(contactsData[i].phoneNumber)); contact.saveDetail(&phoneNumber); statusFlags.setFlag(QContactStatusFlags::HasPhoneNumber, true); } contact.saveDetail(&statusFlags); m_cacheIndices.insert(internalId(contact), m_cache.count()); m_cache.append(CacheItem(contact)); QString fullName = name.firstName() + QChar::fromLatin1(' ') + name.lastName(); CacheItem &cacheItem = m_cache.last(); cacheItem.nameGroup = determineNameGroup(&cacheItem); cacheItem.displayLabel = fullName; } insert(FilterAll, 0, getContactsForFilterType(FilterAll)); insert(FilterFavorites, 0, getContactsForFilterType(FilterFavorites)); insert(FilterOnline, 0, getContactsForFilterType(FilterOnline)); }
void TestSymbianEngine::saveContact() { QContactManager::Error err; QList<QContactSortOrder> sortOrders; QContactId empty; QContactFilter defaultFilter = QContactFilter(); int init_count = m_engine->contactIds(defaultFilter, sortOrders, &err).count(); QVERIFY(err == QContactManager::NoError); // Save a "NULL" contact QVERIFY(!m_engine->saveContact(NULL, &err)); QVERIFY(err == QContactManager::BadArgumentError); int current_count = m_engine->contactIds(defaultFilter, sortOrders, &err).count(); QVERIFY(err == QContactManager::NoError); QVERIFY(init_count == current_count); // Save a contact that is not in database QContact invaId; QVERIFY(m_engine->saveContact(&invaId, &err)); // Add to db QVERIFY(err == QContactManager::NoError); QContactId cId = invaId.id(); m_engine->removeContact(invaId.localId(), &err); // Ensure not in db QVERIFY(err == QContactManager::NoError); invaId.setId(cId); QVERIFY(!m_engine->saveContact(&invaId, &err)); // Update non existent contact QVERIFY(err == QContactManager::DoesNotExistError); current_count = m_engine->contactIds(defaultFilter, sortOrders, &err).count(); QVERIFY(err == QContactManager::NoError); QVERIFY(init_count == current_count); QContact alice; alice.setType("Jargon"); // Save a "non contact(Jargon) type" contact QVERIFY(!m_engine->saveContact(&alice, &err)); QVERIFY(err == QContactManager::InvalidDetailError); QVERIFY(alice.id() == empty); QVERIFY(alice.localId() == 0); current_count = m_engine->contactIds(defaultFilter, sortOrders, &err).count(); QVERIFY(err == QContactManager::NoError); QVERIFY(init_count == current_count); // Save a valid contact alice.setType(QContactType::TypeContact); QVERIFY(m_engine->saveContact(&alice, &err)); QVERIFY(err == QContactManager::NoError); QVERIFY(alice.id() != empty); QVERIFY(alice.localId() != 0); QString uri = QString(QLatin1String(CNT_SYMBIAN_MANAGER_NAME)); QVERIFY(alice.id().managerUri().contains(uri, Qt::CaseInsensitive)); current_count = m_engine->contactIds(defaultFilter, sortOrders, &err).count(); QVERIFY(err == QContactManager::NoError); QVERIFY(init_count + 1 == current_count); // Save a valid contact QContact g; g.setType(QContactType::TypeGroup); QContactName en; en.setCustomLabel("ccc"); QVERIFY(g.saveDetail(&en)); QVERIFY(m_engine->saveContact(&g, &err)); QVERIFY(err == QContactManager::NoError); QVERIFY(g.id() != empty); QVERIFY(g.localId() != 0); QVERIFY(g.id().managerUri().contains(uri, Qt::CaseInsensitive)); }