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