diff options
Diffstat (limited to 'doc/src')
| -rw-r--r-- | doc/src/contacts.qdoc | 320 | ||||
| -rw-r--r-- | doc/src/contactsasync.qdoc | 4 | ||||
| -rw-r--r-- | doc/src/contactssync.qdoc | 63 | ||||
| -rw-r--r-- | doc/src/contactsusage.qdoc | 320 | ||||
| -rw-r--r-- | doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.cpp | 226 | ||||
| -rw-r--r-- | doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.pro | 2 | ||||
| -rw-r--r-- | doc/src/snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp | 313 | ||||
| -rw-r--r-- | doc/src/snippets/qtcontactsdocsample/requestexample.h | 38 |
8 files changed, 1079 insertions, 207 deletions
diff --git a/doc/src/contacts.qdoc b/doc/src/contacts.qdoc index 8d37b69177..17bcdca7d1 100644 --- a/doc/src/contacts.qdoc +++ b/doc/src/contacts.qdoc @@ -69,10 +69,41 @@ applications. \section1 Overview -A contact is the digital representation of a person, group or entity, -which is stored in a platform-specific manner. Information pertaining to a -single contact may be located across several different datastores, and each -datum (or detail) may or may not pertain to a particular context in which +Contact information is stored in datastores whose functionality is exposed +via a \l{QContactManager}{manager}. The Contacts API models a +\l{QContact}{contact} as a collection of distinct details. Each +\l{QContactDetail}{detail} conforms to a particular +\l{QContactDetailDefinition}{definition} (or template), which may be +extensible or otherwise modifiable by clients. Individual contacts may be +related to one other, and these \l{QContactRelationship}{relationships} are +stored separately from contacts themselves and may be manipulated directly by +clients. + +\l{QContact}{Contact}, \l{QContactDetailDefinition}{detail definition}, and +\l{QContactRelationship}{relationship} information may all be +retrieved, modified or deleted by clients using either +\l{Contacts Asynchronous API}{synchronous} or +\l{Contacts Asynchronous API}{asynchronous} API. + +\section1 Client-Facing API + +The client-facing API allows retrieval, modification and deletion of contacts, +detail definitions and relationships, and access to manager meta data and +capability reporting. + +\section2 Container Classes + +Contact information is stored in container (value) classes. These classes +are not derived from QObject, and hence can be used in lists, do not have +parents, do not emit signals, and so on. They represent data which may be +manipulated and retrieved from a \l{Manager}{manager}. + +\section3 Contact + +A \l{QContact}{contact} is the digital representation of a person, group or +entity, which is stored in a platform-specific manner. Information pertaining +to a single contact may be located across several different datastores, and +each datum (or detail) may or may not pertain to a particular context in which that information is valid. A contact may include semantically identical pieces of information that are relevant in different contexts. For example, a contact may have a phone number that is relevant to their "home" @@ -83,67 +114,116 @@ information in a given context can be considered equivalent to a "contextual identity". This allows great flexibility when consolidating data from various sources into a single, cohesive contact. -Each datum (or detail) stored in a contact has defined semantics of usage -and storage. The Qt Contacts API allows per-datastore contact detail -definitions, allowing a manager to provide clients with this information on -demand, and allowing third-party developers to register detail definitions -for use by clients. A detail definition includes the fields (and value-types -of those fields) which make up the detail, per-contact uniqueness constraints on -details of the definition, and access constraints (such as read-only, -create-only, etc). Additionally, the fields of a detail definition may -also be constrained to be read-only or not. - -A detail is a single, cohesive unit of information that is stored in a -contact. As explained previously, it is valid for a particular context or -set of contexts, and conforms to a particular definition. A detail may have -specific metadata associated with it, such as its sub-type, context, and -arbitrary, user-defined metadata. - -Contacts may participate in relationships with other contacts. The details -of any such relationship is stored by the manager which contains the contact. -There are several standard relationship types supported by the default -schema, and arbitrary relationship types are also allowed. In particular, -membership of a contact in a group can be modeled as that group contact -participating in a \c HasMember relationship with the contact. - -Access to the contacts is provided by implementations of the Qt Contacts -manager API. A manager provides access to zero or more platform-specific -datastores. Each datastore may support different capabilities (for example, -the ability to store certain datatypes, the ability to natively filter on -different details or details of different definitions, the provision of -locking mechanisms, the provision of changelog information, etc) which are -reported by the manager on request. The manager therefore provides access to -detail definitions, contacts, and relationships stored in different datastores, -in a platform and datastore independent manner. The engine of a manager may -be implemented as a plugin to allow dynamic loading of different engines at -run-time. - -The functionality exposed by the QContactManager class may be implemented by -plugins which interface directly to a platform-specific backend or provide -their own data storage backend. As such, the terms "manager", "plugin" and -"backend" are used interchangeably in this documentation to refer to any plugin -which implements the functionality exposed by the QContactManager interface. - -\section1 Using the API - -This section provides some examples of common usage of the API. - -\section2 Synchronous API Usage +Each contact stored in a manager is identified by an \l{QContactId}{id} which +consists of a manager identifier (URI) and the +\l{QContactLocalId}{manager-local id} which is used to identify the contact +in that manager. Note that a contact stored in one manager may have the same +local id as a different contact stored in another manager; please see the +QContactId documentation for more information. + +\section3 Detail + +A \l{QContactDetail}{detail} is a single, cohesive unit of information that is +stored in a contact. As explained previously, it is valid for a particular +context or set of contexts, and conforms to a particular definition. A detail +may have specific metadata associated with it, such as its sub-type, context, +and arbitrary, user-defined metadata, as well as access constraints which may +apply to the the detail (such as read-only, irremovable, etc). + +There are a number of common details defined in the API which are intended +for use by clients, as listed \l{"Contact Details" Leaf Classes}{here}. + +\section3 Detail Definition + +Each detail stored in a contact has defined semantics of usage and storage. +The Qt Contacts API allows per-datastore contact +\l{QContactDetailDefinition}{detail definitions}, allowing a manager to +provide clients with this information on demand, and allowing third-party +developers to register detail definitions for use by clients. A detail +definition includes the fields (and value-types of those fields) which make up +the detail, and per-contact uniqueness constraints on details of the +definition. + +Most clients can safely ignore this class entirely, since they will most +likely want to use the predefined details listed +\l{"Contact Details" Leaf Classes}{here}. In some cases, however, a manager +will not support all of the fields of a particular predefined detail leaf +class; in that case, it may be necessary for the client to inspect the +supported detail definition for that leaf class and modify its behaviour +accordingly (for example, if the \c CustomLabel field of the QContactName +leaf detail is not supported in a particular manager). + +\section3 Relationships + +Contacts may participate in \l{QContactRelationship}{relationships} with other +contacts. The details of any such relationship is stored by the manager which +contains the contact. There are several standard relationship types supported +by the default schema, and arbitrary relationship types are also allowed if +the manager supports that feature. One important relationship is that of +group membership; membership of a contact in a group can be modeled as that +group contact participating in a \c HasMember relationship with the contact. + +\section2 Manager + +Access to contacts is provided by implementations of the Qt Contacts +\l{QContactManager}{manager} API. A manager provides access to zero or more +platform-specific datastores. Each datastore may support different +capabilities (for example, the ability to store certain datatypes, the ability +to natively filter on different details or details of different definitions, +the provision of locking mechanisms, the provision of changelog information, +etc) which are reported by the manager on request. The manager therefore +provides access to detail definitions, contacts, and relationships stored in +different datastores, in a platform and datastore independent manner. + +\section3 Meta Data API + +The API offered by the QContactManager exposes functionality which is +implemented by plugins. These plugins may be platform specific, and may be +provided by Nokia or by third party developers. As described above, each +plugin will have different capabilities and implement the functionality +exposed by the Contacts API to a different degree. + +The QContactManager class provides a static function +QContactManager::availableManagers() which allows clients of the API to +determine (at run time) which plugins (managers) are available for use. + +Clients of the API also need to be able to determine (at run time) what the +capabilities of a given plugin (contact manager) are. The QContactManager +class provides API to query the capabilities of a given manager with the +following synchronous functions: +\list + \o hasFeature(QContactManager::ManagerFeature feature, const QString& contactType = QContactType::TypeContact) const + \o isFilterSupported(const QContactFilter& filter) const + \o isRelationshipTypeSupported(const QString& relationshipType, const QString& contactType = QContactType::TypeContact) const + \o supportedDataTypes() const + \o supportedContactTypes() const +\endlist -The synchronous API provides the simplest way to access or modify the -contact information managed by a particular backend. It has the -disadvantage that calls block until completion and is therefore -most suitable only for applications which interact with local, high-speed -datastores, or for applications which do not require a responsive UI. +A given manager is identified by its URI. The URI consists of the manager's +name, any relevant parameters which were used during instantiation of the +manager, and the version of the manager. While the name of the manager +identifies the plugin which provides the functionality, you cannot guarantee +that the data available through one manager will be available through another +with the same name (for example, if one parameter tells the plugin to store +and retrieve contact information from a particular online service or local +file). + +The synchronous API offered to allow run-time querying of a manager's metadata +includes: +\list + \o managerName() const + \o managerParameters() const + \o managerUri() const + \o managerVersion() const; + \o (static) parseUri(const QString& uri, QString* managerName, QMap<QString, QString>* params) + \o (static) buildUri(const QString& managerName, const QMap<QString, QString>& params, int implementationVersion = -1) +\endlist -The synchronous API is offered through the QContactManager class, and includes -manipulation of \l{QContact}{contacts}, \l{QContactRelationship}{contact relationships}, -and \l{QContactDetailDefinition}{schema definitions} as well as capability and -metadata information reporting. +The functionality that the above functions provide is only available through +synchronous API. -For more detailed documentation on the synchronous API, see the \l{Contacts Synchronous API}. -\section2 Asynchronous API Usage +\section3 Asynchronous API The asynchronous API provides a way to access or modify the contact information managed by a particular backend via non-blocking, @@ -157,69 +237,75 @@ QContactDetailDefinitionFetchRequest, QContactDetailDefinitionSaveRequest, QContactDetailDefinitionRemoveRequest, QContactRelationshipFetchRequest, QContactRelationshipSaveRequest, and QContactRelationshipRemoveRequest. -The asynchronous API allows manipulation of \l{QContact}{contacts}, \l{QContactRelationship}{contact relationships}, -and \l{QContactDetailDefinition}{schema definitions}, but does not provide manager capability or -metadata information reporting (which is only available through the \l{Contacts Synchronous API}). +The asynchronous API allows manipulation of \l{QContact}{contacts}, +\l{QContactRelationship}{contact relationships}, and +\l{QContactDetailDefinition}{schema definitions}, but does not provide manager +capability or meta data information reporting. For more detailed documentation on the asynchronous API, see the \l{Contacts Asynchronous API}. -\section2 Contact Details - -Once a contact has been created (or retrieved from a manager), the client can retrieve, create, -update or delete details from the contact. Since QContact and QContactDetail are both container -(value) classes, the API offered for these operations is purely synchronous. - -\section3 Viewing a specific detail of a contact - -The client retrieves the phone numbers of a contact, and displays the first -one +\section3 Synchronous API - \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Viewing a specific detail of a contact - -\section3 Viewing all of the details of a contact +The synchronous API provides the simplest way to access or modify the +contact information managed by a particular backend. It has the +disadvantage that calls block the current thread of execution until completion +and is therefore most suitable only for applications which interact with +local, high-speed datastores, or for applications which do not require a +responsive UI. -The client retrieves all of the details of a contact, and displays them +The synchronous API is offered through the QContactManager class, and includes +manipulation of \l{QContact}{contacts}, +\l{QContactRelationship}{contact relationships}, and +\l{QContactDetailDefinition}{schema definitions}. As previously described, +the meta data reporting and manipulation functions are also provided via +synchronous API only. - \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Viewing the details of a contact +For more detailed documentation on the synchronous API, see the \l{Contacts Synchronous API}. -It is important to note that details are implicitly shared objects with particular -semantics surrounding saving, removal and modification. The following example -demonstrates these semantics +\section2 Actions - \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Demonstration of detail sharing semantics +Clients can perform \l{QContactAction}{actions} on contacts which support +them. Actions are things like "Send Email" or "Dial", and can be provided +from various sources including Qt Plugins or the Qt Mobility Service +Framework. Every action implementation is uniquely identified by a +combination of its name, the name of the vendor which provided the +implementation, and the version of the implementation according to the +vendor. These pieces of data may be encapsulated in a +\l{QContactActionDescriptor} which can be used to retrieve an instance of the +implementation from a \l{QContactActionFactory}. -\section1 Manager Settings And Configuration +When an instance of a \l{QContactAction} is created, the caller takes +ownership of the instance, and must delete it after use. -Users of the contacts API can define which backend they wish to access if a manager -for that backend is available. The list of available managers can be queried programmatically at -run-time, and the capabilities of different managers can be ascertained by inspecting a -QContactManager instance. Furthermore, some managers can be constructed -with parameters which affect the operation of the backend. +\section1 Non-Client-Facing API -\section2 Loading the manager for a specific backend +The non-client-facing API allows third party developers to implement a manager +engine plugin from which clients may request data. -In this example, the client loads a manager for a specific backend. While -this could be found and retrieved using a more advanced plugin framework -(such as the Qt Service Framework), this code assumes that the client has -prior knowledge of the backend in question. +\section2 Manager Engine - \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Loading a specific manager backend +The functionality exposed by the QContactManager class may be implemented by +\l{QContactManagerEngine}{engine} plugins which interface directly to a +platform-specific backend or provide their own data storage backend. As such, +the terms "manager", "plugin" and "backend" are used interchangeably in this +documentation to refer to any engine plugin which implements the functionality +exposed by the QContactManager interface. The plugin architecture allows +dynamic loading of different manager engines at runtime. -\section2 Loading a manager with specific parameters +A manager backend may be implemented by subclassing +\l{QContactManagerEngine}, and providing a \l{QContactManagerEngineFactory} +which can instantiate it when required. -The client loads a manager with specific parameters defined. The -parameters which are available are backend specific, and so the client had -to know that the "Settings" parameter was valid for the particular backend, -and what argument it took. In this example, the client tells the backend to -load detail definitions saved in a particular settings file. +\section1 Using the API - \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Loading a specific manager backend with parameters +Some examples of common usage of the API may be found +\l{Contacts API Usage}{here}. \section1 Building and compiling -This library requires Qt 4.5 to be installed. +This library requires Qt 4.6 to be installed. -To build the library, run \tt qmake and \tt make. +To build the library, see the Qt Mobility installation instructions. \section1 Reference documentation @@ -266,31 +352,15 @@ by passing a \l{QContactSortOrder} (or list of sort orders) to the manager. \section2 Actions -Clients can perform actions on contacts which support them. Actions are -things like "Send Email" or "Dial", and can be provided from various -sources including Qt Plugins or the Qt Mobility Service Framework. Every -action implementation is uniquely identified by a combination of its name, -the name of the vendor which provided the implementation, and the version -of the implementation according to the vendor. These pieces of data may be -encapsulated in a \l{QContactActionDescriptor} which can be used to -retrieve an instance of the implementation from a -\l{QContactActionFactory}. +Actions are described by descriptors and are instantiated by factories. -When an instance of a \l{QContactAction} is created, the caller takes -ownership of the instance, and must delete it after use. +\annotatedlist contacts-actions \section2 Implementing Backends -A manager backend may be implemented by subclassing -\l{QContactManagerEngine}, and providing a \l{QContactManagerEngineFactory} -which can instantiate it when required. - -\section2 Manager information and functionality reporting +A backend implementor must implement the following interfaces: -Different backends have different capabilities and offer different functionality. -In order to allow clients to query the provided functionality at runtime, every -backend must be capable of reporting their functionality and implementation version. They are -reported to clients through various functions provided by the \l{QContactManager} class. +\annotatedlist contacts-backends \section2 Synchronization and Serialization @@ -301,9 +371,11 @@ serialization of a QContact into a vCard document, and vice versa. \section2 Examples +The following sample applications show examples of API usage: \list \o \l{samplephonebook}{Sample Phonebook} \o \l{qmlcontacts}{QML-based Sample Phonebook} \endlist +See also: \l{Contacts API Usage} */ diff --git a/doc/src/contactsasync.qdoc b/doc/src/contactsasync.qdoc index 2e6fba6826..0a47b25354 100644 --- a/doc/src/contactsasync.qdoc +++ b/doc/src/contactsasync.qdoc @@ -98,8 +98,8 @@ of the following functions: \list \o contactIds(const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>()) const \o contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>()) const - \o contacts(const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QStringList& definitionRestrictions = QStringList()) const - \o contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QStringList& definitionRestrictions = QStringList()) const + \o contacts(const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QContactFetchHint& fetchHint = QContactFetchHint()) const + \o contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QContactFetchHint& fetchHint = QContactFetchHint()) const \o saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap) \o removeContacts(QList<QContactLocalId>* contactIds, QMap<int, QContactManager::Error>* errorMap) \endlist diff --git a/doc/src/contactssync.qdoc b/doc/src/contactssync.qdoc index d95c199d02..fb80655b49 100644 --- a/doc/src/contactssync.qdoc +++ b/doc/src/contactssync.qdoc @@ -68,55 +68,26 @@ applications that the asynchronous API be used where possible. The synchronous API offered by the Contacts module is available through the QContactManager class. It consists of four major sections: \list - \o Information And Reporting + \o Error Reporting \o Schema Manipulation \o Contact Manipulation \o Relationship Manipulation \endlist -\section2 Information And Reporting +\section2 Error Reporting -The API offered by the QContactManager exposes functionality which is implemented by -plugins. These plugins may be platform specific, and may be provided by Nokia or by -third party developers. Each plugin will have different capabilities and implement -the functionality exposed by the Contacts API to a different degree. - -The QContactManager class provides a static function QContactManager::availableManagers() which -allows clients of the API to determine (at run time) which plugins (managers) are available for use. - -Clients of the API also need to be able to determine (at run time) what the capabilities of a -given plugin (contact manager) are. The QContactManager class provides API to query the capabilities -of a given manager with the following functions: -\list - \o hasFeature(QContactManager::ManagerFeature feature, const QString& contactType = QContactType::TypeContact) const - \o isFilterSupported(const QContactFilter& filter) const - \o supportedRelationshipTypes(const QString& contactType = QContactType::TypeContact) const - \o supportedDataTypes() const - \o supportedContactTypes() const -\endlist - -A given manager is identified by its URI. The URI consists of the manager's name, any relevant parameters -which were used during instantiation of the manager, and the version of the manager. -While the name of the manager identifies the plugin which provides the functionality, you cannot -guarantee that the data available through one manager will be available through another with the -same name (for example, if one parameter tells the plugin to store and retrieve contact information -from a particular online service or local file). - -The synchronous API offered to allow run-time querying of a manager's metadata includes: -\list - \o managerName() const - \o managerParameters() const - \o managerUri() const - \o managerVersion() const; - \o (static) parseUri(const QString& uri, QString* managerName, QMap<QString, QString>* params) - \o (static) buildUri(const QString& managerName, const QMap<QString, QString>& params, int implementationVersion = -1) -\endlist +When a synchronous operation fails, clients need to be able to retrieve error information associated +with that synchronous operation. The QContactManager::error() function provides this information to clients. -The functionality that the above functions provide is only available through the synchronous API. +For some synchronous operations (for example, batch save or remove operations) it is possible that +multiple errors may occur during the operation. In those cases, the synchronous function will take +a pointer to a map of input index to error, which will be filled by the function as required, and +the QContactManager::error() function will report the overall operation error. -Finally, when a synchronous operation fails, clients need to be able to retrieve error information associated -with that synchronous operation. The QContactManager::error() function provides this information to clients. +Error reporting is handled slightly differently in the asynchronous API, in that each instance of +an asynchronous request is able to report any overall operation error as well as the finer-grained +map of errors, for the operation which it requested. \section2 Contact Manipulation @@ -140,27 +111,27 @@ The contact id retrieval functionality is also provided via asynchronous API thr The synchronous, singular contact manipulation functions offered by the QContactManager class are: \list - \o contact(const QContactLocalId& contactId, const QStringList& definitionRestrictions = QStringList()) const + \o contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint = QContactFetchHint()) const \o saveContact(QContact* contact) \o removeContact(const QContactLocalId& contactId) \endlist -The (optional) definitionRestrictions argument to the contact accessor function allows clients to tell the plugin -which types of details they wish to retrieve. This argument is a hint only, and may be ignored safely by the plugin, +The (optional) fetch argument to the contact accessor function allows clients to tell the plugin +which types of information they wish to retrieve. This argument is a hint only, and may be ignored safely by the plugin, or used by the plugin to optimize the performance of the retrieve operation. The save operation entails a validation step, where the contact's details are checked against the supported schema. If the contact is valid, it will be saved. Note that if the contact already exists in the database (determined by the id of the contact) it will be replaced with the contact contained in the argument. This means that clients should -not save any contact which was retrieved with a non-empty definitionRestrictions set defined, or data loss may occur. +not save any contact which was retrieved with a non-empty fetchHint defined, or data loss may occur. Any error which occurs during such singular contact manipulation functions may be accessed by calling QContactManager::error() directly after the original synchronous call. The synchronous, batch contact manipulation functions offered by the QContactManager class are: \list - \o contacts(const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QStringList& definitionRestrictions = QStringList()) const - \o contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QStringList& definitionRestrictions = QStringList()) const + \o contacts(const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QContactFetchHint& fetchHint = QContactFetchHint()) const + \o contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders = QList<QContactSortOrder>(), const QContactFetchHint& fetchHint = QContactFetchHint()) const \o saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap) \o removeContacts(QList<QContactLocalId>* contactIds, QMap<int, QContactManager::Error>* errorMap) \endlist diff --git a/doc/src/contactsusage.qdoc b/doc/src/contactsusage.qdoc new file mode 100644 index 0000000000..3c6764242d --- /dev/null +++ b/doc/src/contactsusage.qdoc @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + +\page contactsusagehtml + +\title Contacts API Usage + +\tableofcontents + +\section1 Introduction + +This section provides some examples of common usage of the Qt Contacts API. + +\section1 Manager Settings And Configuration + +Users of the contacts API can define which backend they wish to access if a +manager for that backend is available. The list of available managers can be +queried programmatically at run-time, and the capabilities of different +managers can be ascertained by inspecting a QContactManager instance. +Furthermore, some managers can be constructed with parameters which affect the +operation of the backend. + +\section2 Loading the default manager for the platform + +Most users of the API will want to use the default manager for the platform, +which provides access to the system address book. Instantiating a manager by +using the default constructor will result in the default manager for that +platform being instantiated. + +The default constructor can either be used to create a manager on the stack, +in which case it will be deleted automatically when it goes out of scope: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Loading the default manager for the platform + +or it can be used explicitly to create a manager on the heap, in which case +the client must ensure that they delete the manager when they are finished +with it in order to avoid a memory leak: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Loading the default manager for the platform on heap + +\section2 Querying a manager for capabilities + +Different managers will support different capabilities and details. Clients +can use the meta data reporting functions of QContactManager to determine what +the capabilities of the manager they have instantiated might be. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Querying a manager for capabilities + +\section2 Loading the manager for a specific backend + +In this example, the client loads a manager for a specific backend. While +this could be found and retrieved using a more advanced plugin framework +(such as the Qt Service Framework), this code assumes that the client has +prior knowledge of the backend in question. + +Clients may wish to use this feature of the API if they wish to store or +retrieve contact information to a particular manager (for example, one that +interfaces with a particular online service). + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Loading a specific manager backend + +\section2 Loading a manager with specific parameters + +The client loads a manager with specific parameters defined. The +parameters which are available are backend specific, and so the client had +to know that the "Settings" parameter was valid for the particular backend, +and what argument it took. In this example, the client tells the backend to +load detail definitions saved in a particular settings file. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Loading a specific manager backend with parameters + +\section1 Contact Detail Manipulation + +Once a contact has been created (or retrieved from a manager), the client can +retrieve, create, update or delete details from the contact. Since QContact +and QContactDetail are both container (value) classes, the API offered for +these operations is purely synchronous. + +A contact consists of the details it contains, as well as an id. Some details +are read-only (such as the display label of a contact) or irremovable (like +the type of a contact), but most are freely modifiable by clients. + +\section2 Adding a detail to a contact + +The client adds a name and a phone number to a contact. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Adding a detail to a contact + +\section2 Updating a detail in a contact + +The client updates the phone number of a contact. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Updating a detail in a contact + +\section2 Removing a detail from a contact + +The client removes the phone number of a contact. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Removing a detail from a contact + +\section2 Viewing a specific detail of a contact + +The client retrieves and displays the first phone number of a contact + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Viewing a specific detail of a contact + +\section2 Viewing all of the details of a contact + +The client retrieves all of the details of a contact, and displays them + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Viewing the details of a contact + +It is important to note that details are implicitly shared objects with +particular semantics surrounding saving, removal and modification. The +following example demonstrates these semantics + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Demonstration of detail sharing semantics + +\section1 Persistent Contact Information + +After instantiating a manager, clients will wish to retrieve or modify contact +information (including relationships and possibly detail definitions) which +is persistently stored in the manager (for example, in a database or online +cloud). + +If the client wishes to use the asynchronous API, it is suggested that their +class uses member variables for the manager and requests, similarly to: + + \snippet snippets/qtcontactsdocsample/requestexample.h Class setup + +This allows them to define slots which deal with the data as required when the +state of the request changes: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Example of an asynchronous request slot + +Note that if the client is interested in receiving the results of the request +as they become available, rather than only the final set of results once the +request changes state (to \c FinishedState, for example), the client should +instead connect the QContactAbstractRequest::resultsAvailable() signal to the +slot which deals with the results. + +\section2 Creating a new contact in a manager + +The client creates a new contact and saves it in a manager + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Creating a new contact in a manager + +Alternatively, the client can explicitly block execution until the request is +complete, by doing something like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Creating a new contact in a manager waiting until finished + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously creating a new contact in a manager + +\section2 Retrieving contacts from a manager + +The client requests all contacts from the manager which match a particular +filter. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Filtering contacts from a manager + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously filtering contacts from a manager + +The client can also retrieve a particular existing contact from a manager, by +directly requesting the contact with a particular (previously known) id. +With the asynchronous API, this takes the form of another filter: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Retrieving an existing contact from a manager + +The synchronous API provides a function specifically for this purpose: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously retrieving an existing contact from a manager + +\section2 Updating an existing contact in a manager + +The client updates a previously saved contact by saving the updated version of +the contact. Any contact whose id is the same as that of the updated contact +will be overwritten as a result of the save request. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Updating an existing contact in a manager + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously updating an existing contact in a manager + +\section2 Removing a contact from a manager + +The client removes a contact from the manager by specifying its local id. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Removing a contact from a manager + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously removing a contact from a manager + +\section2 Creating a new relationship between two contacts + +The client specifies a relationship between two contacts stored in the manager + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Creating a new relationship between two contacts + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously creating a new relationship between two contacts + +\section2 Retrieving relationships between contacts + +The client requests the relationships that a particular contact is involved in +from the manager in which the contact is stored. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Retrieving relationships between contacts + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously retrieving relationships between contacts + +When a contact is retrieved, it will contain a cache of the relationships in +which it is involved at the point in time at which it was retrieved. +This provides clients with a simple way to retrieve the relationships in which +a contact is involved, but carries the risk that the cache is stale. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Retrieving relationships from cache + +Clients can inform the manager that they do not require this cache of +relationships to be populated when retrieving a contact, which can allow a +manager to optimize contact retrieval. Other retrieval optimizations are also +possible to specify, for example that they do not require action preferences +to be returned, or that they are only interested in certain types of details. +The following code shows how the client can inform the manager that they are +only interested in relationships of the \c HasMember type (groups): + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Providing a fetch hint + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously providing a fetch hint + +\section2 Removing a relationship between two contacts + +The client can remove a relationship directly from a manager. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Removing a relationship + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously removing a relationship + +Alternatively, when a contact which is involved in a relationship is removed, +any relationships in which it is involved will be removed also. + +\section2 Querying the schema supported by a manager + +The client queries the schema supported by a manager, and checks to see if a +particular detail definition supports a certain field. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Querying the schema supported by a manager + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously querying the schema supported by a manager + +\section2 Modifying the schema supported by a manager + +The client attempts to modify a particular detail definition by extending it +so that it supports an extra field. + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp Modifying the schema supported by a manager + +The equivalent code using the synchronous API looks like: + + \snippet snippets/qtcontactsdocsample/qtcontactsdocsample.cpp Synchronously modifying the schema supported by a manager + +Note that some managers do not support mutable definitions, and hence +attempting to modify or remove detail definitions in those managers will fail. + +*/ diff --git a/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.cpp b/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.cpp index f49695175f..263f4df4c0 100644 --- a/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.cpp +++ b/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.cpp @@ -50,6 +50,10 @@ QTM_USE_NAMESPACE +static void loadDefault(); +static void queryManagerCapabilities(); +static void contactDetailManipulation(); +static void contactManipulation(); static void addContact(QContactManager*); static void callContact(QContactManager*); static void matchCall(QContactManager*, const QString&); @@ -88,9 +92,192 @@ int main(int argc, char *argv[]) app.exec(); delete cm; + // more doc snippet examples + loadDefault(); + queryManagerCapabilities(); + contactDetailManipulation(); + contactManipulation(); + + // async doc snippet examples + AsyncRequestExample example; + QTimer::singleShot(10, &example, SLOT(performRequests())); + app.exec(); + return 0; } +void loadDefault() +{ +//! [Loading the default manager for the platform] + QContactManager stackDefaultContactManager; +//! [Loading the default manager for the platform] + +//! [Loading the default manager for the platform on heap] + QContactManager *heapDefaultContactManager = new QContactManager; + // ... perform contact manipulation + delete heapDefaultContactManager; +//! [Loading the default manager for the platform on heap] +} + +void queryManagerCapabilities() +{ +//! [Querying a manager for capabilities] + QContactManager cm; + qDebug() << "The default manager for the platform is:" << cm.managerName(); + qDebug() << "It" << (cm.isRelationshipTypeSupported(QContactRelationship::HasAssistant) ? "supports" : "does not support") << "assistant relationships."; + qDebug() << "It" << (cm.supportedContactTypes().contains(QContactType::TypeGroup) ? "supports" : "does not support") << "groups."; + qDebug() << "It" << (cm.hasFeature(QContactManager::MutableDefinitions) ? "supports" : "does not support") << "mutable detail definitions."; +//! [Querying a manager for capabilities] +} + +void contactDetailManipulation() +{ +//! [Adding a detail to a contact] + QContact exampleContact; + + QContactName nameDetail; + nameDetail.setFirstName("Adam"); + nameDetail.setLastName("Unlikely"); + + QContactPhoneNumber phoneNumberDetail; + phoneNumberDetail.setNumber("+123 4567"); + + exampleContact.saveDetail(&nameDetail); + exampleContact.saveDetail(&phoneNumberDetail); +//! [Adding a detail to a contact] + +//! [Updating a detail in a contact] + phoneNumberDetail.setNumber("+123 9876"); + exampleContact.saveDetail(&phoneNumberDetail); // overwrites old value on save +//! [Updating a detail in a contact] + +//! [Removing a detail from a contact] + exampleContact.removeDetail(&phoneNumberDetail); +//! [Removing a detail from a contact] +} + +void contactManipulation() +{ + QContactManager m_manager("memory"); +//! [Synchronously 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 + if (!m_manager.saveContact(&exampleContact)) + qDebug() << "Error" << m_manager.error() << "occurred whilst saving contact!"; +//! [Synchronously creating a new contact in a manager] + +//! [Synchronously filtering contacts from a manager] + QList<QContact> results = m_manager.contacts(QContactPhoneNumber::match("+123 4567")); +//! [Synchronously filtering contacts from a manager] + +//! [Synchronously retrieving an existing contact from a manager] + QContact existing = m_manager.contact(exampleContact.localId()); +//! [Synchronously retrieving an existing contact from a manager] + +//! [Synchronously updating an existing contact in a manager] + phoneNumberDetail.setNumber("+123 9876"); + exampleContact.saveDetail(&phoneNumberDetail); + m_manager.saveContact(&exampleContact); +//! [Synchronously updating an existing contact in a manager] + +//! [Synchronously removing a contact from a manager] + m_manager.removeContact(exampleContact.localId()); +//! [Synchronously removing a contact from a manager] + +//! [Synchronously 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 + QMap<int, QContactManager::Error> errorMap; + QList<QContact> saveList; + saveList << exampleGroup << exampleGroupMember; + m_manager.saveContacts(&saveList, &errorMap); + + // 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 + m_manager.saveRelationship(&groupRelationship); +//! [Synchronously creating a new relationship between two contacts] + +//! [Synchronously retrieving relationships between contacts] + QList<QContactRelationship> groupRelationships = m_manager.relationships(QContactRelationship::HasMember, exampleGroup.id(), QContactRelationship::First); + QList<QContactRelationship> result; + for (int i = 0; i < groupRelationships.size(); i++) { + if (groupRelationships.at(i).second() == exampleGroupMember.id()) { + result.append(groupRelationships.at(i)); + } + } +//! [Synchronously retrieving relationships between contacts] + +//! [Retrieving relationships from cache] + exampleGroup = m_manager.contact(exampleGroup.localId()); // refresh the group contact + groupRelationships = exampleGroup.relationships(QContactRelationship::HasMember); + for (int i = 0; i < groupRelationships.size(); i++) { + if (groupRelationships.at(i).second() == exampleGroupMember.id()) { + result.append(groupRelationships.at(i)); + } + } +//! [Retrieving relationships from cache] + +//! [Synchronously providing a fetch hint] + QContactFetchHint hasMemberRelationshipsOnly; + hasMemberRelationshipsOnly.setRelationshipTypesHint(QStringList(QContactRelationship::HasMember)); + + // retrieve all contacts, with no specified sort order, requesting that + // HasMember relationships be included in the cache of result contacts + QList<QContact> allContacts = m_manager.contacts(QContactFilter(), QList<QContactSortOrder>(), hasMemberRelationshipsOnly); +//! [Synchronously providing a fetch hint] + +//! [Synchronously removing a relationship] + m_manager.removeRelationship(groupRelationship); +//! [Synchronously removing a relationship] + +//! [Synchronously querying the schema supported by a manager] + QMap<QString, QContactDetailDefinition> definitions = m_manager.detailDefinitions(); + qDebug() << "This manager" + << (definitions.value(QContactName::DefinitionName).fields().contains(QContactName::FieldCustomLabel) ? "supports" : "does not support") + << "the custom label field of QContactName"; +//! [Synchronously querying the schema supported by a manager] + +//! [Synchronously 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_manager.saveDetailDefinition(nameDefinition, QContactType::TypeContact); + } +//! [Synchronously modifying the schema supported by a manager] +} + //! [Creating a new contact] void addContact(QContactManager* cm) { @@ -362,45 +549,18 @@ void RequestExample::stateChanged(QContactAbstractRequest::State state) } //! [Asynchronous contact request] -//! [Loading a specific manager backend] void loadManager() { - QContactManager* cm = new QContactManager("KABC"); - QList<QContactLocalId> contactIds = cm->contactIds(); - if (!contactIds.isEmpty()) { - QContact a = cm->contact(contactIds.first()); - qDebug() << "This manager contains" << a.displayLabel(); - } else { - qDebug() << "This manager contains no contacts"; - } - - delete cm; -} //! [Loading a specific manager backend] + QContactManager contactManager("KABC"); +//! [Loading a specific manager backend] +} -//! [Loading a specific manager backend with parameters] void loadManagerWithParameters() { +//! [Loading a specific manager backend with parameters] QMap<QString, QString> parameters; parameters.insert("Settings", "~/.qcontactmanager-kabc-settings.ini"); - QContactManager* cm = new QContactManager("KABC", parameters); - QMap<QString, QContactDetailDefinition> definitions = cm->detailDefinitions(); - - qDebug() << "This backend currently supports the following detail definitions:"; - QList<QContactDetailDefinition> allDefinitions = definitions.values(); - foreach (const QContactDetailDefinition& defn, allDefinitions) { - QMap<QString, QContactDetailFieldDefinition> fields = defn.fields(); - foreach (const QString& fieldKey, fields.keys()) { - QList<QVariant> allowableValues = fields.value(fieldKey).allowableValues(); - qDebug() << "\t" << fieldKey << "(" << fields.value(fieldKey).dataType() << "):"; - if (allowableValues.isEmpty()) { - qDebug() << "\t\tAny Value Permitted"; - } else { - qDebug() << allowableValues; - } - } - } - - delete cm; -} + QContactManager contactManager("KABC", parameters); //! [Loading a specific manager backend with parameters] +} diff --git a/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.pro b/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.pro index bf99cf2b58..b74edd13fc 100644 --- a/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.pro +++ b/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.pro @@ -19,5 +19,5 @@ QMAKE_RPATHDIR+=$$OUTPUT_DIR/lib CONFIG += mobility console MOBILITY = contacts -SOURCES += qtcontactsdocsample.cpp +SOURCES += qtcontactsdocsample.cpp qtcontactsdocsampleasync.cpp HEADERS += requestexample.h diff --git a/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp b/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp new file mode 100644 index 0000000000..9cd844c88c --- /dev/null +++ b/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsampleasync.cpp @@ -0,0 +1,313 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmobilityglobal.h" +#include "qtcontacts.h" +#include "requestexample.h" + +#include <QDebug> +#include <QCoreApplication> +#include <QObject> +#include <QTimer> + +QTM_USE_NAMESPACE + +AsyncRequestExample::AsyncRequestExample() + : QObject() +{ + m_manager = new QContactManager("memory"); +} + +AsyncRequestExample::~AsyncRequestExample() +{ + delete m_manager; +} + +//! [Example of an asynchronous request slot] +void AsyncRequestExample::contactFetchRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) { + QContactFetchRequest *request = qobject_cast<QContactFetchRequest*>(QObject::sender()); + if (request->error() != QContactManager::NoError) { + qDebug() << "Error" << request->error() << "occurred during fetch request!"; + return; + } + + QList<QContact> results = request->contacts(); + for (int i = 0; i < results.size(); i++) { + qDebug() << "Retrieved contact:" << results.at(i).displayLabel(); + } + } else if (newState == QContactAbstractRequest::CanceledState) { + qDebug() << "Fetch operation canceled!"; + } +} +//! [Example of an asynchronous request slot] + +void AsyncRequestExample::contactSaveRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished saving the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Save operation canceled!"; +} + +void AsyncRequestExample::contactRemoveRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished removing the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Remove operation canceled!"; +} + +void AsyncRequestExample::relationshipFetchRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished fetching the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Fetch operation canceled!"; +} + +void AsyncRequestExample::relationshipSaveRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished saving the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Save operation canceled!"; +} + +void AsyncRequestExample::relationshipRemoveRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished removing the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Remove operation canceled!"; +} + +void AsyncRequestExample::definitionFetchRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished fetching the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Fetch operation canceled!"; +} + +void AsyncRequestExample::definitionSaveRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished saving the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Save operation canceled!"; +} + +void AsyncRequestExample::definitionRemoveRequestStateChanged(QContactAbstractRequest::State newState) +{ + if (newState == QContactAbstractRequest::FinishedState) + qDebug() << "Finished removing the contacts!"; + else if (newState == QContactAbstractRequest::CanceledState) + qDebug() << "Remove operation canceled!"; +} + +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] +} diff --git a/doc/src/snippets/qtcontactsdocsample/requestexample.h b/doc/src/snippets/qtcontactsdocsample/requestexample.h index e8fcbd5e32..b6f2b284dc 100644 --- a/doc/src/snippets/qtcontactsdocsample/requestexample.h +++ b/doc/src/snippets/qtcontactsdocsample/requestexample.h @@ -56,9 +56,45 @@ #include <QObject> #include "qmobilityglobal.h" -#include "qcontactfetchrequest.h" +#include "qcontactrequests.h" +//! [Class setup] QTM_USE_NAMESPACE +class AsyncRequestExample : public QObject +{ + Q_OBJECT + +public: + AsyncRequestExample(); + ~AsyncRequestExample(); + +public slots: + void performRequests(); + +private slots: + void contactFetchRequestStateChanged(QContactAbstractRequest::State newState); + void contactSaveRequestStateChanged(QContactAbstractRequest::State newState); + void contactRemoveRequestStateChanged(QContactAbstractRequest::State newState); + void relationshipFetchRequestStateChanged(QContactAbstractRequest::State newState); + void relationshipSaveRequestStateChanged(QContactAbstractRequest::State newState); + void relationshipRemoveRequestStateChanged(QContactAbstractRequest::State newState); + void definitionFetchRequestStateChanged(QContactAbstractRequest::State newState); + void definitionSaveRequestStateChanged(QContactAbstractRequest::State newState); + void definitionRemoveRequestStateChanged(QContactAbstractRequest::State newState); + +private: + QContactManager *m_manager; + QContactFetchRequest m_contactFetchRequest; + QContactSaveRequest m_contactSaveRequest; + QContactRemoveRequest m_contactRemoveRequest; + QContactRelationshipFetchRequest m_relationshipFetchRequest; + QContactRelationshipSaveRequest m_relationshipSaveRequest; + QContactRelationshipRemoveRequest m_relationshipRemoveRequest; + QContactDetailDefinitionFetchRequest m_definitionFetchRequest; + QContactDetailDefinitionSaveRequest m_definitionSaveRequest; + QContactDetailDefinitionRemoveRequest m_definitionRemoveRequest; +}; +//! [Class setup] class RequestExample : public QObject { |
