Warning, /frameworks/purpose/README.md is written in an unsupported language. File is not indexed.

0001 # Purpose
0002 
0003 Offers available actions for a specific purpose
0004 
0005 ## Introduction
0006 
0007 This framework offers the possibility to create integrate services and actions
0008 on any application without having to implement them specifically. Purpose will
0009 offer them mechanisms to list the different alternatives to execute given the
0010 requested action type and will facilitate components so that all the plugins
0011 can receive all the information they need.
0012 
0013 ## Usage
0014 
0015 There's 2 main ways of using Purpose: from C++ and QML/QtQuick.
0016 
0017 To import it from QML, import
0018 
0019     import org.kde.purpose 1.0
0020 
0021 It offers different ways of integrating the actions in an application. For full
0022 control on the procedure, we can use:
0023 * *AlternativesModel* for listing the different possibilities
0024 * *JobView* for displaying a job's status, including configuration
0025 
0026 Furthermore, there's the *AlternativesView* component that will integrate all the
0027 process defined below for convenience.
0028 
0029 If you want to import in the C++ application, you can import it using CMake by
0030 calling:
0031 
0032     find_package(KF6Purpose)
0033 
0034 Or its QMake counterpart. Then you'll have available the Purpose library if it
0035 needs to be done specifically and PurposeWidgets for convenience.
0036 
0037 To integrate on the UI, QtQuick will still be used, as the configuration files
0038 provided by the plugins are written in QML. The recommended way to integrate
0039 on a QtWidgets interface is by using the *Purpose::Menu* class that will allow
0040 us to place the integration wherever pleases us. This class will offer us
0041 a pointer to the used *Purpose::AlternativesModel* so that we can specify what kind of
0042 services we're interested in.
0043 
0044 ## Plugins
0045 
0046 ### The plugin configuration
0047 
0048 There will be 2 files specifying the behavior of a plugin:
0049 * The `*PluginType.json` files.
0050 * The plugin metadata JSON file.
0051 
0052 The plugin type will be identified by the file name. It will specify:
0053 * `X-Purpose-InboundArguments` defines the arguments the application must provide.
0054 * `X-Purpose-OutboundArguments` defines the arguments the plugin must provide by
0055 the end of the execution.
0056 
0057 In the plugin metadata we will define:
0058 * `X-Purpose-PluginTypes` defines the purposes tackled by the plugin
0059 * `X-Purpose-Constraints` defines the conditions that make plugin is useful, given the
0060 inboundArguments. These are the currently supported constraints
0061     * mimeType: for example `mimeType:video/*`. Useful to specify which kind of files
0062     the plugin is interested in.
0063     * exec: for example `exec:kate`. Can be used to show the plugin only if an executable is
0064     present in the `$PATH` directories.
0065     * application: for example `application:org.kde.okular.desktop`. Checks
0066     that the specified file is present in the `$XDG_DATA_DIRS/applications`
0067     directories of the system.
0068     * dbus: for example `dbus:org.kde.kdeconnect`. Will only offer the plugin if
0069     a certain dbus service is running on the system.
0070     * `[]`: for example `['exec:bash', 'exec:zsh']`. an array of constraints
0071     can be used to restrict to either of the conditions instead of all of them.
0072 * `X-Purpose-Configuration` provides a list of extra arguments that the plugin will need.
0073 Ideally everything should be in the plugin type but sometimes we can only wish. This allows
0074 the opportunity to the application to let the user add the missing data.
0075 
0076 ### Plugin types
0077 The application says what it wants to do, Purpose finds the correct plugins. This
0078 is how we balance decoupling of implementation but keep on top of what the framework
0079 is supposed to do.
0080 
0081 An example of such files is the `ExportPluginType.json`:
0082 ```json
0083 {
0084     "KPlugin": {
0085         "Icon": "edit-paste",
0086         "Name": "Upload..."
0087     },
0088     "X-Purpose-InboundArguments": [ "urls", "mimeType" ],
0089     "X-Purpose-OutboundArguments": [ "url" ]
0090 }
0091 ```
0092 
0093 As previously discussed, here we can define the generic tasks that the different
0094 plugins will implement on top, having the inbound arguments as a given and the
0095 outbound as a requirement.
0096 
0097 Examples of such plugin types are (hypothetically, not all implemented yet):
0098 * Share: where you can get the different services to share
0099 * GetImage that would list your scanner, camera and also some web services.
0100 * AddContact that would let you add a contact on your address book or
0101 in whichever plugin is offered.
0102 
0103 ### Plugin creation
0104 
0105 There's two approaches to plugin implementation: native plugins and separate
0106 processes.
0107 
0108 #### Native
0109 To implement a Qt-based plugin, it will be required to implement a
0110 `Purpose::PluginBase` class, that acts as a factory for its `Purpose::Job`
0111 instances.
0112 
0113 These will be the jobs in charge of performing the action the plugin is meant to
0114 do.
0115 
0116 Furthermore, a `pluginname_config.qml` will be provided for extra Configuration,
0117 if required.
0118 
0119 These plugins can be optionally be executed in-process.
0120 
0121 #### Separate Process
0122 Sometimes executing some actions through Qt code can require some extra work.
0123 For those cases, it's possible to implement the plugin in a separate process.
0124 It will require some extra work when it comes to implementing the feedback
0125 process with the main process but it allows to run plugins in any imaginable
0126 technologies.
0127 
0128 The file structure for these plugins is the one of defined by [KPackage](https://api.kde.org/frameworks-api/frameworks5-apidocs/kpackage/html/index.html)
0129 which allows to package and distributethe plugins in an archive.
0130 
0131 To that end, we will need to provide:
0132 * A `manifest.json` file, that will define the plugin description, capabilities
0133 and requirements.
0134 * A `code/main*` file that will be executed when the plugin action needs happen.
0135 * A `config/config.qml` file that will be in charge of requesting the necessary
0136 information to the user.
0137 
0138 ### Disallowing plugins
0139 It is possible to globally disable certain plugins through configuration file called
0140 `purposerc` in /etc/xdg (applies to all users) or in ~/.config (applies to current
0141 user).
0142 
0143 The disabled plugins are specified as a comma-separated list in the `disabled` key
0144 in the `plugins` group.
0145 
0146 ```
0147 [plugins]
0148 # Disable KDE Connect and Imgur sharing plugins
0149 disabled=kdeconnectplugin,imgurplugin
0150 ```