Calligra/Schedules/3.0/Porting Notes: Difference between revisions

From KDE Community Wiki
(Created page with "For general plan see 3.0 Porting Plan = Plugin system = Calligra in some 2.x version stopped to use kdelibs' KSyCoCa (System Configur...")
 
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
For general plan see [[Calligra/Schedules/3.0/Porting_Plan|3.0 Porting Plan]]
For general plan see [[Calligra/Schedules/3.0/Porting_Plan|3.0 Porting Plan]]
= General notes =
* recommendation from #kde-devel: not blindly run any porting scripts that are available, but rather decide case-by-case if to run the script or just do manual porting
* some of the porting scripts conflict with using kdelibs4support ("e.g. if #include <KGlobal> has been removed, we might have to restore it")
== General Porting Info ==
* [https://community.kde.org/Frameworks/Porting_Notes Frameworks 5 porting notes]
* [http://doc.qt.io/qt-5/portingguide.html Qt5 Porting Guide]
* [http://api.kde.org/frameworks-api/frameworks5-apidocs/ Frameworks 5 apidox]
* [https://community.kde.org/Frameworks/Building Frameworks 5 build instructions]
* [[Calligra/Building/3|Building Calligra]] is still the same, just with new deps
* [http://quickgit.kde.org/?p=kde-dev-scripts.git kde-dev-scripts.git] on git.kde.org has useful porting scripts
* [http://quickgit.kde.org/?p=kdelibs.git&a=blob&h=bbc1c41b06b780301f0b890dcb79831b900dde86&f=KDE5PORTING.html&o=plain#kdecore KDE5PORTING.html]
* [http://api.kde.org/ecm/ ECM API dox]
* [https://techbase.kde.org/Development/ECM_SourceIncompatChanges ECM SourceIncompatChanges]
* http://www.proli.net/2014/06/21/porting-your-project-to-qt5kf5/
<br/>To see changes done in the previous Qt5 port:
    git diff 9fb2dfcfe0ee0aeb032a149d6 origin/calligra-qt5-rempt -- some/subdir/or/files


= Plugin system =
= Plugin system =
Line 8: Line 27:


=== Adapting plugins ===
=== Adapting plugins ===
{{Note|After the related .desktop file changes kcoreaddons_desktop_to_json() does not update the target. You need to call cmake by hand as explained in the [https://bugs.kde.org/349398 bug report].}}
Creating the metadata in JSON format from the desktop file:
Creating the metadata in JSON format from the desktop file:


Line 59: Line 80:
#include <KoServiceLocator.h>
#include <KoServiceLocator.h>
// ...
// ...
     const KService::List offers = KoServiceLocator::instance()->entries("Calligra/Part", mimetype);
     const KService::List offers =
    KoServiceLocator::instance()
    ->entries("Calligra/Part", mimetype);


     foreach(KService::Ptr offer, offers) {
     foreach(KService::Ptr offer, offers) {
Line 68: Line 91:
#include <QPluginLoader>
#include <QPluginLoader>
// ...
// ...
     const QList<QPluginLoader *> offers = KoJsonTrader::self()->query("Calligra/Part", mimetype);
     const QList<QPluginLoader *> offers =
    KoJsonTrader::self()
    ->query("Calligra/Part", mimetype);


     foreach(QPluginLoader *pluginLoader, offers) {
     foreach(QPluginLoader *pluginLoader, offers) {
</source>
</source>
|}
|}
Line 85: Line 109:
#include <KoServiceLocator.h>
#include <KoServiceLocator.h>
// ...
// ...
    const KService::List offers = KoServiceLocator::instance()->entries(serviceType);
  const KService::List offers =  
  KoServiceLocator::instance()->entries(serviceType);


    foreach(KService::Ptr offer, offers) {
  foreach(KService::Ptr offer, offers) {
            const QString pluginName = service->property(QLatin1String("X-KDE-PluginInfo-Name"), QVariant::String).toString();
    const QString pluginName = service->property(
    QLatin1String("X-KDE-PluginInfo-Name"),
    QVariant::String)
  .toString();
 
 
</source>  
</source>  
|
|
Line 95: Line 125:
#include <QPluginLoader>
#include <QPluginLoader>
// ...
// ...
    const QList<QPluginLoader *> offers = KoJsonTrader::self()->query(serviceType, QString());
  const QList<QPluginLoader *> offers =  
  KoJsonTrader::self()
  ->query(serviceType, QString());


    foreach(QPluginLoader *loader, offers) {
  foreach(QPluginLoader *loader, offers) {
        QJsonObject json = loader->metaData().value("MetaData").toObject();
    QJsonObject json = loader->metaData()
        json = json.value("KPlugin").toObject();
    .value("MetaData").toObject();
        const QString pluginName = json.value("Id").toString();
    json = json.value("KPlugin").toObject();
    const QString pluginName =
    json.value("Id").toString();
</source>
</source>
|}
|}
More info and other plugin systems:
* [http://api.kde.org/frameworks-api/frameworks5-apidocs/kservice/html/index.html KService] - initial blog http://vizzzion.org/blog/2013/08/kde-frameworks-5-plugin-factory-guts (note: a bit outdated info [https://git.reviewboard.kde.org/r/121959/])
* A sample with deps: [http://dtk.inria.fr/blog/?p=502 DTK]
* Advanced: [http://www.kdab.com/kdab-products/kdcf-overview/ KDCF]
* Advanced: [http://www.commontk.org/index.php/Documentation/Plugin_Framework commontk]


= Resource system =
= Resource system =
KStandardDirs, sometimes bound to certain KComponentData, has been used in kdelibs4 to access all kind of resources:
* app resources (referenced by hardcoded ids, possible to customize by overrides in user app data dir), like icons, images, fonts etc. used in the UI
* material for mixing into content created with the app (tool configurations, brushes, palettes, clipart, styles, etc.)
* user created content, managed via the app and not by filemanager (templates, plan workshops, etc.)
App resources are either be accessed from hardcoded path, defined during buildtime, or could also be relative to executable (useful platforms where installation location only decided at installation time, or where installations should be relocatable as a bundle, think "Krita on a USB stick").
Material for mixing into content creation should also be found in other places than the app's own, either in standard locations or app-specific ones of well known applications (e.g. "Gimp"). Also might the user be allowed to extend the collection of resources, either by importing from somewhere or even creating assisted by the application ("palette editor"). These new resources should be either installed in a standard place, so they are also accessilble in other standard-aware applications, or the app-specific locations.
In KF5, KStandardDirs lost the ability to be bound to KComponentData instances, there is now only one global set of dirs.
To be continued...
= Translations =
= Translations =
= Debug logging =
= Debug logging =
= Locale =
* KLocale -> QPrinterInfo for KoPageFormat: patch at [https://git.reviewboard.kde.org/r/123410/].
** There are two other occurences in calligra that use KGlobal::locale()->pageSize().
**..and 325 occurences of KGlobal::locale()

Latest revision as of 20:28, 14 July 2015

For general plan see 3.0 Porting Plan

General notes

  • recommendation from #kde-devel: not blindly run any porting scripts that are available, but rather decide case-by-case if to run the script or just do manual porting
  • some of the porting scripts conflict with using kdelibs4support ("e.g. if #include <KGlobal> has been removed, we might have to restore it")

General Porting Info


To see changes done in the previous Qt5 port:

   git diff 9fb2dfcfe0ee0aeb032a149d6 origin/calligra-qt5-rempt -- some/subdir/or/files

Plugin system

Calligra in some 2.x version stopped to use kdelibs' KSyCoCa (System Configuration Cache) and the class KServiceTypeTrader to find any installed shapes, parts, filters or other plugins. Instead it uses its own system, based on the .desktop files of all plugins, with the plugin metadata, being installed in the subfolder /calligra of the install dir for the service metadata. And uses the class KoServiceLocator from libs/koplugin to query from those metadata for the matching shapes, parts, filters or other plugin types.

With Qt5 there is now the option to store the metadata about plugins directly into the binary module file itself (using a special section) and to also read the metadata from there, without actually loading the plugin. So for Calligra it was decided to move like proposed from the desktop files to the embedded metadata. The metadata is stored in JSON format.

Adapting plugins

Note

After the related .desktop file changes kcoreaddons_desktop_to_json() does not update the target. You need to call cmake by hand as explained in the bug report.


Creating the metadata in JSON format from the desktop file:

Instead of installing the desktop file, use the given macro to create a JSON file in the build dir from the desktop file. The generated JSON file will have the same basename as the .desktop file, e.g. foo.json with foo.desktop

Original Code Ported Code
add_library(foo MODULE ${foo_SRCS})
install(FILES foo.desktop DESTINATION ${SERVICES_INSTALL_DIR}/calligra)
add_library(foo MODULE ${foo_SRCS})
kcoreaddons_desktop_to_json(foo foo.desktop)

Including the generated JSON file into the plugin via a C++ macro:

Original Code Ported Code
K_PLUGIN_FACTORY(FooFactory, registerPlugin<Foo>();)
K_EXPORT_PLUGIN(FooFactory("foo"))
K_PLUGIN_FACTORY_WITH_JSON(FooFactory, "foo.json",
                           registerPlugin<Foo>();)

Adapting searches

When searching for plugins with embedded JSON metadata one uses KoJsonTrader from libs/koplugin.

Searching parts for a mimetype:

Original Code Ported Code
#include <KoServiceLocator.h>
// ...
    const KService::List offers =
     KoServiceLocator::instance()
     ->entries("Calligra/Part", mimetype);

    foreach(KService::Ptr offer, offers) {
#include <KoJsonTrader.h>
#include <QPluginLoader>
// ...
    const QList<QPluginLoader *> offers =
     KoJsonTrader::self()
     ->query("Calligra/Part", mimetype);

    foreach(QPluginLoader *pluginLoader, offers) {

Searching plugins of a type, with custom filtering of the results:

Original Code Ported Code
#include <KoServiceLocator.h>
// ...
  const KService::List offers = 
   KoServiceLocator::instance()->entries(serviceType);

   foreach(KService::Ptr offer, offers) {
     const QString pluginName = service->property(
     QLatin1String("X-KDE-PluginInfo-Name"),
     QVariant::String)
   .toString();
#include <KoJsonTrader.h>
#include <QPluginLoader>
// ...
  const QList<QPluginLoader *> offers = 
   KoJsonTrader::self()
   ->query(serviceType, QString());

  foreach(QPluginLoader *loader, offers) {
    QJsonObject json = loader->metaData()
     .value("MetaData").toObject();
    json = json.value("KPlugin").toObject();
    const QString pluginName =
     json.value("Id").toString();

More info and other plugin systems:

Resource system

KStandardDirs, sometimes bound to certain KComponentData, has been used in kdelibs4 to access all kind of resources:

  • app resources (referenced by hardcoded ids, possible to customize by overrides in user app data dir), like icons, images, fonts etc. used in the UI
  • material for mixing into content created with the app (tool configurations, brushes, palettes, clipart, styles, etc.)
  • user created content, managed via the app and not by filemanager (templates, plan workshops, etc.)

App resources are either be accessed from hardcoded path, defined during buildtime, or could also be relative to executable (useful platforms where installation location only decided at installation time, or where installations should be relocatable as a bundle, think "Krita on a USB stick").

Material for mixing into content creation should also be found in other places than the app's own, either in standard locations or app-specific ones of well known applications (e.g. "Gimp"). Also might the user be allowed to extend the collection of resources, either by importing from somewhere or even creating assisted by the application ("palette editor"). These new resources should be either installed in a standard place, so they are also accessilble in other standard-aware applications, or the app-specific locations.

In KF5, KStandardDirs lost the ability to be bound to KComponentData instances, there is now only one global set of dirs.

To be continued...

Translations

Debug logging

Locale

  • KLocale -> QPrinterInfo for KoPageFormat: patch at [2].
    • There are two other occurences in calligra that use KGlobal::locale()->pageSize().
    • ..and 325 occurences of KGlobal::locale()