Calligra/Schedules/3.0/Porting Notes
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
- Frameworks 5 porting notes
- Qt5 Porting Guide
- Frameworks 5 apidox
- Frameworks 5 build instructions
- Building Calligra is still the same, just with new deps
- kde-dev-scripts.git on git.kde.org has useful porting scripts
- KDE5PORTING.html
- ECM API dox
- ECM SourceIncompatChanges
- http://www.proli.net/2014/06/21/porting-your-project-to-qt5kf5/
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
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:
- KService - initial blog http://vizzzion.org/blog/2013/08/kde-frameworks-5-plugin-factory-guts (note: a bit outdated info [1])
- A sample with deps: DTK
- Advanced: KDCF
- Advanced: commontk
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()