Frameworks/Porting Notes: Difference between revisions
Cyeleighton (talk | contribs) (→Docbook Documentation Changes: CMake document processing macros) |
|||
(16 intermediate revisions by 9 users not shown) | |||
Line 13: | Line 13: | ||
<syntaxhighlight lang="cmake"> | <syntaxhighlight lang="cmake"> | ||
include(KDEInstallDirs) | include(KDEInstallDirs) | ||
include(KDECompilerSettings) | include(KDECompilerSettings NO_POLICY_SCOPE) | ||
include(KDECMakeSettings) | include(KDECMakeSettings) | ||
include(FeatureSummary) | include(FeatureSummary) | ||
Line 40: | Line 40: | ||
== Installing Icons == | == Installing Icons == | ||
The command to install icons has seen major changes | The command to install icons has seen major changes which are described in the [[techbase:Development/ECM_SourceIncompatChanges|source-incompatible changes]] page. | ||
= KDECore Changes = | = KDECore Changes = | ||
Line 87: | Line 87: | ||
* A major difference is that KCmdLineArgs was set up before KApplication, while QCommandLineParser should be set up after creating the Q[Core]Application. This allows to use i18n() or tr() in the option definitions. | * A major difference is that KCmdLineArgs was set up before KApplication, while QCommandLineParser should be set up after creating the Q[Core]Application. This allows to use i18n() or tr() in the option definitions. | ||
* Use kde-dev-scripts/kf5/convert-kcmdlineargs.pl to automate most of the conversion. | * Use kde-dev-scripts/kf5/convert-kcmdlineargs.pl to automate most of the conversion. | ||
* KCmdLineArgs::addTempFileOption() becomes | |||
parser.addOption(QCommandLineOption(QStringList{"tempfile"}, i18n("The files/URLs opened by the application will be deleted after use"))); | |||
* args.url(i) becomes QUrl::fromUserInput(args.at(i), QDir::currentPath()) (possibly with QUrl::AssumeLocalFile as 3rd argument if the application supports creating files, see documentation) | |||
== KAboutData == | == KAboutData == | ||
* Make sure to call KAboutData::setApplicationData() from the main() of the application. | * Make sure to call KAboutData::setApplicationData() from the main() of the application. | ||
* Make sure to create KAboutData instance only once the Q*Application instance has been created, if you are using KI18n's i18n() calls for translated strings. Only after the instance creation all locale settings are done as needed. | |||
* Make sure to call KAboutData::setApplicationData() only once the Q*Application instance has been created, otherwise the respective Q*Application metadata will not be set (e.g. QGuiApplication::applicationDisplayName), which other KF5 code now relies on. | * Make sure to call KAboutData::setApplicationData() only once the Q*Application instance has been created, otherwise the respective Q*Application metadata will not be set (e.g. QGuiApplication::applicationDisplayName), which other KF5 code now relies on. | ||
* KAboutData::setApplicationData() no longer sets the app window icon. For shells which do not fetch the icon name via the desktop file, make sure to call QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("foo"))); (in GUI apps). | |||
* KAboutData::LicenseKey enums (e.g. KAboutData::License_LGPL) have all been moved to KAboutLicense in the KCoreAddons framework (KAboutLicense::LGPL, in this example). | * KAboutData::LicenseKey enums (e.g. KAboutData::License_LGPL) have all been moved to KAboutLicense in the KCoreAddons framework (KAboutLicense::LGPL, in this example). | ||
* KAboutData::catalogName and setCatalogName are gone, as is the constructor taking a catalogName. For KF5 software you want to use [http://api.kde.org/frameworks-api/frameworks5-apidocs/ki18n/html/classKLocalizedString.html#ad866b11bf396b9d93b7dc313a1930b7b KLocalizedString::setApplicationDomain] to set your translation catalog before constructing KAboutData. Alternately, there is still K4AboutData for temporary compatibility help while porting. | * KAboutData::catalogName and setCatalogName are gone, as is the constructor taking a catalogName. For KF5 software you want to use [http://api.kde.org/frameworks-api/frameworks5-apidocs/ki18n/html/classKLocalizedString.html#ad866b11bf396b9d93b7dc313a1930b7b KLocalizedString::setApplicationDomain] to set your translation catalog before constructing KAboutData. Alternately, there is still K4AboutData for temporary compatibility help while porting. | ||
* KCmdLineArgs uses K4AboutData rather than KAboutData: K4AboutData keeps the old mechanism for delayed translations (I18N_NOOP), while KAboutData is the one used by plugins, which can use immediate translation (i18n). | * KCmdLineArgs uses K4AboutData rather than KAboutData: K4AboutData keeps the old mechanism for delayed translations (I18N_NOOP), while KAboutData is the one used by plugins, which can use an immediate translation (i18n). | ||
== URL == | == URL == | ||
Line 103: | Line 108: | ||
* KUrl::upUrl is now the static method KIO::upUrl | * KUrl::upUrl is now the static method KIO::upUrl | ||
It is <b>very strongly</b> recommended to set -DQT_NO_URL_CAST_FROM_STRING so that the calls to QUrl(QString) are explicit. | |||
Many signals with a KUrl have been replaced with a QUrl (remember to update your connect statements and your slots!): | Many signals with a KUrl have been replaced with a QUrl (remember to update your connect statements and your slots!): | ||
Line 180: | Line 185: | ||
</pre> | </pre> | ||
The following functions have been moved into khtml with the | The following functions have been moved into khtml with the original KEncodingDetector class. khtml is the only user of them. | ||
<pre> | <pre> | ||
enum KEncodingDetector::EncodingChoiceSource -> removed | enum KEncodingDetector::EncodingChoiceSource -> removed | ||
Line 277: | Line 282: | ||
* Call QCoreApplication::setOrganizationDomain("kde.org") | * Call QCoreApplication::setOrganizationDomain("kde.org") | ||
* Call QGuiApplication::setApplicationDisplayName(i18n("...")) for GUI programs | * Call QGuiApplication::setApplicationDisplayName(i18n("...")) for GUI programs | ||
* Call QGuiApplication::setDesktopFileName("...") for GUI programs | |||
Make sure that the desktop file name set directly or via KAboutData matches the desktop file name (without file extension) installed for the program. This property is used by shells like Plasma to access more metadata about a running program which is stored in its desktop file. | |||
* Call QGuiApplication::setWindowIcon(QIcon::fromTheme("...")) for GUI programs | * Call QGuiApplication::setWindowIcon(QIcon::fromTheme("...")) for GUI programs (needed by shells not using desktop file to retrieve app metadata) | ||
* Use KDBusService for DBus registration, and optional "unique" behavior | * Use KDBusService for DBus registration, and optional "unique" behavior. Use also the "NoExitOnFailure" flag, unless unsuited. | ||
* Important: if you create a QApplication (instead of KApplication) after using KCmdLineArgs, do not pass argc and argv to it, but KCmdLineArgs::qtArgc() and KCmdLineArgs::qtArgv(). This can go away when porting away from KCmdLineArgs. | * Important: if you create a QApplication (instead of KApplication) after using KCmdLineArgs, do not pass argc and argv to it, but KCmdLineArgs::qtArgc() and KCmdLineArgs::qtArgv(). This can go away when porting away from KCmdLineArgs. | ||
Line 287: | Line 294: | ||
* remove "%i" (not supported by any Q*Application) | * remove "%i" (not supported by any Q*Application) | ||
If your program should work as a D-Bus activatable service, the base name of the D-Bus service description file or of the desktop file you install must match the D-Bus "well-known name" for which the program will register. For example, KDBusService will use a name created from the reversed organization domain with the component name attached, so for an organization domain "bar.org" and a component name "foo" the name of an installed D-Bus service file needs to be "org.bar.foo.service" or the name of the installed desktop file "org.bar.foo.desktop". | |||
X-DBUS-ServiceName=org. | |||
to the .desktop file | For still supporting the deprecated start of services via KToolInvocation, the desktop file needs to have an entry with the key "X-DBUS-ServiceName" and a value which matches the used D-Bus "well-known name" as just described, so with the above used values it needs a line "X-DBUS-ServiceName=org.bar.foo" | ||
If you adopt the desktop file name for being D-Bus activatable, make sure to also update the value set for the desktopFileName application data property (see above). With the given example, it would accordingly be set to "org.bar.foo". | |||
For standard purposes, it is recommended to use a desktop file name which uses an organization domain. So if without one yet and unless the desktop file name is bound to its current name (e.g. by respective D-Bus well-known name being in use), consider renaming it (and then adapting all related data). The appdata file should have the same name for consistency. | |||
== General == | == General == | ||
Line 320: | Line 331: | ||
* KLed: Several protected virtual methods to override painting got removed. If you need custom painting, override paintEvent() instead. | * KLed: Several protected virtual methods to override painting got removed. If you need custom painting, override paintEvent() instead. | ||
* Use [http://qt-project.org/doc/qt-5/qkeysequence.html QKeySequence] instead of KShortcut to set shortcuts in actions. | * Use [http://qt-project.org/doc/qt-5/qkeysequence.html QKeySequence] instead of KShortcut to set shortcuts in actions. | ||
* KInputDialog: use QInputDialog instead, with a relevant difference the returned value: QInputDialog allows empty input and it is not possible to define a validator. Ensure that the returned value is checked if an empty value is not acceptable. | |||
* KPushButton::setGuiItem(const KGuiItem&): use QPushButton and KGuiItem::assign(QPushButton *button, const KGuiItem &item) ([https://api.kde.org/frameworks/kdelibs4support/html/classKPushButton.html#a6d5921d7d162c1da12a0d93526032d80 details]) | |||
== Global Settings == | == Global Settings == | ||
Line 389: | Line 402: | ||
== Dialog == | == Dialog == | ||
* KDialog: It has been deprecated and moved to kde4support. | * KDialog: It has been deprecated and moved to kde4support. Port to QDialog + QDialogButtonBox. The script in kde-dev-scripts/kf5/convert-kdialog.pl can help. | ||
== KCharSelect == | |||
* KCharSelect: To allow the user to select characters outside the Unicode BMP, you must <tt>setAllPlanesEnabled(true)</tt> and port to the uint-based methods and signals (available since version 5.25): | |||
** <tt>QChar currentChar()</tt> ➙ <tt>uint currentCodePoint()</tt> | |||
** <tt>setCurrentChar(QChar)</tt> ➙ <tt>setCurrentCodePoint(uint)</tt> | |||
** <tt>charSelected(QChar)</tt> ➙ <tt>codePointSelected(uint)</tt> | |||
** <tt>currentCharChanged(QChar)</tt> ➙ <tt>currentCodePointChanged(uint)</tt> | |||
To convert between uint code points and QString, use <tt>QString::fromUcs4()</tt> and <tt>QString::toUcs4()</tt>: | |||
<syntaxhighlight lang="cpp-qt"> | <syntaxhighlight lang="cpp-qt"> | ||
... | |||
Q_SLOTS: | |||
void codePointSelected(uint code) { | |||
QString selected = QString::fromUcs4(&code, 1); | |||
... | |||
} | |||
... | |||
</syntaxhighlight> | </syntaxhighlight> | ||
You can also manually do the surrogate pair handling. | |||
== Style == | == Style == | ||
Line 413: | Line 440: | ||
* Use QFontDialog instead of KFontDialog. Notice that, in the case of KFontDialog::getFont vs QFontDialog::getFont, QFontDialog::getFont returns the selected font instead of the dialog code, and the Accept/Cancel value is returned through a pointer to a boolean value that is passed as the first argument. Also, notice that the flags for KFontDialog::getFont (defined at [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKFontChooser.html#a5f8cecef70d1a0b820592c17db7dafb7 KFontChooser::DisplayFlag]) do not map to those of QFontDialog::getFont (defined at [http://qt-project.org/doc/qt-5/qfontdialog.html#FontDialogOption-enum QFontDialog:: FontDialogOptions]) and serve a different purpose. | * Use QFontDialog instead of KFontDialog. Notice that, in the case of KFontDialog::getFont vs QFontDialog::getFont, QFontDialog::getFont returns the selected font instead of the dialog code, and the Accept/Cancel value is returned through a pointer to a boolean value that is passed as the first argument. Also, notice that the flags for KFontDialog::getFont (defined at [http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKFontChooser.html#a5f8cecef70d1a0b820592c17db7dafb7 KFontChooser::DisplayFlag]) do not map to those of QFontDialog::getFont (defined at [http://qt-project.org/doc/qt-5/qfontdialog.html#FontDialogOption-enum QFontDialog:: FontDialogOptions]) and serve a different purpose. | ||
* It should be noted that QFontDialog does not support the deactivation of the style list. If necessary, KFontChooser is a better alternative. | |||
== Window Systems == | == Window Systems == | ||
Line 482: | Line 511: | ||
= KParts Changes = | = KParts Changes = | ||
* With the port from KUrl to QUrl in APIs, the signature of the virtual method openUrl has changed, make sure | * With the port from KUrl to QUrl in APIs, the signature of the virtual method openUrl has changed, make sure to port your reimplemented methods to QUrl! | ||
* TerminalInterfaceV2 has been merged into TerminalInterface, you can remove the "V2" everywhere (classname, interface name). | * TerminalInterfaceV2 has been merged into TerminalInterface, you can remove the "V2" everywhere (classname, interface name). | ||
* The installed normal lowercase headers no longer define multiple classes. Now it is only one class per header, with the filename matching the classname (e.g. KParts::ReadOnlyPart is no longer defined in <kparts/part.h> but <kparts/readonlypart.h>). So make sure you now include the matching headers. | * The installed normal lowercase headers no longer define multiple classes. Now it is only one class per header, with the filename matching the classname (e.g. KParts::ReadOnlyPart is no longer defined in <kparts/part.h> but <kparts/readonlypart.h>). So make sure you now include the matching headers. | ||
Line 517: | Line 546: | ||
= KDNSSD Changes = | = KDNSSD Changes = | ||
* The include paths | * The include paths have changed from dnssd to kdnssd | ||
* The namespace has changed from DNSSD to KDNSSD | * The namespace has changed from DNSSD to KDNSSD | ||
Line 534: | Line 563: | ||
libplasma has been replaced with libplasma2. See the [[Plasma/PortingTolibplasma2|libplasma2 porting notes]]. | libplasma has been replaced with libplasma2. See the [[Plasma/PortingTolibplasma2|libplasma2 porting notes]]. | ||
Plasma themes specifications has seen small changes as well (intended and unintended) . See the [https://techbase.kde.org/Development/Tutorials/Plasma5/ThemePortingToPlasma5 Theme porting notes]. | |||
= Docbook Documentation Changes = | = Docbook Documentation Changes = | ||
== DocBook XML schema == | |||
The DocBookXML schema used by the documentation has changed; the custom KDE DTD is now based on version 4.5 (previously was 4.2). The change is almost painless (and should be completely painless for applications using KDE4Support). | |||
You need to change the DOCTYPE declaration as follows: | |||
<syntaxhighlight lang="diff"> | <syntaxhighlight lang="diff"> | ||
--- <!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [ | --- <!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [ | ||
Line 545: | Line 575: | ||
(The changes are "V4.2" to "V4.5" and "dtd/kdex.dtd" to "dtd/kdedbx45.dtd"). | (The changes are "V4.2" to "V4.5" and "dtd/kdex.dtd" to "dtd/kdedbx45.dtd"). | ||
== Document processing macros == | |||
CMake document processing macros have been renamed from prefix <code >kde4_</code > to prefix <code >kdoctools_</code >. The <code >DocTools</code > component must be loaded to use them. | |||
= KAuth Changes = | = KAuth Changes = | ||
Line 551: | Line 584: | ||
= KTextEditor Changes = | = KTextEditor Changes = | ||
Changes to the KTextEditor Interfaces are documented in the API documentation: http://api.kde.org/frameworks-api/frameworks5-apidocs/ktexteditor/html/kte_port_to_5.html | Changes to the KTextEditor Interfaces are documented in the API documentation: http://api.kde.org/frameworks-api/frameworks5-apidocs/ktexteditor/html/kte_port_to_5.html | ||
= KNotifications Changes = | |||
* KNotifications lets you set a default sound for notifications. Typically for KDE applications these were sounds shipped by kde-runtime. These should be changed to files shipped by Plasma 5. This is the same as the kde-runtime sound theme but with files renamed to start with Oxygen- instead of KDE-. You will need to update your .notifyrc file for this, e.g. Sound=KDE-Sys-Log-Out.ogg is now Sound=Oxygen-Sys-Log-Out.ogg | |||
= Solid Changes = | = Solid Changes = |
Latest revision as of 20:16, 14 November 2022
This document contains the changes you have to apply to programs written for KDE 4.x when you want to port them to KDE Frameworks 5.
The other part of the porting documentation is the notes in the documentation for deprecated methods (especially in kdelibs4support), make sure to check that out as well.
Build System
A lot of CMake code that used to be provided by kdelibs is now provided by the extra-cmake-modules package. This can be obtained by doing
find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
and something approximating the settings provided with kdelibs 4 can be achieved by
include(KDEInstallDirs)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(KDECMakeSettings)
include(FeatureSummary)
TechBase has a list of source incompatible changes in ECM.
Other changes of significance include:
- Add a feature_summary line to the end of the top level CMakeLists.txt.
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
- If you previously built with -DCMAKE_BUILD_TYPE=DebugFull, you should now use -DCMAKE_BUILD_TYPE=debug. Note that the old DebugFull build type passed -g3 to the compiler (causing it to include macro expansions in the debugging information), while CMake's built-in debug build type just passes -g. You can use the [[1]] variable to reintroduce this flag if necessary (ie: add -DCMAKE_CXX_FLAGS_DEBUG:STRING=-g3 and possibly -DCMAKE_C_FLAGS_DEBUG:STRING=-g3 to your CMake command line).
- The kde4_add_executable macro uses, should be changed into CMake's add_executable command.
- The NOGUI tag in kde4_add_executable should be replaced by the ecm_mark_nongui_executable() macro in ECM
- The TEST tag in kde4_add_executable should be replaced by the ecm_mark_as_test() macro in ECM
- To access the ecm_mark_as_test() macro, you must add:
include(ECMAddTests)
- The kde4_add_plugin uses, should be changed for add_library(... MODULE ...). If WITH_PREFIX was being used, you'll have to tell CMake what prefix you want: set_target_properties(<targetname> PROPERTIES PREFIX "${CMAKE_SHARED_LIBRARY_PREFIX}")
- KDE4_ADD_KDEINIT_EXECUTABLE should be turned into KF5_ADD_KDEINIT_EXECUTABLE, provided by KF5InitMacros.cmake.
- include directories are automatically generated from specified target_link_library parameters, e.g., to include KTextEditor headers, add "KF5::TextEditor" to the target_link_libraries call.
- kde4_add_unit_test(name sources) should be changed to add_executable(name sources) and add_test(lib-name name) and ecm_mark_as_test(name)
Installing Icons
The command to install icons has seen major changes which are described in the source-incompatible changes page.
KDECore Changes
kdecore has been split up into a number of independent libraries: libkarchive, libkauth, libkdbus, etc.
General
- KSaveFile has been deprecated in favour of the new QSaveFile:
- backupFile ➙ KBackup::backupFile
- open() ➙ open(QIODevice::WriteOnly)
- finalize() ➙ commit()
- abort() ➙ cancelWriting()
- close() ➙ do not call close, call commit or cancelWriting directly
- the return value from write() calls does not need to be checked anymore, commit will cancel in case of a write error
- Use kde-dev-scripts/kf5/convert-ksavefile.pl to automate most of the conversion.
- K_GLOBAL_STATIC: replace by adding #include <QGlobalStatic>, replace K_GLOBAL_STATIC with Q_GLOBAL_STATIC and move the declaration out of the instace() method. The constructor of a class used with QGlobalStatic must be public. This was not the case with K_GLOBAL_STATIC.
- KStandardDirs: see these specific porting notes.
- KArchive::writeFile takes arguments in a different order from before, so that "user" and "group" are now optional, and so that const char* data, qint64 size could be replaced with a QByteArray.
- KTemporaryFile is deprecated, port to QTemporaryFile instead, see KTemporaryFile API documentation for details. (Use kde-dev-scripts/kf5/convert-ktemporaryfile.pl to automate most of the conversion. )
- KTempDir is deprecated, port to QTemporaryDir instead, see KTempDir API documentation for details. (Use kde-dev-scripts/kf5/convert-ktempdir.pl to automate most of the conversion. )
- KToolInvocation::invokeHelp is now KHelpClient::invokeHelp, in the KConfigWidgets framework.
- KToolInvocation::klauncher() has been removed. Use startKdeinit if you just want kdeinit/klauncher to be running. For setLaunchEnv(), generate klauncher_iface.h from the installed org.kde.KLauncher.xml.
- KMD5 is deprecated, port to QCryptographicHash instead. (Use kde-dev-scripts/kf5/convert-kmd5.pl to automate most of the conversion.)
- qtest_kde.h is deprecated. Port to <QtTest>, for core tests, or to <QtTestWidgets> for tests that use widgets, otherwise they'll crash in code that requires QApplication internally.
- K_EXPORT_PLUGIN is deprecated. Either use Qt's native plugin system for simple plugins, or the K_PLUGIN_FACTORY or the K_PLUGIN_FACTORY_WITH_JSON macro, defined in kpluginfactory.h. In both cases, remove the K_EXPORT_PLUGIN macro from your code. This case is indicated by the K_EXPORT_PLUGIN_is_deprecated_see_KDE5PORTING warning. More details about the plugin factory changes are explained in this blog post.
- KAuthorized::authorizeUrlAction and KAuthorized::allowUrlAction have been moved to a new KUrlAuthorized namespace.
- kde_file.h: KDE_struct_stat is now QT_STATBUF, KDE::lstat is now QT_LSTAT, include qplatformdefs.h instead of kde_file.h
- KDebug is deprecated, use QDebug or QLogginCategory instead.
- For non-categorized logging:
- kDebug() ➙ qDebug()
- kError() ➙ qCritical()
- kFatal() ➙ qFatal()
- kWarning() ➙ qWarning()
- Use kde-dev-scripts/kf5/convert-kdebug.pl to automate most of the conversion.
- For categorized logging like kDebug(1221), see the kDebug -> qCDebug porting guide. (Use kde-dev-scripts/kf5/convert-kdebug-with-argument.sh to automate most of the conversion. )
- For non-categorized logging:
- *ui.rc files should now be installed in the ${KXMLGUI_INSTALL_DIR} directory
KComponentData
- The class is in kde4support now. Port away from it. In your main(), just remove the instantiation, and instead use QCoreApplication::setApplicationName, QGuiApplication::setApplicationDisplayName, QGuiApplication::setWindowIcon. In plugins, see KPluginFactory/KPluginLoader.
- dirs() has been removed. You can use kde4support's KGlobal::dirs, but better port to QStandardPaths. The only difference (for other KComponentData instances than the main one), is the "appdata" resource, which would now point to the application name rather than the component name. It's cleaner to use "data" anyway (or QStandardPaths::GenericDataLocation), and prepend the component name to the searched file.
- The main componentData now needs to be created only once a QCoreApplication instance exists, otherwise the call to KAboutData::setApplicationData() during registration as MainComponent will not have any effect and leave application name unset, resulting e.g. in no display name and resources not found
KCmdLineArgs
- Port to QCommandLineParser instead.
- A major difference is that KCmdLineArgs was set up before KApplication, while QCommandLineParser should be set up after creating the Q[Core]Application. This allows to use i18n() or tr() in the option definitions.
- Use kde-dev-scripts/kf5/convert-kcmdlineargs.pl to automate most of the conversion.
- KCmdLineArgs::addTempFileOption() becomes
parser.addOption(QCommandLineOption(QStringList{"tempfile"}, i18n("The files/URLs opened by the application will be deleted after use")));
- args.url(i) becomes QUrl::fromUserInput(args.at(i), QDir::currentPath()) (possibly with QUrl::AssumeLocalFile as 3rd argument if the application supports creating files, see documentation)
KAboutData
- Make sure to call KAboutData::setApplicationData() from the main() of the application.
- Make sure to create KAboutData instance only once the Q*Application instance has been created, if you are using KI18n's i18n() calls for translated strings. Only after the instance creation all locale settings are done as needed.
- Make sure to call KAboutData::setApplicationData() only once the Q*Application instance has been created, otherwise the respective Q*Application metadata will not be set (e.g. QGuiApplication::applicationDisplayName), which other KF5 code now relies on.
- KAboutData::setApplicationData() no longer sets the app window icon. For shells which do not fetch the icon name via the desktop file, make sure to call QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("foo"))); (in GUI apps).
- KAboutData::LicenseKey enums (e.g. KAboutData::License_LGPL) have all been moved to KAboutLicense in the KCoreAddons framework (KAboutLicense::LGPL, in this example).
- KAboutData::catalogName and setCatalogName are gone, as is the constructor taking a catalogName. For KF5 software you want to use KLocalizedString::setApplicationDomain to set your translation catalog before constructing KAboutData. Alternately, there is still K4AboutData for temporary compatibility help while porting.
- KCmdLineArgs uses K4AboutData rather than KAboutData: K4AboutData keeps the old mechanism for delayed translations (I18N_NOOP), while KAboutData is the one used by plugins, which can use an immediate translation (i18n).
URL
KUrl has been deprecated in favour of QUrl. Warning: look at the KUrl documentation for proper porting. Do not just do a global search-and-replace. In particular:
- KUrl(QString) means "absolute local file or absolute url" while QUrl(QString) means "relative url or absolute url", so for local files you have to use QUrl::fromLocalFile(QString), or if it could be local-or-remote, use QUrl::fromUserInput(QString). Note that the one-argument form of QUrl::fromUserInput assumes a web browser context. Qt 5.4 introduces a 2- or 3-argument form that is more appropriate for contexts such as command-line arguments. The closest equivalent to KUrl(QString) in Qt 5.4 is QUrl::fromUserInput(QString, QString(), QUrl::AssumeLocalFile). A version that always returns an absolute URL (as, e.g., KCmdLineArgs::url did) is QUrl::fromUserInput(QString, QDir::currentPath(), QUrl::AssumeLocalFile). (QUrl::AssumeLocalFile means that nonexistent files should not be assumed to be http:// URLs. This is required for output file names, and recommended for input file names in most contexts, because otherwise mistyped file names can result in DNS lookups, leaking user information.) If you don't want to depend on Qt 5.4 yet, use this code.
- KUrl u; u.setPath("/tmp"); would make it file:///tmp, while QUrl u; u.setPath("/tmp"); is an incomplete URL, without a scheme. The correct way with QUrl is QUrl::fromLocalFile("/tmp").
- KUrl::isParentOf means "parent or equal" while QUrl::isParentOf is strictly "parent" (see porting instructions in KUrl::isParentOf)
- KUrl::upUrl is now the static method KIO::upUrl
It is very strongly recommended to set -DQT_NO_URL_CAST_FROM_STRING so that the calls to QUrl(QString) are explicit.
Many signals with a KUrl have been replaced with a QUrl (remember to update your connect statements and your slots!):
- KUrlRequester: urlSelected(const KUrl&) ➙ urlSelected(const QUrl&)
- KRecentFilesAction: urlSelected(const KUrl&) ➙ urlSelected(const QUrl&)
- KUrlComboBox: urlActivated(const KUrl&) ➙ urlActivated(const QUrl&)
- KPropertiesDialog: saveAs(KUrl,KUrl) ➙ saveAs(QUrl,QUrl)
KUrl also provided the KUrl::List class that was mainly a QList of KUrl objects with some static helper methods to deal with MIME data. It should now be a QList<QUrl>, and the following changes should be made
Some commonly-used methods:
- KUrl::prettyUrl ➙ QUrl::toDisplayString (warning: do not use plain toString(), because it includes the password by default, see also CVE-2013-2074)
- KUrl::pathOrUrl ➙ QUrl::url(QUrl::PreferLocalFile)
- Porting hints for many other KUrl methods can be found in the API documentation for KUrl in KDELibs4Support.
Mime Types
KMimeType is deprecated, port to QMimeType instead. kde-dev-scripts/kf5/convert-kmimetype.pl implements most of the following porting guide:
- QMimeDatabase db;, all the methods need a db instance, but it's very cheap to create, on stack is fine.
- KMimeType::Ptr mime ➙ QMimeType mime
- if (mime) ➙ if (mime.isValid())
- KMimeType::mimeType(name) ➙ db.mimeTypeForName(name)
- KMimeType::mimeType(name, DontResolveAlias) ➙ db.mimeTypeForName(name), there is no separate mime object for the alias
- KMimeType::findByUrl(url) ➙ db.mimeTypeForUrl(url)
- KMimeType::findByUrl(url, 0, is_local, true) ➙ db.mimeTypeForFile(url.path(), QMimeDatabase::MatchExtension)
- KMimeType::findByPath(path) ➙ db.mimeTypeForFile(path)
- KMimeType::findByPath(path, 0, true) ➙ db.mimeTypeForFile(path, QMimeDatabase::MatchExtension) (this is slightly different in case of conflicting globs though, findByPath used to return empty, so that delayed mimetype determination could then refine this; mimeTypesForFileName can be useful to detect this case. But for most applications this detail doesn't matter).
- KMimeType::findByContent(data) ➙ db.mimeTypeForData(data)
- KMimeType::findByNameAndContent(fileName, data_or_device) ➙ db.mimeTypeForFileNameAndData(fileName, data_or_device)
- KMimeType::findByFileContent(path) ➙ db.mimeTypeForFile(path, QMimeDatabase::MatchContent)
- mime->name() == KMimeType::defaultMimeType() ➙ mime.isDefault()
- mime.allParentMimeTypes() ➙ mime.allAncestors()
- KMimeType::extractKnownExtension(fileName) ➙ db.suffixForFileName(fileName)
- KMimeType::iconNameForUrl(url) has additional logic on top of db.mimeTypeForUrl(url).iconName(), to fallback to the protocol-specific icon (e.g. trash icon for trash:/, etc.). This logic has now moved to KIO::iconNameForUrl(from kio/global.h).
- KMimeType::patterns() ➙ QMimeType::globPatterns()
- KMimeType::allMimeTypes() ➙ db.allMimeTypes()
- KMimeType::comment and KMimeType::iconName no longer take a KUrl argument. If you were passing such an argument (to support .directory files in directories), port the code to KFileItem::mimeComment and KFileItem::iconName.
The following fake MIME types have been removed and should be replaced as follows:
- all/allfiles ➙ application/octet-stream
- all/all ➙ application/octet-stream+inode/directory
- uri/{mms,mmst,mmsu,pnm,rtspt,rtsptu} ➙ x-scheme-handler/...
Config
- KConfig and KDesktopFile have been ported to QStandardPaths. This changes the "const char* resourceType" in the API into QStandardPaths::StandardLocation, and means that modifying the "config" resource before using KConfig has no effect on KConfig anymore.
- KConfigBase::sync now returns a bool
- KCoreConfigSkeleton::writeConfig now returns a bool
- KCoreConfigSkeleton::usrWriteConfig now returns a bool
- kde4_add_kcfg_files, used in the build system to generate code from KConfigXT files, should be changed to kconfig_add_kcfg_files.
- If you want the config files placed in the correct location instead of being mixed up with other stuff, make sure you have QCoreApplication::setOrganizationDomainName() call that sets the correct name for your application.
Encoding
KEncodingDetector is removed, port to KEncodingProber.
Porting guide:
KEncodingDetector detector -> KEncodingProber prober enum KEncodingDetector::AutoDetectScript -> enum KEncodingProber::ProberType detector.encoding() -> prober.encoding() detector.visuallyOrdered() -> check prober.encoding() hebrew detector.autoDetectLanguage() -> prober.proberType() detector.setAutoDetectLanguage(script) -> prober.setProberType(proberType) detector.decode(data) -> prober.feed(data) + QTextCodec::codecForName(prober.encoding())->toUnicode(data) detector.decodeWithBuffering(data, len) -> prober.feed(data1), feed(data2), feed(data3) + check prober.state() + QTextCodec::codecForName(prober.encoding())->makeDecoder() detector.decodedInvalidCharacters() -> QTextCodec::codecForName(prober.encoding())->makeDecoder() + hasFailure() detector.resetDecoder() -> prober.reset() detector.flush() -> prober.feed(data1), feed(data2), feed(data3) + QTextCodec::codecForName(prober.encoding())->toUnicode KEncodingDetector::scriptForName(lang) -> KEncodingProber::proberTypeForName(lang) KEncodingDetector::nameForScript(script) -> KEncodingProber::nameForProberType(proberType) KEncodingDetector::hasAutoDetectionForScript(script) -> if (proberType == KEncodingProber::None) ... else ... KEncodingProber::encodingName() is removed, use KEncodingProber::encoding() instead.
The following functions have been moved into khtml with the original KEncodingDetector class. khtml is the only user of them.
enum KEncodingDetector::EncodingChoiceSource -> removed KEncodingDetector::setEncoding(encoding, choice) -> removed, implement it in khtml code KEncodingDetector::encodingChoiceSource() -> removed
Localization
KLocale has been deprecated and moved to kde4support, with its features split between QLocale and KLocalizedString:
- For translation support, use KLocalizedString (ki18n framework).
- For string formatting, use QLocale, or KFormat from the KCoreAddons framework when QLocale does not provide the formatting you need.
- For localized string comparison, KStringHandler::naturalCompare() is deprecated in kdelibs4support, use QCollator instead.
The formating/parsing functions of KLocale have been replaced by QLocale:
- Replace all uses of "KGlobal::locale()" with "QLocale()", e.g.:
// KDE4
QString string = KGlobal::locale().formatDate(myDate);
// KF5
QString string = QLocale().toString(myDate);
- Replace all uses of KGlobal::setLocale() with QLocale::setDefault(myLocale)
- QLocale does not allow changing of default formats, i.e. with KLocale you could call "KGlobal::locale()->setDateFormat("%y-%M-%d")" to change the applications default date format, you cannot do this with QLocale. You must use the standard QLocale custom formatters each time, e.g. "QLocale().toString("yyyy-MM-dd)", or set a new application default QLocale using "QLocale::setDefault()".
- QLocale formatter/parser methods are named as toString()/toDate() pairs rather than formatDate()/readDate() pairs as in KLocale, and take different enum or format strings. See the QLocale docs for full details.
- QLocale date and time formatting does not use the POSIX format codes like "%y-%M-%d", you need to use the Qt format codes like "yyyy-MM-dd" instead.
- QLocale does not have an option for formatByteSize(), FancyDate, formatDuration(), or prettyFormatDuration(), use KCoreAddons::KFormat instead.
- int KLocale::pageSize() ➙ QPageSize QPrinterInfo::defaultPageSize() (since Qt 5.3) - Note this gives you the default paper size for any installed printer, but may not work if there is no printer installed. It is preferable to check the QLocale().measurementSystem(), if it is QLocale::ImperialUSSystem then use QPageSize::Letter, otherwise use QPage::SizeA4.
Translations
Translations are now entirely handled in the Ki18n library, primarily the KLocalizedString class.
- Translation catalogs are no longer dynamically inserted, so the idiom KGlobal::locale()->insertCatalog("somecatalog") is no longer available. To simply make the code build, for the sake of porting other things first, just remove or comment out these calls. This will stop translations from working, and to fully port them eventually, follow the section "Connecting Calls to Catalogs" in ki18n programmer's guide.
- i18n*() functions no longer handle KUIT markup. If you use KUIT markup, use the new xi18n*() functions.
Date / Time
KDateTime, KCalendarSystem, KLocalizedDate, KTimeZone and other related classes have been deprecated and moved to kde4support. Use QDateTime and QTimeZone instead. KCalendarSystem has yet to be replaced by QCalendarSystem (planned for Qt 5.7?), the few places that require this must use kde4support or wait for QCalendarSystem.
Replace all instances of KDateTime with QDateTime. The KDateTime api was deliberately very similar to QDateTime, so most method names will be unchanged, but the enums they take, and the constructors, are different:
- The KDateTime::Spec class should be removed and the KDateTime::SpecType replaced with Qt::TimeSpec. This may need some careful investigation, but most users of KDateTime do not use this feature.
- KDateTime::ClockTime has no direct Qt::TimeSpec equivalent, but Qt:LocalTime is effectively the same
- KDateTime::LocalZone has no direct Qt::TimeSpec equivalent, instead just use Qt::TimeZone with the QTimeZone::systemTimeZone().
- KDateTime::Invalid has no Qt::TimeSpec equivalent.
- The KDateTime::TimeFormat enum is replaced with Qt::DateFormat
- KDateTime::RFCDate and KDateTime::RFCDateDay are replaced by Qt::RFC2822Date, fromString() will accept with or without the day name, toString() does not write the day name so will need to be manually added.
- KDateTime::ISODate supported "simplified" and other variant ISO dates like YYYYMMDD, that Qt does not.
- KDateTime::RFC3339Date is replaced by Qt:ISODate.
- KDateTime::QtTextDate is replaced by Qt::TextDate, but should never be used.
- KDateTime::LocalDate is replaced by Qt::LocalDate, but is deprecated and should never be used. Use QLocale methods instead.
- The date/time string formats are changed from the POSIX standard (such as "%y %M %d") to the Qt standard which is a hybrid of CLDR and Windows (e.g. "yyyy MM dd").
- Replace all calls to the KDateTime or QDateTime toString()/fromString() using the format strings to use the QLocale equivalents instead to ensure that the local calendar system is used.
Method changes:
- utcOffset() => offsetFromUtc()
- isClockTime() => (qdt.timeSpec() == Qt::LocalTime)
- isLocalZone() => (qdt.timeSpec() == Qt::LocalTime) or (qdt.timeZone() == QTimeZone::systemTimeZone())
- isOffsetFromUtc() => (qdt.timeSpec() == Qt::OffsetFromUTC)
- isUtc() => (qdt.timeSpec() == Qt::UTC)
- int secsTo(KDateTime) => QDateTime returns qint64 instead of int
- qint64 secsTo_long(KDateTime) => Use secsTo() instead
- setTime_t(qint64) => QDateTime version takes a uint, perhaps use setMSecsSinceEpoch() if it matters
- toClockTime() => toLocalTime()
- toLocalZone() => toLocalTime() or toTimeZone(QTimeZone::systemTimeZone())
- toOffsetFromUtc() => qdt.toOffsetFromUtc(qdt.offsetFromUtc())
- toUtc() => toUTC()
- toZone() => toTimeZone()
- KDateTime::currentLocalDateTime() => QDateTime::currentDateTime()
- KDateTime::currentUtcDateTime() => QDateTime::currentDateTimeUtc()
Unsupported methods / features
- KDateTime::dateTime() and KDateTime::setDateTime() - No longer required, use the QDateTime instance directly.
- KDateTime::Comparison and KDateTime::compare() - QDateTime does not have an equivalent.
- KDateTime::isDateOnly() and KDateTime::setDateOnly() - QDateTime does not have a "Date Only" mode, use QDate instead, or a QDateTime with a time of 00:00:00 instead.
- KDateTime::isSecondOccurrence() and KDateTime::setSecondOccurrence() - QDateTIme does not as yet have proper second occurrence support.
- KDateTime::detach() is no longer required, QDateTime manages this itself.
- KDateTime::setSimulatedSystemTime and KDateTime::setFromStringDefault() - QDateTime does not a time simulation testing facility.
KDEUI Changes
Application
KApplication and KUniqueApplication are replaced with QApplication
Make sure to:
- Call void KAboutData::setApplicationData(const KAboutData &aboutData)
or separately:
- Call QCoreApplication::setApplicationName("...")
- Call QCoreApplication::setApplicationVersion("...") (from the old KAboutData object)
- Call QCoreApplication::setOrganizationDomain("kde.org")
- Call QGuiApplication::setApplicationDisplayName(i18n("...")) for GUI programs
- Call QGuiApplication::setDesktopFileName("...") for GUI programs
Make sure that the desktop file name set directly or via KAboutData matches the desktop file name (without file extension) installed for the program. This property is used by shells like Plasma to access more metadata about a running program which is stored in its desktop file.
- Call QGuiApplication::setWindowIcon(QIcon::fromTheme("...")) for GUI programs (needed by shells not using desktop file to retrieve app metadata)
- Use KDBusService for DBus registration, and optional "unique" behavior. Use also the "NoExitOnFailure" flag, unless unsuited.
- Important: if you create a QApplication (instead of KApplication) after using KCmdLineArgs, do not pass argc and argv to it, but KCmdLineArgs::qtArgc() and KCmdLineArgs::qtArgv(). This can go away when porting away from KCmdLineArgs.
Also adapt in the .desktop file of the program the "Exec=" entry:
- replace "-caption" with "-qwindowtitle" (supported by QGuiApplication)
- remove "%i" (not supported by any Q*Application)
If your program should work as a D-Bus activatable service, the base name of the D-Bus service description file or of the desktop file you install must match the D-Bus "well-known name" for which the program will register. For example, KDBusService will use a name created from the reversed organization domain with the component name attached, so for an organization domain "bar.org" and a component name "foo" the name of an installed D-Bus service file needs to be "org.bar.foo.service" or the name of the installed desktop file "org.bar.foo.desktop".
For still supporting the deprecated start of services via KToolInvocation, the desktop file needs to have an entry with the key "X-DBUS-ServiceName" and a value which matches the used D-Bus "well-known name" as just described, so with the above used values it needs a line "X-DBUS-ServiceName=org.bar.foo"
If you adopt the desktop file name for being D-Bus activatable, make sure to also update the value set for the desktopFileName application data property (see above). With the given example, it would accordingly be set to "org.bar.foo".
For standard purposes, it is recommended to use a desktop file name which uses an organization domain. So if without one yet and unless the desktop file name is bound to its current name (e.g. by respective D-Bus well-known name being in use), consider renaming it (and then adapting all related data). The appdata file should have the same name for consistency.
General
- KColorDialog: Use QColorDialog instead.
- KLineEdit: Two choices:
- Use QLineEdit instead, setClickMessage(...) becomes setPlaceholderText(...), setClearButtonShown(...) becomes setClearButtonEnabled(...). showClearButton property becomes clearButtonEnabled. clearButtonClicked() signal isn't available, connect to textChanged(const QString & text) and check if text.isEmpty(). (Use kde-dev-scripts/kf5/convert-klineedit.pl to automate most of the conversion. )
- Use KLineEdit from the kcompletion framework.
- KIntValidator: Use QIntValidator instead, the only difference was that KIntValidator attempted to support non-decimal bases (but it was broken with prefix and suffix texts, and therefore unused in KDE SC)
- KIntSpinBox: Use QSpinBox instead (Make sure to set minimum/maximum as needed! The defaults are 0-99). If using KIntSpinBox::setSuffix() with ki18n use KPluralHandlingSpinBox.
- KDoubleValidator: Use QDoubleValidator instead (as part of KLocale -> QLocale)
- KFloatValidator: Use QDoubleValidator instead (drop-in replacement)
- KSvgRenderer: Use QSvgRenderer instead (drop-in replacement)
- KCursor: Use QCursor instead
- KToolBar::applySettings and KMainWindow::applyMainWindowSettings don't take a "bool force" as second argument anymore (it was unused since KDE3 anyway)
- the virtual method KMainWindow::queryExit doesn't exist anymore. Either use queryClose/closeEvent for things that should be done for every window (or simply if there's only ever one window), or connect to QCoreApplication::aboutToQuit for things that should only be done once on shutdown.
- KIdentityProxyModel: Removed, used QIdentityProxyModel instead (trivial search/replace)
- Other proxy models: Moved to the KItemModels framework
- KPassivePopup: standardView() now returns a QWidget* instead of a KVBox*. The QWidget has a QVBoxLayout, i.e., additional widgets can be appended by calling widget->layout()->addWidget().
- KCodecAction: use enum KEncodingProber::ProberType instead of enum KEncodingDetector::AutoDetectScript
- KXMessages: the "obsolete = false" argument has been removed from all methods, and int screen has a default value of -1 now. Remove the "-1, false" in all calls. The sendMessage and sendMessageX methods were apparently unused, and have been commented out. Email kde-frameworks-devel at kde.org if you need them back.
- KNotification: setComponentData(KComponentData) is now setComponentName(QString), only the component name was used.
- KUndoStack: Use QUndoStack with KUndoActions::createUndoAction() and KUndoActions::createRedoAction() instead
- KRichTextWidget: createActions() does not take any KActionCollection and returns a list of QAction instead. You could use KActionCollection.addActions(KRichTextWidget.createActions()) instead.
- KTextBrowser: Use QTextBrowser instead. The only difference is QTextBrowser does not support "whatsthis:" urls. (Use kde-dev-scripts/kf5/convert-ktextbrowser.pl to automate most of the conversion. )
- KTextEditInterface: This was a hack to preserve the ABI. Please use the methods in KTextEdit instead.
- KTimeZoneWidget: Was copied as K4TimeZoneWidget in KDE4Support framework. A new KTimeZoneWidget replacement might appear so we freed the name.
- KIcon: has been deprecated and moved to kde4support, prefer QIcon. Port KIcon("foo") to QIcon::fromTheme("foo") and KIcon("foo", iconLoaderPtr) to QIcon(new KIconEngine("foo", iconLoaderPtr)) using KIconEngine from the KIconThemes framework. Note: XDG_DATA_DIRS has to be set to allow icons to be found. (Use kde-dev-scripts/kf5/convert-kicon.pl to automate most of the conversion. )
- KPixmapSequence now can only be instanced with a fullPath, to use XDG icons use KIconLoader::loadPixmapSequence.
- KLed: Several protected virtual methods to override painting got removed. If you need custom painting, override paintEvent() instead.
- Use QKeySequence instead of KShortcut to set shortcuts in actions.
- KInputDialog: use QInputDialog instead, with a relevant difference the returned value: QInputDialog allows empty input and it is not possible to define a validator. Ensure that the returned value is checked if an empty value is not acceptable.
- KPushButton::setGuiItem(const KGuiItem&): use QPushButton and KGuiItem::assign(QPushButton *button, const KGuiItem &item) (details)
Global Settings
- KGlobalSettings::contextMenuKey is gone, reimplement QWidget::contextMenuEvent() instead.
- KGlobalSettings::*Font methods are deprecated. Use QFontDatabase::systemFont(...). ::menuFont, ::taskBarFont and ::toolBarFont are not available now (they are provided by the QPA but not public API). If cases needing those arise we'll have to find an alternative
- KGlobalSettings::naturalCompare is deprecated, you'll have to specifically read the settings:
KConfigGroup g( KSharedConfig::openConfig(), "KDE" ); m_naturalSorting = g.readEntry("NaturalSorting", true);
Message Box
KMessageBox is no longer a class, but a namespace, as it only had static methods. The KMessageBox namespace spans now in two frameworks:
- Queued methods are deprecated and moved to kdelibs4support as kmessagebox_queued.h
- All other methods are in kwidgetsaddons as kmessagebox.h
Other changes:
- setDontShowAskAgainConfig was renamed to setDontShowAgainConfig
- KMessageBox methods now return enums instead of ints. While code using int will continue to build, you are encouraged to switch to enums for better type safety.
- KMessageBoxMessageHandler is deprecated and moved to kdelibs4support
Action
- KActionCollection and KXMLGUIClient: replace setComponentData with setComponentName and setComponentDisplayName
- KAction is deprecated now, use QAction or QWidgetAction. (Use kde-dev-scripts/kf5/convert-kaction.pl to automate most of the conversion. )
- Shape and rocker gestures are now handled by KGestureMap. The existing KAction methods related to gesture handling delegate to KGestureMap.
- KAction global shortcut handling logic moved to KGlobalAccel. So the KAction::globalShortcutChanged signal was removed and a new corresponding KGlobalAccel::globalShortcutChanged has been added. The signal semantics have not changed.
Gesture
- KGestureMap changes:
- addGesture renamed to setShapeGesture and setRockerGesture and now allow replacing existing gestures. When this occurs, a warning is traced with qDebug.
- new setDefault[Shape|Rocker]Gesture methods allow defining default gestures for an action, providing the functionality removed from KAction.
- new shapeGesture and defaultShapeGesture methods retrieves already defined shape gestures for a given action
- new rockerGesture and defaultRockerGesture methods retrieves already defined rocker gestures for a given action
Event Filter
- KSystemEventFilter was removed as Qt 5 uses XCB instead of XLib. To get the same functionality derive from QAbstractNativeEventFilter, filter XCB events and register the filter in the QCoreApplication:
class MyXcbEventFilter : public QAbstractNativeEventFilter
{
public:
MyXcbEventFilter()
{
QCoreApplication::instance()->installNativeEventFilter(this);
}
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long int*) Q_DECL_OVERRIDE
{
if (eventType != "xcb_generic_event_t") {
// only interested in XCB events
return false;
}
auto *event = static_cast<xcb_generic_event_t*>(message);
switch (event->response_type & 0x80) {
case XCB_KEY_PRESS:
auto *keyEvent = reinterpret_cast<xcb_key_press_event_t*>(event);
// handle key press event...
return true;
case XCB_KEY_RELEASE:
// ...
}
return false;
}
};
Dialog
- KDialog: It has been deprecated and moved to kde4support. Port to QDialog + QDialogButtonBox. The script in kde-dev-scripts/kf5/convert-kdialog.pl can help.
KCharSelect
- KCharSelect: To allow the user to select characters outside the Unicode BMP, you must setAllPlanesEnabled(true) and port to the uint-based methods and signals (available since version 5.25):
- QChar currentChar() ➙ uint currentCodePoint()
- setCurrentChar(QChar) ➙ setCurrentCodePoint(uint)
- charSelected(QChar) ➙ codePointSelected(uint)
- currentCharChanged(QChar) ➙ currentCodePointChanged(uint)
To convert between uint code points and QString, use QString::fromUcs4() and QString::toUcs4():
...
Q_SLOTS:
void codePointSelected(uint code) {
QString selected = QString::fromUcs4(&code, 1);
...
}
...
You can also manually do the surrogate pair handling.
Style
In styles based on KStyle, this will work out of the box.
- KStyle: Was copied as K4Style in KDE4Support framework. New KStyle class has been trimmed down and reimplements only necessary methods to enforce some of the user settings (for example icons). K4Style users should use K_EXPORT_K4STYLE instead of K_EXPORT_STYLE
Toolbar
- ToolBar has moved to XMLGUI. If you don't want to depend on XMLGUI, use QToolBar instead, with the following setup:
- Set ToolButtonStyle to Qt::ToolButtonFollowStyle, this will make QToolBar use the settings for "Main Toolbar"
- Additionally set QToolBar::setProperty("otherToolbar", true) to use settings for "Other toolbars"
- Settings from "Other toolbars" will only work on a widget style that derives from KStyle
QToolBar *toolbar = new QToolBar();
toolbar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
toolbar->setProperty("otherToolbar", true);
Font Dialog
- Use QFontDialog instead of KFontDialog. Notice that, in the case of KFontDialog::getFont vs QFontDialog::getFont, QFontDialog::getFont returns the selected font instead of the dialog code, and the Accept/Cancel value is returned through a pointer to a boolean value that is passed as the first argument. Also, notice that the flags for KFontDialog::getFont (defined at KFontChooser::DisplayFlag) do not map to those of QFontDialog::getFont (defined at QFontDialog:: FontDialogOptions) and serve a different purpose.
- It should be noted that QFontDialog does not support the deactivation of the style list. If necessary, KFontChooser is a better alternative.
Window Systems
KWindowSystem changes:
- NETWinInfo2 class got removed. All methods are merged into NETWinInfo. Use NETWinInfo instead of NETWinInfo2.
- NETRootInfo and NETWinInfo use xcb datatypes instead of XLib datatypes. Inheriting classes need to adjust the method arguments.
- Constructor of NETRootInfo and NETWinInfo expect an xcb_connection_t* instead of Display*.
- Constructor of NETRootInfo and NETWinInfo no longer take an array for properties, but dedicated flag types.
- Method NETRootInfo::screenNumber has been removed.
- NETRootInfo, NETWinInfo, KWindoInfo and KWindowSystem adjusted to use flag types instead of unsigned long int for the flags. This includes virtual method NETWinInfo::changeState.
- NETWinInfo::event(xcb_generic_event_t*) returns NET::Properties
- NETWinInfo::passedProperties returns NET::Properties and a new NETWinInfo::passedProperties2 is added which returns the NET::Properties2
- NETRootInfo::event(xcb_generic_event_t*) returns NET::Properties
- NETRootInfo::passedProperties returns NET::Properties and new methods for Properties2, WindowTypes, States and Actions are added
- NETRootInfo::supportedProperties returns NET::Properties and new methods for Properties2, WindowTypes, States and Actions are added.
- Desktop argument in NETRootInfo::desktopGeometry() and NETRootInfo::setDesktopGeometry() has been removed.
Printing
KDE's print support which added extra features to the Qt print dialog has been deprecated and moved to kdelibs4support. All the extra features have been added to Qt.
- For Qt printing support you will need to link to Qt5::PrintSupport.
- KPrintPreview is replaced by QPrintPreview
- KdePrint::createPrintDialog() is replaced by QPrintDialog
Examples:
// KDE4 style
QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, parent);
// KF5 style
QPrintDialog *printDialog = new QPrintDialog(&printer, 0);
// KDE4 style, adding custom widgets
QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, customWidgetList, parent);
// KF5 style, adding custom widgets
QPrintDialog *printDialog = new QPrintDialog(&printer, 0);
printDialog->setOptionTabs(customWidgetList);
// KDE4 style, setting server-side page selection
QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, KdePrint::SystemSelectsPages, parent);
// KF5 style, tell Qt you don't do client-side page selection, it will do server-side if supported
QPrintDialog *printDialog = new QPrintDialog(&printer, 0);
printDialog->setOption(QPrintDialog::PrintPageRange, false);
KIO Changes
- The very common job->ui()->setWindow(widget) has to be ported to KJobWidgets::setWindow(job, widget), because job->ui() is now only a KJobUiDelegate.
- The deprecated KIO::Job::showErrorDialog() has been removed, use KJobWidgets::setWindow(job, parent) and job->ui()->showErrorMessage()
- The KFileItem API has been ported to QMimeType. As a consequence, mimeTypePtr() is now currentMimeType().
- KFileItem::run(QWidget*) has disappeared, due to core/gui separation. Use new KRun(item.targetUrl(), widget) instead.
- KFileItem::pixmap(size, state=0) has disappeared, due to core/gui separation. If you can, use KDE::icon(item.iconName(), item.overlays(), 0) instead. If you really need a QPixmap, e.g. for showing in a QLabel, use this instead:
KIconLoader::global()->loadMimeTypeIcon(item.iconName(), KIconLoader::Desktop, size, state);
- KIO::pixmapForUrl has moved from kio/global.h to kio/pixmaploader.h (so that global.h is core only)
- KProtocolInfo::isHelperProtocol() and exec() no longer detect apps associated with x-scheme-handler/*. This has moved up to KRun. Therefore KProtocolInfo is again about .protocol files only.
- KIO::RenameDialogPlugin was removed, it was unused for a long time anyway. The rename dialog uses KFileMetaDataWidget and PreviewJob instead.
- When Job::setUiDelegate(0) is used on a CopyJob (KIO::copy or KIO::move), an extra call to setUiDelegateExtension(0) is probably necessary, to disable skip and rename dialogs.
- KIO::Job::isInteractive() has been removed, use uiDelegate() or uiDelegateExtension() depending on what is meant (error messages, or rename/skip dialog).
- KIO::http_update_cache() now takes a QDateTime instead of a time_t, you can use QDateTime::fromTime_t if you need to
- The "resume" and "resume_until" metadata keys have been renamed to "range-start" and "range-end".
- KBookmark and assorted classes are now in a separate framework, kbookmarks. One API change is that KBookmarkDialog::addBookmark now takes a QString icon (to remove a dependency on KIO::iconNameForUrl). Instead, the caller is recommended to call KIO::iconNameForUrl himself (from the header kio/global.h).
- KIO::NetAccess is deprecated, use KIO::get or similar functions and ->exec() the returned job object.
KFile Changes
- libkfile is now called KIOFileWidgets, part of the KIO framework.
- KFileWidget no longer inherits KAbstractFileWidget (which no longer exists). KAbstractFileWidget::{OperationMode, Other, Opening, Saving} is now KFileWidget::{...}
KParts Changes
- With the port from KUrl to QUrl in APIs, the signature of the virtual method openUrl has changed, make sure to port your reimplemented methods to QUrl!
- TerminalInterfaceV2 has been merged into TerminalInterface, you can remove the "V2" everywhere (classname, interface name).
- The installed normal lowercase headers no longer define multiple classes. Now it is only one class per header, with the filename matching the classname (e.g. KParts::ReadOnlyPart is no longer defined in <kparts/part.h> but <kparts/readonlypart.h>). So make sure you now include the matching headers.
ItemViews Changes
- KCategoryDrawer margins should be set by overriding the leftMargin/rightMargin methods as appropriate.
- KWidgetItemDelegate::createItemWidgets now has an QModelIndex with the index to create widgets for. It does not need to be used
KArchive Changes
- KFilterBase::findFilterByFileName and KFilterBase::findFilterByMimeType are gone, now you should use KCompressionDevice::filterForCompressionType
- To get the CompressionType you can call KFilterDev::compressionTypeForMimeType
- KFilterDev::device is deprecated, instead you should use:
KCompressionDevice::CompressionType type = KFilterDev::compressionTypeForMimeType(mimeType);
KCompressionDevice flt(&file, false, type);
- KFilterDev::deviceForFile is deprecated, instead you should use:
KFilterDev dev(fileName)
KEmoticons Changes
- KEmoticonsProvider::save is deprecated, instead you should use KEmoticonsProvider::saveTheme
- KEmoticonsTheme::save is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::saveTheme
- KEmoticonsProvider::createNew is deprecated, instead you should use KEmoticonsProvider::newTheme
- KEmoticonsTheme::createNew is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::newTheme
- KEmoticonsProvider::addEmoticonsMap is deprecated, instead you should use KEmoticonsProvider::addMapItem
- KEmoticonsProvider::removeEmoticonsMap is deprecated, instead you should use KEmoticonsProvider::removeMapItem
- KEmoticonsProvider::addEmoticonIndex is deprecated, instead you should use KEmoticonsProvider::addIndexItem
- KEmoticonsProvider::removeEmoticonIndex is deprecated, instead you should use KEmoticonsProvider::removeIndexItem
- KEmoticonsTheme::loadTheme is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::loadTheme
- KEmoticonsTheme::addEmoticon is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::addEmoticon
- KEmoticonsTheme::removeEmoticon is deprecated, instead you should subclass KEmoticonsProvider and implement the pure virtual method KEmoticonsProvider::removeEmoticon
KDNSSD Changes
- The include paths have changed from dnssd to kdnssd
- The namespace has changed from DNSSD to KDNSSD
KNewStuff3 Changes
- The include paths has changed from knewstuff3 to kns3 (Use kde-dev-scripts/kf5/adapt_knewstuff3_includes.pl to automate most of the conversion. )
KUnitConversion Changes
- KUnitConversion is now a separate Tier 2 Framework, you need to link to KF5::UnitConversion
- The Convertor, CategoryUnit, Unit and Value classes are all now standard Qt shared data containers, i.e. like QString. Each class is either implicitly or explicitly shared as appropriate, and should be passed by const references. The main impact of this is that existing code will need to change from calling of methods from -> to . notation.
- The api now uses the enums instead of int
- The api now uses qreal instead of double
- The custom constructors and protected setters have been removed. If you require adding custom units, please contact the maintainer to discuss.
Plasma Changes
libplasma has been replaced with libplasma2. See the libplasma2 porting notes. Plasma themes specifications has seen small changes as well (intended and unintended) . See the Theme porting notes.
Docbook Documentation Changes
DocBook XML schema
The DocBookXML schema used by the documentation has changed; the custom KDE DTD is now based on version 4.5 (previously was 4.2). The change is almost painless (and should be completely painless for applications using KDE4Support). You need to change the DOCTYPE declaration as follows:
--- <!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
+++ <!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
(The changes are "V4.2" to "V4.5" and "dtd/kdex.dtd" to "dtd/kdedbx45.dtd").
Document processing macros
CMake document processing macros have been renamed from prefix kde4_
to prefix kdoctools_
. The DocTools
component must be loaded to use them.
KAuth Changes
- KDE4_AUTH_HELPER_MAIN should be replaced by KAUTH_HELPER_MAIN
KTextEditor Changes
Changes to the KTextEditor Interfaces are documented in the API documentation: http://api.kde.org/frameworks-api/frameworks5-apidocs/ktexteditor/html/kte_port_to_5.html
KNotifications Changes
- KNotifications lets you set a default sound for notifications. Typically for KDE applications these were sounds shipped by kde-runtime. These should be changed to files shipped by Plasma 5. This is the same as the kde-runtime sound theme but with files renamed to start with Oxygen- instead of KDE-. You will need to update your .notifyrc file for this, e.g. Sound=KDE-Sys-Log-Out.ogg is now Sound=Oxygen-Sys-Log-Out.ogg
Solid Changes
Interfaces
- DvbInterface: We only supported linux plus usually this is used together with a multimedia framework. Users of this interface will be better suited using that multimedia framework to get a list of devices.
- Video: We only supported linux plus usually this is used together with a multimedia framework. Users of this interface will be better suited using that multimedia framework to get a list of devices.
- Button: New Async api will be added to announce button availability and state.
- NetworkInterface: Use QNetworkConfigurationManager.
- InternetGateway: This class mattered only for UPnP, we never had proper UPnP support so if you were using this just remove any usage.
- SerialInterface: You can use UdevQt (you can find that inside Solid) for the time being. New api will be added to QtSerialport.
- AudioInterface: We were only supporting Alsa here, if you were using this either use Alsa directly or UdevQt.
- SmartCardReader: This was not even working since we moved from HAL (4 years ago). If you are using this please remove any usage of it.
Solid Networking
QNetworkConfigurationManager does most of the things Solid/Networking did.
Solid Powermanagement
New async api will be added, W.I.P
Sonnet Changes
The only big change from an API consumer standpoint is that it was ported away from KConfig, and also lost the ability to set per-application settings, for now. It's on my todolist to bring it back, but if someone else wants to implement it feel free (one semi-big gotcha will be to avoid exposing QSettings directly, as the QSettings codebase is a mess and we might want to port away from it in the future, without impacting applications that use Sonnet).
libkonq
-
KonqMimeData::populateMimeData(mimeData, kdeUrls, mostLocalUrls, cut) is now
KIO::setClipboardDataCut(mimeData, cut); KUrlMimeData::setUrls(kdeUrls, mostLocalUrls, mimeData);
or if one of the two URL lists was always empty, just mimeData->setUrls(urls);
- KonqMimeData::addIsCutSelection(mimeData, cut) is now KIO::setClipboardDataCut(mimeData, cut);
- KonqMimeData::decodeIsCutSelection is now KIO::isClipboardDataCut.
- KonqStatusbarMessageLabel has moved back to konqueror, its only user.
- KonqFileItemCapabilities and KonqPopupMenuInformation were removed, use KFileItemListProperties from KIO.
- KonqMenuActions was removed, use KFileItemActions from KIO.
- KNewMenu was removed, use KNewFileMenu from KIO.
-
KonqOperations::restoreTrashedItems should be replaced with
KIO::RestoreJob *job = KIO::restoreFromTrash(urls); KJobWidgets::setWindow(job, m_mainWindow); job->uiDelegate()->setAutoErrorHandlingEnabled(true); // or connect to the result signal
- KonqOperations::emptyTrash should be replaced with
KIO::JobUiDelegate uiDelegate; uiDelegate.setWindow(m_mainWindow); if (uiDelegate.askDeleteConfirmation(QList<QUrl>(), KIO::JobUiDelegate::EmptyTrash, KIO::JobUiDelegate::DefaultConfirmation)) { KIO::Job* job = KIO::emptyTrash(); KJobWidgets::setWindow(job, m_mainWindow); job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal }
It's a bit more verbose, but you can choose how you want to ask confirmation and how you want to handle errors.
- KonqOperations::askDeleteConfirmation should be replaced with uiDelegate.askDeleteConfirmation as in the example above.
- KonqOperations::del should be replaced with
KIO::JobUiDelegate uiDelegate; uiDelegate.setWindow(m_mainWindow); if (uiDelegate.askDeleteConfirmation(urls, KIO::JobUiDelegate::Trash or Delete, KIO::JobUiDelegate::DefaultConfirmation)) { KIO::Job* job = KIO::del(urls); // or KIO::trash(urls) // after KIO::trash, add this for undo/redo support: // KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::Trash, urls, KUrl("trash:/"), job ); KJobWidgets::setWindow(job, m_mainWindow); job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal }
- KonqOperations::copy should be replaced with
KIO::CopyJob* job = KIO::copy(selectedUrls, destUrl); // or KIO::move, or KIO::link KIO::FileUndoManager::self()->recordCopyJob(job); KJobWidgets::setWindow(job, m_mainWindow); job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal
- KonqOperations::mkdir should be replaced with
KIO::SimpleJob* job = KIO::mkdir(url); KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Mkdir, QList<QUrl>(), url, job); KJobWidgets::setWindow(job, m_mainWindow); job->ui()->setAutoErrorHandlingEnabled(true); // or connect to the result signal
- KonqOperations::newDir should be replaced with KNewFileMenu::createDirectory, which requires having a long-living instance, calling setParentWidget, and setPopupFiles first. See this gwenview commit for an example.
- KonqOperations::pasteInfo(destUrl) should be replaced with KIO::pasteActionText(QApplication::clipboard()->mimeData(), &enable, destItem)
Migrating configuration
Since KDE Frameworks 5.2, there is a convenience class in KCoreAddons (Kdelibs4ConfigMigrator) that can be used to migrate configuration files from 4.x applications (stored in KDEHOME/share/config) to the XDG_*_HOME used by KF5-based applications. As it will ensure that user-facing applications will not lose their settings once ported to KF5, hence usage is highly recommended (with some caveats: see below).
If you use it, you will have to link to KCoreAddons.
Running the migration is an one-time step, and you should put it directly in the main() function of your application, before instantiating QApplication:
#include <Kdelibs4ConfigMigrator>
// ... other code here
Kdelibs4ConfigMigrator migrator(QStringLiteral("myappname")); // the same name defined in the aboutData
// all the config files of your application
migrator.setConfigFiles(QStringList() << QStringLiteral("myapprc") << QStringLiteral("myotherconfigrc"));
// list of KXMLGUI files used by your application
migrator.setUiFiles(QStringList() << QStringLiteral("myappui.rc"));
migrator.migrate();
There is a caveat you should keep in mind: this code copies the files verbatim. In case you have adjusted your configuration files, don't forget to use a kconf_update script to ensure they are adjusted properly.
There is no need to check for the existence of the migrated files: if they are already present, the migration is skipped.