Resource Management
===================
Purpose of the rewrite:
-----------------------
* The current implementation is very buggy
* The current implementation does not scale
* The current implementation loads all resources on start-up
* this is slow.
* this takes a lot of memory: default pack is 120 mb of memory
* even if the brushes get dropped after loading, the least amount of memory management is better because it takes less time.
* some people have 20K amount of resources. These people don't want to have all of those loaded all the time. We wish to offer people grouping.
Grouping and Tagging
--------------------
Resources should be groupable. Users need to be able to select which resources are visible in the user interface, group resources related to tasks together. Groups can be heterogenous. We have the following options to group resources:
* Bundles
* Library (Adobe brush library)
* Tags:
* The most flexible.
* Usability is a bit buggier (adding/removing) Four types of tags:
* Krita tags
* Bundle tags. We have both bundles and tags, for each bundle an automatic tag is generated. Sometimes when the bundle is removed. Automatic Bundle Tag is troublesome because they have an ugly name.
* We probably should stop automatic generating of tags for bundles. Bundles can be enabled and disabled in the resource manager.
* We should allow search by bundle name in the resource browser search bar
* We should recommend that bundle authors provide useful tags inside the bundle
* Tags inside the bundle.
* User tags
* Resources can refer to each other. (tips, patterns)
We will consider bundles and adobe resource libraries as resource storage and not as user-visible grouping mechanisms. All grouping in Krita will be done with tags. Bundles and adobe resource libraries are read-only. (We will provide a way to generate and regenerate bundles.
Tags are considered to be a separate resource.
### Translating tags
The tags Krita provides by default should be translatable. Tags contained in a bundle should also be translatable. We will provide a default set of useful tags that can be translated by the i18n community. Bundle authors can use these tags, or provide tags with translations. The bundle will provide a domain for translations: if a bundle contains a translated tag that is a duplicate of a tag provided by Krita or by another bundle, krita will use the translation only for the resources in the bundle.
Resource locations
------------------
Right now we have 2 places of resources that get loaded.
* resources contained in the Krita installation: these are read-only
* User resources.
There is a third place, namely .kra files, which can contain gamut masks and palettes. Maybe .kra files should be treated as temporary bundle storages.
These two folders are tricky to keep in sync and this gives a lot of trouble. We will package the default resources in the application binary through Qt's resource system (http://doc.qt.io/qt-5/resources.html). The bundled resources will be treated as a "template". On first run, the resources will be placed in the user's resource location. The user will be able to select one location where Krita will store resources.
* There will be a button for restoring resource(s) to factory?
* How to handle modified resource overriding.
* Only copying files over when the brushes are new.
* UUID?
* Store database in bundle?
* How to handle duplicated files with different UUID?
* Scan function?
* GUI duplicates?
* Force duplicate brushes to be named differently?
* update:
* user didn't change anything
* user changed stuff
* User deleted stuff
* Krita changed
* Krita Deleted
* Krita added stuff.
The user's local resource storage system will contain a database with metadata about installed resources (name, icon, history, location of the resource). The database should be sufficient to populate the resource selection models. Only when a resource is accessed should it be loaded.
It must be possible to locate the resource storage in a synchronized folder, like Dropbox, onedrive, icloud, google drive or nextcloud. The system should not have absolute paths to resources.
Note: should it be a goal to support network drives? If so, the database should not be in the storage location, because that would give us all the headaches of a single-user database masking as a multi-user database.
Synchronizing the database and the folder: this should be light-weight. We will check for:
* filename: if we cannot find a file, or a new file appears, the database must be updated
* creation/modification date. If the date differs, we need to run a checksum to determine whether there's been a real change.
This takes care of the situation where resources are changed with outside applications.
It should be possible to migrate a resource storage to a new system. Either through zipping up everything or an export/import mechanism.
What happens with resources on updating Krita
---------------------------------------------
||User made no change|User changed|User Removed|
|Krita made no change|–|–|No change|
|Krita changed|Copy to user|Keep user, no history|Keep remembered|
|Krita remove simple|Remove|Keep|–|
|Krita force remove|Remove even when used a lot|Keep|–|
|Krita add|Add resource|– |–|
Simple Remove: Brush has been removed from the default set in a newer version of Krita.
Forced Remove: Brush has been determined to be buggy, and we want to be sure it or any derived brush gets removed.
We will implement a mechanism that checks how often and how recent a resource has been used: if Krita removes a brush from the default install but the user has used this resource often and recently, it will be kept and become a user-defined resource.
This means that a Krita update needs to have a list of resources removed since we implemented the new resource handling.
We might want to allow the user to review changed resources on udpating Krita. This should not be shown by default on updating, but as a flag in the resource history view. See next section.
What happens if the user adds an old compatibility bundle that contains resources that have the same "identity" as a new resource? The latest added resource will be the current version. Add a bundle with 2.9 resources that have the same uuid as current resources, and the current resources will be replaced, the old ones will become history states.
History of resources
--------------------
We will implement a history management dialog that will show the history of resources: creating/installation, modification, removal, restore.
* Make it possible to allow users to step backwards: recover earlier states of a resource
* This needs restore to system or just clearing the history.
* Add a collapse history state function which will delete everything but original and last state.
* Handling states: a history slider
* Locking states: users can flag a state for keeping, even if history will be cleared or collapsed
* Which doesn't get removed.
* Add favourite/bookmarked states
* History can be collapsed automatically if there are more than X states: locked, favorite or bookmarked states do not count towards X.
* Make default: a certain state that will be used as a default state to restore to.
* Restart from a history?
* Hide the resource and history cache from the user.
The history view should also have a resource inspector to view:
* Metadata inside kpp files
* GIMP and others delete the metadata, so that is awkward.
* Users should be able to see the md5sum for resources. In fact, all the boring information should be visible to the user in some kind of distant window.
The resource inspector should also be available from the bundle editor.
Resources that contain resources
--------------------------------
We will not consider bundles or libraries to be resources in their own right but as a storage mechanism.
Examples:
1. Adobe brush libraries:
* Treat the abr library as a bundle? Yes.
2. Bundles
3. Folders as a sort of bundle
Vector libraries are one resource per library, swatches are one resource per swatch file.
What is a resource, and what is not a resource
----------------------------------------------
* ASL (Adobe Style Library)
* Is a resource without resourceserver.
* Templates: though they should be
* Workspaces and Sessions are technically resources.
* Text/Paragraph/Shape styles: are not implemented yet. There is already a design for this.
Translating Resources
---------------------
* We currently translate brush presets and brush tips and other Gimp-based resources. We will stop doing this, because it makes it very difficult to support tutorials. However, we will show the translations as tooltips.
* Translating templates (https://phabricator.kde.org/T8759).
* Use keywords/vocabulary which can be translated.
* And then when we create an image from the template it translates the keywords into proper language.
* We can also do this when creating a new image
Resources that have no extensions
---------------------------------------
Not all resources have no sensible extension
Dmitry: Solve by database.
Dynamic Resources
----------------------
These get created by Krita
* They cannot be edited
* They cannot be deleted.
* Only gimp gradients can have foreground/background as part of the gradient definition.
* Clipboard brush?
* Clipboard pattern -- custom brush.
No resource state
----------------------
If there's no resources at all, what should Krita do?
* Create a new default brush?
* If this situation happens, krita informs user that resource folder could not be accessed.
* Crash?
* No resources.
Answer: Just stick all resources into a qrc and let noone near them? Dmitry suggest using the paintopfactory. Decision made affects unit test.
Editing Bundles
---------------
If the user edits a resource that originates from a bundle we will not automatically save the new version in the bundle. This is hellish when user changes a bundle, and then shares it again, it may seem that the original bundle with copyright attached is kinda awful.
We _will_ make it possible for bundle authors to regenerate bundles from edited resources.
* Make changes to brushes that are in bundles, having some kind of updating of the brushes inside the bundle with the changes brushes outside.
* Using history to check if brushes have been changed.
* Also works for removing and adding.
The current bundle creator/editor is sufficient gui-wise, though bugs need to be fixed.
* Create a wizard that creates a bundle from a set of tags.
* Awkward if there’s patterns + gradients.
* Bundle creation is pretty easy due to automatic pattern and brush-tip resolution.
If the bundle format changes, it will be by extending the current format. No automatic conversion of older bundles is foreseen.
* People really really want to get rid of their bundles: just disabling is not enough.
Get Hot New Stuff/share.krita.org
---------------------------------
* Clemens is still putting money in it, two fte are working on the server side
* The protocol is pretty hard though. The work done in 2017 was not useful.
* We still have no moderation: the design has not been adapted, so all share sites are one big database.
RSS feeds for bundles as an alternative? → Just researching what is possible in terms of registery. We could have an upload queue that we could moderate, and then publish as an rss feed and page on the website. The rss feed could be shown in the welcome page or the resoruce manager.