Abstract

It is often desirable to be able to find specific types of services or services with specific features or designations. KDE provides a simple yet powerful query language to accomplish this called the KTrader Query Language.

A Tale of Two Traders

KDE provides two classes that act as "traders". A trader takes a query and returns a set of services that match those constraints. There is one trader for plugins and other add-ons: KServiceTypeTrader, and one for mimetypes: KMimetypeTrader. Characteristics for both are similar: they have same syntax for querying, offer a singleton pattern accessor, return KService::Ptrs, as well as other similarities. So while this tutorial concentrates primarily on the KServiceTypeTrader, much of the content is applicable to the mimetype trader as well.

Service Types

KServiceTypeTrader is used to locate individual components such as application plugins, screensavers, and control panels that are registered with the system. The primary concept used here, is that of the "service type". Each set of services has a unique service type, which makes it very easy to locate the sort of component needed.

This means that, each kind of application plugin is uniquely namespaced within the set of all services. So, it is trivial to locate plugins for a given application, without having to worry about getting another application's plugin in the list.

Examples of service types include:

KParts/ReadWritePart

KTextEditor/Document

ScreenSaver

TerminalEmulator

UserAgentStrings

ThumbCreator

KDevelop/Plugin

There is no limit to the number of service types that a given application may use or register. Of course, service types are not limited to plugins and may be used for any sort of data component.

In each case zero or more services are returned that are now usable for locating, describing and loading the item it represents.

The KTrader Query Language

The above examples are quite simplistic and are not detailed enough for many application needs. For instance, we may only want to list plugins for a certain category, that are associated with a particular mimetype, or that have a specific plugin name. This is where the query language comes in.

The query language itself is designed to be human readable and flexible. KServiceTypeTrader::query optionally takes a query, in addition to the service type, and uses that to provide more fine-grained searches. So, for example, we'll modify the earlier example in the following way:

This code will look for a KPart that is both capable of reading/writing plain text files and is also a KOffice component, or can simply read ODF document formats.

Errors in queries are reported via debug output to console at runtime.

Order of Operations

The query string is evaluated left to right, one section at a time. Sections are divided by boolean operators (see below) or by parentheses ('()'), which serve as grouping characters.

Literals

Three types of literals are supported by the KTrader Query Language:

strings: character strings, which must be enclosed in single quotes (')

booleans: TRUE or FALSE

signed integers

signed floating point numbers

Identifiers

Identifiers in a query string are mapped to entries listed in the service's .desktop file. For example, "Name" is the name of the service, "ServiceTypes" is a list of the service types it supports.

Identifiers may only contain alphanumeric characters and the '-' character.
Identifiers that do not start with an alphabetical character or that contain non-alphanumeric characters must be enclosed in brackets, e.g. [X-KDE-Init].

There are also three special identifiers:

DesktopEntryName stands for the filename of the service desktop entry without its extension. This can be useful to exclude some specific services.

DesktopEntryPath stands for the relative or full path to the .desktop file, see KService::desktopEntryPath.

Library: a synonym for [X-KDE-Library] in the .desktop file.

An identifier can be checked for existence with the exist operator, e.g. "exist [X-KDE-Library]". This is especially useful when checking for the value of an identifier with a default value. For example, if MyProp is a property with type boolean, one might write "not exist MyProp or MyProp" to match MyProp with a default of "true".

Comparison Operators

The following comparison operators can be used to compare values of any of the supported data types:

==: equality

!=: inequality

<: less than

<=: less than or equal to

>: greater than

>=: greater than or equal to

Mathematical Operators

The following mathematical operators can be used with numerical types:

+

-

*

/

Boolean Operators

The following boolean operators are supported:

and

or

not

String Matching Operators

The string matching operators all return a boolean value, indicating success or failure.

String comparisons are done using the following operators:

==: equality, case sensitive

=~: equality, case insensitive

!=: inequality, case sensitive

!~: inequality, case insensitive

Sub-string matching can be accomplished by using the following operators: