void CntSimContactFetchRequest::run()
{
    QContactFetchRequest *r = req<QContactFetchRequest>();
    
    if (!r->isActive())
        return;
    
    // Get filter
    QContactLocalIdFilter lidFilter;
    if (r->filter().type() == QContactFilter::LocalIdFilter) {
        lidFilter = static_cast<QContactLocalIdFilter>(r->filter());
    }        

    // Fetch all contacts and filter the results.
    // Contacts are fetched starting from index 1, all slots are read
    // since slots may be not filled in a sequence.
    int index = 1;
    int numSlots = simStore()->storeInfo().m_totalEntries;
    
    if (lidFilter.ids().count() == 1) {
        // Optimization for performance. Fetch a single contact from store.
        // This is mainly for CntSymbianSimEngine::contact().
        index = lidFilter.ids().at(0);
        numSlots = 1;
    } 

    QContactManager::Error error = QContactManager::NoError;    
    if (!simStore()->read(index, numSlots, &error)) {
        QContactManagerEngine::updateContactFetchRequest(r, QList<QContact>(), error, QContactAbstractRequest::FinishedState);
    }
}
/*!
 * Reads a contact from the Etel store.
 *
 * \param contactId The Id of the contact to be retrieved.
 * \param definitionRestrictions Definition restrictions.
 * \param error Qt error code.
 * \return A QContact for the requested QContactLocalId value or 0 if the read
 *  operation was unsuccessful (e.g. contact not found).
 */
