Warning, /pim/akonadi/docs/tags.md is written in an unsupported language. File is not indexed.
0001 # Tags # {#tags} 0002 0003 [TOC] 0004 0005 Akonadi tags are an abstract concept designed to allow attaching the same shared 0006 data to multiple Akonadi Items, rather than just grouping of arbitrary Akonadi Items 0007 (like the more conventional meaning of "tags"). They can however be used, and most 0008 commonly are used, as simple labels. 0009 0010 [ Note: this document uses the word "label" to refer to tags in the more common sense 0011 of the word - as a named labels like "Birthday", "Work", etc. that are used by users 0012 in applications to group multiple emails, files etc. based on their shared characteristic. 0013 The word "tag" in this document always refers to the concept of Akonadi Tags. ] 0014 0015 0016 Akonadi Tags have an ID, type, GID, RemoteID and a parent. 0017 0018 * ID - an immutable unique identifier within Akonadi instance, same as Item and Collection IDs 0019 * Type - an immutable string describing the type of a Tag. Applications can define custom tag 0020 types and can fetch Tags of only a certain type. 0021 * GID - an immutable string-based identifier. GID can be used to lookup a Tag in Akonadi. If 0022 application needs to store a reference to a Tag in a configuration file or a cache it should 0023 use GID rather than ID. GID may or may not be a human-readable string. Generally for Tags 0024 exposed to UI one should use Akonadi::Tag::setName() to set a human-readable name of the Tag 0025 (Akonadi::Tag::setName() is equivalent to adding Akonadi::TagAttribute and setting its displayName). 0026 * RemoteID - an identifier used by Akonadi Resources to identify the Tag in the remote storage. 0027 * Parent - Akonadi allows for hierarchical Tags. The semantics of the hierarchy are only meaningful 0028 to the application or the user, Akonadi does not make any assumptions about the meaning of the 0029 hierarchy. 0030 * Attributes - same as Item or Collection attributes 0031 0032 # Tag type # {#tag_types} 0033 0034 Akonadi Tags have types to differentiate between different usecases of Tags. 0035 Applications can define their own types of Tags - for example an email client 0036 could create a Tag of type SENDER, tagging each email with Rags representing 0037 the email sender, allowing to quickly perform a reverse-lookup for all emails 0038 from a certain sender. 0039 0040 In Akonadi, two Tag types are present by default: PLAIN and GENERIC. 0041 0042 There's no limitation as to which attributes can be used with which type. Generally 0043 PLAIN Tags are not used much, and the GENERIC Tags are used as labels. 0044 0045 0046 # Tag GID # {#tag_gid} 0047 0048 For the needs of uniquely identifying Tags, each Tag has a GID. The GID is immutable 0049 and should be used by applications if they need to store a reference to a Tag in 0050 a configuration file or a cache. 0051 0052 GID is also used in Tag merging: when a Resource tries to create a new Tag with a 0053 GID that already exists in Akonadi, the Tags are assumed to be the same and the 0054 new Tag is merged into the existing Tag (see Tag Remote ID below for details and 0055 example as how Tags are handled from Resource point of view). 0056 0057 0058 0059 # Tag RemoteID # {#tag_rid} 0060 0061 Much like with Items and Collections remote IDs, Tag RIDs are used by Akonadi Agents 0062 and Resources to be able to map the Akonadi Tag to their representation in the 0063 backend storage (IMAP server, CalDAV server, etc.) 0064 0065 There is one major difference between RIDs for Items or Collections and for Tags. 0066 Unlike Items and Collections which all have a strictly defined owner Resource, 0067 Tags don't have an owner. This is because Tags can group entities belonging to 0068 different Resources. For this reason, each Tag has multiple remote IDs, where 0069 each Remote ID belongs to an individual Resource. The isolation of the Remote IDs 0070 is fully handled by the server and is opaque to the Resources. 0071 0072 For this reason, Tag Remote IDs are not exposed to client applications, instead 0073 client applications should use the GID, with is immutable and shared between 0074 both clients and Resources. 0075 0076 0077 As an example, let's have a Tag of GENERIC type with GID "birthday": 0078 0079 An IMAP Resource may fetch an Item with a flag "$BIRTHDAY". The resource will then 0080 create a new GENERIC Tag with GID "birthday" and remoteID "$BIRTHDAY". The 0081 Akonadi Server, instead of creating another Tag with GID "birthday" instead 0082 adds the "$BIRTHDAY" remoteID with relation to the IMAP resource to the existing 0083 "birthday" Tag. 0084 0085 A DAV Resource may fetch an Item with a label "dav:birthday". The resource will 0086 then create a new GENERIC Tag with GID "birthday" and remoteID "dav:birthday". 0087 The Akonadi Server will add the "dav:birthday" and the relation to the DAV resource 0088 to the existing "birthday" Tagg as well. 0089 0090 When user decides to add the "birthday" tag to two events - one owned by the DAV 0091 resource and one owned by the IMAP resource the Akonadi server will send a change 0092 notification to the DAV Resource with the "dav:birthday" RID and with the "$BIRTHDAY" 0093 RID to the IMAP Resource. 0094 0095 0096 # Client API # {#tag_client_api} 0097 0098 Existing Tags can be retrieved from Akonadi using Akonadi::TagFetchJob. 0099 0100 To create a new GENERIC Tag with TagAttribute with display name set, one should use 0101 Akonadi::Tag::genericTag(const QString &name) static method. The tag will have a 0102 randomly generated GID set. This is equivalent to 0103 calling 0104 0105 ~~~~~~~~~~~~~{.cpp} 0106 Tag tag; 0107 tag.setType("GENERIC"); 0108 tag.setGid(QUuid::createUuid().toByteArray()); 0109 tag.setName(name); 0110 ~~~~~~~~~~~~~ 0111 0112 0113 Such Tag can now be uploaded to Akonadi using Akonadi::TagCreateJob. If a Tag with 0114 the same Type and GID already exist in Akonadi, all other data in the existing 0115 Tag will be overwritten by data in the new tag. 0116 0117 Any changes to a Tag can be stored in Akonaddi using Akonadi::TagModifyJob. Resources 0118 can use Akonadi::TagModifyJob to set or unset a RemoteID for an existing Tag. If the 0119 Tag has no Remote IDs left after this, the Tag will automatically be removed from 0120 Akonadi. 0121 0122 A tag can be removed from Akonadi using Akonadi::TagDeleteJob. Removing a Tag 0123 will also untag it from all Items and will notify all Resources about it so 0124 that the entities are untagged in their backend storage as well. 0125 0126 To retrieve all Items with a certain Tag, Akonadi::ItemFetchJob has an overloaded 0127 constructor that takes an Akonadi::Tag as an argument. 0128 0129 Tags for each Item are available in Akonadi::Item::tags(). To tag or untag an Item 0130 modify the list of Tags in the Item and store the change in Akonadi using 0131 Akonadi::ItemModifyJob. 0132 0133 0134 ## Fetch Scope ## {#tag_fetch_scope} 0135 0136 By default Item Tags are not fetched when simply running Akonadi::ItemFetchJob. To 0137 enable fetching Tags, you have to set Akonadi::ItemFetchScope::fetchTags to true. 0138 The retrieved Tags will only have their ID set. To retrieve more you need to modify 0139 the Akonadi::TagFetchScope (from Akonadi::ItemFetchScope::fetchScope()) and unset 0140 Akonadi::TagFetchScope::fetchIdOnly(). Now ItemFetchJob will return Items with Tags 0141 with ID, GID. If the Akonadi::TagFetchScope::attributes() is empty then all attributes 0142 will be received. Otherwise you can restrict the fetch scope to only fetch certain 0143 attributes. 0144 0145 0146 ## Implementation in Resources ## {#tag_resource_impl} 0147 0148 If the storage backend supports some form of labels it should implement support for Tags 0149 so that tags from the backend are synchronized into Akonadi and vice versa. 0150 0151 To be notified about changes in Tags, Resource implementation must inherit from 0152 Akonadi::AgentBase::ObserverV4 (or later). 0153 0154 Akonadi::AgentBase::ObserverV4::tagAdded(), tagChanged() and tagRemoved() may be 0155 optionally reimplemented by Resource implementation if it wants to synchronize 0156 all local Tags with the remote storage so they can be presented to the user, even 0157 if no Items belonging to the Resource are tagged with it. 0158 0159 The most important method to reimplement by Resource implementations is 0160 Akonadi::AgentBase::ObserverV4::itemsTagsChanged(), which gives a list of changed 0161 Items belonging to the Resource, a set of Tags added to all those Items and a set 0162 of Tags removed from those Items. 0163