Development/Tutorials/Services/Introduction: Difference between revisions

    From KDE TechBase
    (Language navigation bar added)
    No edit summary
    (4 intermediate revisions by 3 users not shown)
    Line 1: Line 1:
    {{Template:I18n/Language Navigation Bar|Development/Tutorials/Services/Introduction}}
     


    {{TutorialBrowser|
    {{TutorialBrowser|
    Line 43: Line 43:
    == KService ==
    == KService ==


    The {{class|KService}} class is at the center of the services system. It serves both an informational and a functional role. {{class|KService}} provides access to details on a given service such as whether it is an application, the name of the service, the associated icon (if any), etc. But it can also used to launch applications and load plugins from disk.
    The {{class|KService}} class is at the center of the services system. It serves both an informational and a functional role. {{class|KService}} provides access to details on a given service such as whether it is an application, the name of the service, the associated icon (if any), etc. But it can also be used to launch applications and load plugins from disk.


    A {{class|KService}} object can be obtained in one of three ways:
    A {{class|KService}} object can be obtained in one of three ways:
    Line 51: Line 51:
    The first approach is the most straightforward and often looks something like this:
    The first approach is the most straightforward and often looks something like this:


    <code cppqt>
    <syntaxhighlight lang="cpp-qt">
    QString pathToDesktopFile = KStandardDirs::locate("apps",
    QString pathToDesktopFile = KStandardDirs::locate("services", "konqueror.desktop");
                                                      "konqueror");
    KService service(pathToDesktopFile);
    KService service(pathToDesktopFile);
    </code>
    </syntaxhighlight>


    KService also provides ways to load services by name directly with the <tt>serviceBy*</tt> set of methods, of which the safest and most recommended is <tt>serviceByStorageId</tt>:
    KService also provides ways to load services by name directly with the <tt>serviceBy*</tt> set of methods, of which the safest and most recommended is <tt>serviceByStorageId</tt>:


    <code cppqt>
    <syntaxhighlight lang="cpp-qt">
    KService::Ptr service = KService::serviceByStorageId("konqueror");
    KService::Ptr service = KService::serviceByStorageId("konqueror");
    </code>
    </syntaxhighlight>


    Note that it passed back a <tt>KService::Ptr</tt> rather than just a {{class|KService}}. A <tt>{{class|KService}}::Ptr</tt> looks, acts and behaves just like a regular pointer (<tt>{{class|KService}}*</tt>) but it is automatically memory managed. It is not necessary to manually delete <tt>KService::Ptr</tt>s, because they are reference counted.
    Note that it passed back a <tt>KService::Ptr</tt> rather than just a {{class|KService}}. A <tt>{{class|KService}}::Ptr</tt> looks, acts and behaves just like a regular pointer (<tt>{{class|KService}}*</tt>) but it is automatically memory managed. It is not necessary to manually delete <tt>KService::Ptr</tt>s, because they are reference counted.
    Line 69: Line 68:
    At this point we now have access to all sorts of information on the service, which in this case is an application called <tt>konqueror</tt>. We can even launch the app using this service:
    At this point we now have access to all sorts of information on the service, which in this case is an application called <tt>konqueror</tt>. We can even launch the app using this service:


    <code cppqt>
    <syntaxhighlight lang="cpp-qt">
    if (service.isApplication()) {
    if (service.isApplication()) {
         KUrl::List urls;
         KUrl::List urls;
    Line 75: Line 74:
         KRun::run(service, urls, 0);
         KRun::run(service, urls, 0);
    }
    }
    </code>
    </syntaxhighlight>


    This would launch <tt>konqueror</tt> and cause it to open the KDE homepage.
    This would launch <tt>konqueror</tt> and cause it to open the KDE homepage.
    Line 91: Line 90:
    While the <tt>.desktop</tt> (file) method is very handy for users (and adding new entries), performance could be an issue because it is common to have thousands of these files describing various mimetypes, applications, plugins, screensavers, etc. Thus, the entries are put into a binary cache which is accessed via shared memory by all applications. The cache is known as the '''Sy'''stem '''Co'''nfiguration '''Ca'''che, or SyCoCa for short. Loading and locating {{class|KService}}s is done via this cache, transparently to the application.  
    While the <tt>.desktop</tt> (file) method is very handy for users (and adding new entries), performance could be an issue because it is common to have thousands of these files describing various mimetypes, applications, plugins, screensavers, etc. Thus, the entries are put into a binary cache which is accessed via shared memory by all applications. The cache is known as the '''Sy'''stem '''Co'''nfiguration '''Ca'''che, or SyCoCa for short. Loading and locating {{class|KService}}s is done via this cache, transparently to the application.  


    Whenever a new <tt>.desktop</tt> file is added, removed or altered, the cache is automatically updated by the {{path|kbuildsycoca}} application. You can force an update of the cache by running {{path|kbuildsycoca}} manually, though usually it is launched by {{path|kded}} automatically when needed. A full rebuild of the cache (versus a simple update) can be triggered by passing <tt>--noincremental</tt> to {{path|kbuildsycoca}}.
    Whenever a new <tt>.desktop</tt> file is added, removed or altered, the cache is automatically updated by the {{path|kbuildsycoca4}} application. You can force an update of the cache by running {{path|kbuildsycoca4}} manually, though usually it is launched by {{path|kded4}} automatically when needed. A full rebuild of the cache (versus a simple update) can be triggered by passing <tt>--noincremental</tt> to {{path|kbuildsycoca4}}.


    == Searching For Services ==
    == Searching For Services ==


    The next tutorial is [[../Traders|Finding Services Using Trader Queries]]. We will look at how to find services using the KTrader query language and {{class|KServiceTypeTrader}} .
    The next tutorial is [[../Traders|Finding Services Using Trader Queries]]. We will look at how to find services using the KTrader query language and {{class|KServiceTypeTrader}} .

    Revision as of 09:14, 14 July 2012


    Introduction to the Services Framework

    Abstract

    Services represent applications, plugins and other add-ons available on the system. They make it easy to find, launch and load the items they represent without having to hardcode any specific component or even know ahead of time what services will be available. This tutorial covers what the services system provides and where the information is stored.

    Advantages of Using Services

    There are three main advantages to using services:

    • it's simple
    • it's future proof
    • it's flexible

    Whenever your application needs to launch another desktop application, find available applications, load plugins or find application add-ons it's as simple as a few lines of code to do so and the code is quite similar regardless of what you are looking for.

    Since most of the details involved in looking up services are hidden away from your application, if things change either due to time and new standards or platform specific features your code will continue to work. For instance, when KDE implemented the freedesktop.org specification for describing application launcher menu structures, application code that had been functioning previous to this continued to function without any changes or even a recompile.

    Best of all, the services system provides a flexible system under the hood for users and administrators to be able to customize, add new entries, remove existing items and even lock down access without putting any burden of complexity on application developers.

    Classes At A Glance

    The main services related classes that applications are likely to use are generally limited to the following two:

    • KService: represents one application, plugin or add on
    • KServiceTypeTrader: allows discovery of available services through a simple query language; this class and the query language is covered in detail in the next tutorial

    Other classes that are available but less often used by applications include:

    • KServiceOffer: provides information on user preference for a given service; primarly used for mimetypes
    • KServiceType: provides access to information about a given type of service
    • KServiceTypeProfile: represents the user's preferences between multiple services of the same type; this is used internally by KServiceTypeTrader

    KService

    The KService class is at the center of the services system. It serves both an informational and a functional role. KService provides access to details on a given service such as whether it is an application, the name of the service, the associated icon (if any), etc. But it can also be used to launch applications and load plugins from disk.

    A KService object can be obtained in one of three ways:

    • creating one manually
    • requesting one by name
    • querying

    The first approach is the most straightforward and often looks something like this:

    QString pathToDesktopFile = KStandardDirs::locate("services", "konqueror.desktop");
    KService service(pathToDesktopFile);
    

    KService also provides ways to load services by name directly with the serviceBy* set of methods, of which the safest and most recommended is serviceByStorageId:

    KService::Ptr service = KService::serviceByStorageId("konqueror");
    

    Note that it passed back a KService::Ptr rather than just a KService. A KService::Ptr looks, acts and behaves just like a regular pointer (KService*) but it is automatically memory managed. It is not necessary to manually delete KService::Ptrs, because they are reference counted.

    A list of all services can be retrieved using the KService::allServices method. Of course, one often wants finer grained control over locating services, which is the role of the KServiceTypeTrader and is the topic of the next tutorial in this series.

    At this point we now have access to all sorts of information on the service, which in this case is an application called konqueror. We can even launch the app using this service:

    if (service.isApplication()) {
        KUrl::List urls;
        urls << "http://www.kde.org";
        KRun::run(service, urls, 0);
    }
    

    This would launch konqueror and cause it to open the KDE homepage.

    Registering Services

    Services are represented on disk as individual .desktop files. This makes it easy to add, remove, and customize services on the system. The .desktop files are organized by their type of service. Applications, plugins, protocols, and mimetypes are each kept in their own directories. The location of these directories is documented in the KDE Filesystem Hierarchy page. Installation is usually automated through the build system, such as CMake in KDE4.

    Services may also have one or more "service types" that are used to categorize and search for them. While applications and mimetypes don't utilize this, plugins and other services do. These service types are registered by placing a .desktop file describing the service type in the correct location in the filesystem, usually share/kde4/servicetypes. See the KDE Filesystem Hierarchy page for more information.

    The content and form of these .desktop files is covered in detail in the Creating and Loading Plugins Using KService tutorial.

    SyCoCa: The System Configuration Cache

    While the .desktop (file) method is very handy for users (and adding new entries), performance could be an issue because it is common to have thousands of these files describing various mimetypes, applications, plugins, screensavers, etc. Thus, the entries are put into a binary cache which is accessed via shared memory by all applications. The cache is known as the System Configuration Cache, or SyCoCa for short. Loading and locating KServices is done via this cache, transparently to the application.

    Whenever a new .desktop file is added, removed or altered, the cache is automatically updated by the kbuildsycoca4 application. You can force an update of the cache by running kbuildsycoca4 manually, though usually it is launched by kded4 automatically when needed. A full rebuild of the cache (versus a simple update) can be triggered by passing --noincremental to kbuildsycoca4.

    Searching For Services

    The next tutorial is Finding Services Using Trader Queries. We will look at how to find services using the KTrader query language and KServiceTypeTrader .