QContact CntSymbianSimEngine::contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint, QContactManager::Error* error) const
{
    QContactFetchRequest req;
    QContactLocalIdFilter filter;
    filter.setIds(QList<QContactLocalId>() << contactId);
    req.setFilter(filter);
    req.setFetchHint(fetchHint);
    executeRequest(&req, error);
    if (req.contacts().count() == 0)
        return QContact();
    return req.contacts().at(0); 
}
/* A FetchByIdRequestController is a RequestController for QContactFetchByIdRequests */
bool FetchByIdRequestController::start()
{
    // Our strategy is to translate it to a ContactFetchRequest.  Later when it finishes, we can
    // fiddle with the results to get it in the right format.
    Q_ASSERT(m_request);
    QContactFetchRequest* qcfr = new QContactFetchRequest;
    QContactLocalIdFilter lif;
    lif.setIds(static_cast<QContactFetchByIdRequest*>(m_request.data())->localIds());
    qcfr->setFilter(lif);
    qcfr->setFetchHint(qcfr->fetchHint());
    // normally, you'd set the manager, but in this case, we only have a bare engine:
    QContactManagerEngineV2Wrapper::setEngineOfRequest(qcfr, m_engine);
    m_currentSubRequest.reset(qcfr);
    connect(qcfr, SIGNAL(stateChanged(QContactAbstractRequest::State)),
            this, SLOT(handleUpdatedSubRequest(QContactAbstractRequest::State)),
            Qt::QueuedConnection);
    return qcfr->start();
}
bool SeasideCache::event(QEvent *event)
{
    if (event->type() != QEvent::UpdateRequest) {
        return QObject::event(event);
    } else if (!m_contactsToRemove.isEmpty()) {
        m_removeRequest.setContactIds(m_contactsToRemove);
        m_removeRequest.start();

        m_contactsToRemove.clear();
    } else if (!m_contactsToCreate.isEmpty() || !m_contactsToSave.isEmpty()) {
        m_contactsToCreate.reserve(m_contactsToCreate.count() + m_contactsToSave.count());

        typedef QHash<QContactLocalId, QContact>::iterator iterator;
        for (iterator it = m_contactsToSave.begin(); it != m_contactsToSave.end(); ++it) {
            m_contactsToCreate.append(*it);
        }

        m_saveRequest.setContacts(m_contactsToCreate);
        m_saveRequest.start();

        m_contactsToCreate.clear();
        m_contactsToSave.clear();
    } else if (!m_changedContacts.isEmpty()) {
        m_resultsRead = 0;

        QContactLocalIdFilter filter;
        filter.setIds(m_changedContacts);

        m_changedContacts.clear();

        m_fetchRequest.setFilter(filter);
        m_fetchRequest.start();
    } else if (m_refreshRequired) {
        m_resultsRead = 0;
        m_refreshRequired = false;
        m_fetchFilter = SeasideFilteredModel::FilterFavorites;

#ifdef SEASIDE_SPARQL_QUERIES
        m_contactIdRequest.setFavoritesOnly(true);
#else
        m_contactIdRequest.setFilter(QContactFavorite::match());
#endif
        m_contactIdRequest.start();
    } else {
        m_updatesPending = false;

        const QHash<QContactLocalId,int> expiredContacts = m_expiredContacts;
        m_expiredContacts.clear();

        typedef QHash<QContactLocalId,int>::const_iterator iterator;
        for (iterator it = expiredContacts.begin(); it != expiredContacts.end(); ++it) {
            if (*it >= 0)
                continue;
            QHash<QContactLocalId, SeasideCacheItem>::iterator cacheItem = m_people.find(it.key());
            if (cacheItem != m_people.end()) {
                delete cacheItem->person;
                m_people.erase(cacheItem);
            }
        }
    }
    return true;
}
void AsyncRequestExample::performRequests()
{
//! [Creating a new contact in a manager]
    QContact exampleContact;

    QContactName nameDetail;
    nameDetail.setFirstName("Adam");
    nameDetail.setLastName("Unlikely");

    QContactPhoneNumber phoneNumberDetail;
    phoneNumberDetail.setNumber("+123 4567");

    exampleContact.saveDetail(&nameDetail);
    exampleContact.saveDetail(&phoneNumberDetail);

    // save the newly created contact in the manager
    connect(&m_contactSaveRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(contactSaveRequestStateChanged(QContactAbstractRequest::State)));
    m_contactSaveRequest.setManager(m_manager);
    m_contactSaveRequest.setContacts(QList<QContact>() << exampleContact);
    m_contactSaveRequest.start();
//! [Creating a new contact in a manager]

    m_contactSaveRequest.waitForFinished();

//! [Creating a new contact in a manager waiting until finished]
    m_contactSaveRequest.setManager(m_manager);
    m_contactSaveRequest.setContacts(QList<QContact>() << exampleContact);
    m_contactSaveRequest.start();
    m_contactSaveRequest.waitForFinished();
    QList<QContact> savedContacts = m_contactSaveRequest.contacts();
//! [Creating a new contact in a manager waiting until finished]

//! [Filtering contacts from a manager]
    connect(&m_contactFetchRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(contactFetchRequestStateChanged(QContactAbstractRequest::State)));
    m_contactFetchRequest.setManager(m_manager);
    m_contactFetchRequest.setFilter(QContactPhoneNumber::match("+123 4567"));
    m_contactFetchRequest.start();
//! [Filtering contacts from a manager]

    m_contactFetchRequest.waitForFinished();

//! [Retrieving an existing contact from a manager]
    QContactLocalIdFilter idListFilter;
    idListFilter.setIds(QList<QContactLocalId>() << exampleContact.localId());
    m_contactFetchRequest.setManager(m_manager);
    m_contactFetchRequest.setFilter(idListFilter);
    m_contactFetchRequest.start();
//! [Retrieving an existing contact from a manager]

    m_contactFetchRequest.waitForFinished();

//! [Updating an existing contact in a manager]
    phoneNumberDetail.setNumber("+123 9876");
    exampleContact.saveDetail(&phoneNumberDetail);
    m_contactSaveRequest.setManager(m_manager);
    m_contactSaveRequest.setContacts(QList<QContact>() << exampleContact);
    m_contactSaveRequest.start();
//! [Updating an existing contact in a manager]

    m_contactFetchRequest.waitForFinished();

//! [Removing a contact from a manager]
    connect(&m_contactRemoveRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(contactRemoveRequestStateChanged(QContactAbstractRequest::State)));
    m_contactRemoveRequest.setManager(m_manager);
    m_contactRemoveRequest.setContactIds(QList<QContactLocalId>() << exampleContact.localId());
    m_contactRemoveRequest.start();
//! [Removing a contact from a manager]

    m_contactFetchRequest.waitForFinished();

//! [Creating a new relationship between two contacts]
    // first, create the group and the group member
    QContact exampleGroup;
    exampleGroup.setType(QContactType::TypeGroup);
    QContactNickname groupName;
    groupName.setNickname("Example Group");
    exampleGroup.saveDetail(&groupName);
    
    QContact exampleGroupMember;
    QContactName groupMemberName;
    groupMemberName.setFirstName("Member");
    exampleGroupMember.saveDetail(&groupMemberName);

    // second, save those contacts in the manager
    QList<QContact> saveList;
    saveList << exampleGroup << exampleGroupMember;
    m_contactSaveRequest.setContacts(saveList);
    m_contactSaveRequest.start();
    m_contactSaveRequest.waitForFinished();

    // third, create the relationship between those contacts
    QContactRelationship groupRelationship;
    groupRelationship.setFirst(exampleGroup.id());
    groupRelationship.setRelationshipType(QContactRelationship::HasMember);
    groupRelationship.setSecond(exampleGroupMember.id());

    // finally, save the relationship in the manager
    connect(&m_relationshipSaveRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(relationshipSaveRequestStateChanged(QContactAbstractRequest::State)));
    m_relationshipSaveRequest.setManager(m_manager);
    m_relationshipSaveRequest.setRelationships(QList<QContactRelationship>() << groupRelationship);
    m_relationshipSaveRequest.start();
//! [Creating a new relationship between two contacts]

    m_contactFetchRequest.waitForFinished();

//! [Retrieving relationships between contacts]
    connect(&m_relationshipFetchRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(relationshipFetchRequestStateChanged(QContactAbstractRequest::State)));
    m_relationshipFetchRequest.setManager(m_manager);
    // retrieve the list of relationships between the example group contact and the example member contact
    // where the group contact is the first contact in the relationship, and the member contact is the
    // second contact in the relationship.  In order to fetch all relationships between them, another
    // relationship fetch must be performed with their roles reversed, and the results added together.
    m_relationshipFetchRequest.setFirst(exampleGroup.id());
    m_relationshipFetchRequest.setSecond(exampleGroupMember.id());
    m_relationshipFetchRequest.start();
//! [Retrieving relationships between contacts]

    m_contactFetchRequest.waitForFinished();

//! [Providing a fetch hint]
    QContactFetchHint hasMemberRelationshipsOnly;
    hasMemberRelationshipsOnly.setRelationshipTypesHint(QStringList(QContactRelationship::HasMember));

    m_contactFetchRequest.setManager(m_manager);
    m_contactFetchRequest.setFilter(QContactFilter()); // all contacts
    m_contactFetchRequest.setFetchHint(hasMemberRelationshipsOnly);
    m_contactFetchRequest.start();
//! [Providing a fetch hint]

//! [Removing a relationship]
    connect(&m_relationshipRemoveRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(relationshipRemoveRequestStateChanged(QContactAbstractRequest::State)));
    m_relationshipRemoveRequest.setManager(m_manager);
    m_relationshipRemoveRequest.setRelationships(QList<QContactRelationship>() << groupRelationship);
    m_relationshipRemoveRequest.start();
//! [Removing a relationship]

    connect(&m_definitionFetchRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(definitionFetchRequestStateChanged(QContactAbstractRequest::State)));
//! [Querying the schema supported by a manager]
    m_definitionFetchRequest.setManager(m_manager);
    m_definitionFetchRequest.setDefinitionNames(QStringList(QContactName::DefinitionName));
    m_definitionFetchRequest.start();
    m_definitionFetchRequest.waitForFinished();
    QMap<QString, QContactDetailDefinition> definitions = m_definitionFetchRequest.definitions();
    qDebug() << "This manager"
             << (definitions.value(QContactName::DefinitionName).fields().contains(QContactName::FieldCustomLabel) ? "supports" : "does not support")
             << "the custom label field of QContactName";
//! [Querying the schema supported by a manager]

    connect(&m_definitionSaveRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(definitionSaveRequestStateChanged(QContactAbstractRequest::State)));
    connect(&m_definitionRemoveRequest, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(definitionRemoveRequestStateChanged(QContactAbstractRequest::State)));
//! [Modifying the schema supported by a manager]
    // modify the name definition, adding a patronym field
    QContactDetailDefinition nameDefinition = definitions.value(QContactName::DefinitionName);
    QContactDetailFieldDefinition fieldPatronym;
    fieldPatronym.setDataType(QVariant::String);
    nameDefinition.insertField("Patronym", fieldPatronym);

    // save the updated definition in the manager if supported...
    if (m_manager->hasFeature(QContactManager::MutableDefinitions)) {
        m_definitionSaveRequest.setManager(m_manager);
        m_definitionSaveRequest.setContactType(QContactType::TypeContact);
        m_definitionSaveRequest.setDefinitions(QList<QContactDetailDefinition>() << nameDefinition);
        m_definitionSaveRequest.start();
    }
//! [Modifying the schema supported by a manager]

    QCoreApplication::exit(0);
}