============================================================= How does resource tagging in Gimp work? ============================================================= GimpTagged Tagging is not limited to a concrete class hierarchy, but any class implementing the GimpTagged interface can be tagged. In addition to methods for adding/removing/enumerating tags it also requires GimpTagged objects to identify themselves: * gimp_tagged_get_identifier: used to get a unique identifier of a GimpTagged object. For objects which are stored in a file it will usually be a filename. * gimp_tagged_get_checksum: the identifier mentioned above has the problem that it can change during sessions (for example, user moves or renames a resource file). Therefore, there needs to be a way to get another identifier from the data of the tagged object, so that tags stored between session can be remapped properly. GimpTag Tags are represented by a GimpTag object. There are no limitations for tag names except that they cannot contain a selected set of terminal punctuation characters (used to separate tags), leading or trailing whitespace and cannot begin with a reserved prefix for internal tags ('gimp:'). These conditions are enforced when creating a tag object from a tag string. The only reason for tag creation to fail is if there are no characters left after trying to fix a tag according to the rules above. Tag names are displayed as the user typed them (case sensitive), but tag comparison is done case-insensitively. Tags are immutable, i.e. when a tag is created with one name string, it cannot be changed, but a new tag has to be created instead. There are methods provided for convenient use with glib, a comparison function which can be used to sort tag lists and functions for storing tags in a GHashTable. GimpTagCache Between sessions, tags assigned to objects are stored in a cache file. The cache file is a simple XML file, which lists all resources and tags which are added to them. Resources which have no tags assigned are listed here too, so that when we check the cache we know that they have no tags assigned instead of trying to find out if the resource file has been renamed. When the session ends, a list of all resources and their tags is constructed. Resources which were not loaded during this session, but had tags assigned are also added to the list (they are saved because they could be useful in the next session, for example, when a temporarily disconnected network directory is reconnected). The list is then written to a tag cache file in the user's home directory. When the session starts, the previously saved resource and tag mapping has to be loaded and assigned to GimpTagged objects. First the tag cache is loaded from file, and then containers are added (GimpContainer objects which contain items implementing the GimpTagged interface). After that, loaded resources are assigned tags: If a resource identifier matches an identifier in the cache, corresponding tags are assigned to the GimpTagged object. Else, if the identifier is not found in the tag cache, an attempt is made to check if the resource file has been moved/renamed. In such case the checksum is used to match the GimpTagged object with all of the records in the tag cache. If a match is found, the identifier is updated in the tag cache. Otherwise, the loaded GimpTagged object is considered to be a newly added resource. GimpFilteredContainer A GimpFilteredContainer is a "view" (representation) of a GimpContainer. It is related to tagging in that it can be used to filter a GimpContainer to contain only GimpTagged objects which have certain tags assigned. It is automatically updated with any changes in the GimpContainer it wraps. However, items should not be added or removed from this container manually as changes do not affect the original container and would be lost when the GimpFilteredContainer is updated. Instead, the contents should be changed by setting a tag list which would be used to filter GimpTagged objects containing all of the given GimpTags. GimpFilteredContainer can use any GimpContainer as a source container. Therefore, it is possible to use the decorator design pattern to implement additional container views, such as a view combining items from multiple containers. GimpTagEntry widget The GimpTagEntry widget extends GtkEntry and is used to either assign or query tags depending on the selected mode. The widget support various usability features: * Jellybeans: When a tag is entered and confirmed by either separator, pressing return or otherwise, it becomes a jellybean, i.e. a single unit, not a bunch of characters. Navigating in a GimpTagEntry, deleting tags, etc. can be performed much faster. However, while a tag is just being entered (not yet confirmed), all actions operate on characters as usual. * Custom auto completion is implemented in the GimpTagEntry widget which allows to complete tags in the middle of a tag list, doesn't offer already completed tags, tab cycles all possible completions, etc. * If the GimpTagEntry is empty and unused it displays a description for the user regarding its purpose. When operating in tag assignment mode, tags are assigned only when the user hits the return key. When operating in tag query mode, the given GimpFilteredContainer is filtered as the user types. The GimpTagEntry also remembers recently used configurations, which can be cycled using up and down arrow keys. GimpComboTagEntry widget The GimpComboTagEntry widget extends GimpTagEntry and adds the ability to pick tags from a menu-like list (using the GimpTagPopup widget). GimpTagPopup widget The GimpTagPopup widget is used as a tag list menu from the GimpComboTagEntry widget. It is not designed to be used with any other widget. GimpTagPopup has many visual and behavioral similarities to GtkMenu. In particular, it uses menu-like scrolling. GimpTagPopup implements various usability features, some of which are: * Tags which would result in an empty selection of resources are made insensitive. * Closing either with the keyboard or by clicking outside the popup area. * Underlining of highlighted (hovered) tags.