Frameworks/Porting Notes

From KDE Community Wiki
Revision as of 00:26, 7 January 2014 by Kfunk (talk | contribs) (Add note where to find KIO::iconNameForUrl)

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.

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} ${ECM_KDE_MODULE_DIR})

and something approximating the settings provided with kdelibs 4 can be acheived by

include(KDEInstallDirs)
include(KDECompilerSettings)
include(KDECMakeSettings)
include(FeatureSummary)

TechBase has a list of source incompatible changes in ECM.

Other changes of significance include:

  • 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
  • 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 KInitMacros.cmake.

KDECore Changes

  • kdecore has been split up into a number of independent libraries: libkarchive, libkauth, libkdbus, etc.
  • 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)).
    • 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
  • 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)
  • 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.
  • 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.
  • KComponentData:
    • The class is in kde4support now. Port away from it. In your main(), just remove the instanciation, use QCoreApplication::setApplicationName and QCoreApplication::setApplicationDisplayName instead. 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.
  • KStandardDirs: see Frameworks/Porting_Notes/KStandardDirs for porting notes.
  • 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
  • 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.
  • KTempDir is deprecated, port to QTemporaryDir instead, see KTempDir API documentation for details.
  • KToolInvocation::invokeHelp is now KHelpClient::invokeHelp, in the kwidgets 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.
  • KMimeType is deprecated, port to QMimeType instead. Here's a 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(name, data_or_device) -> db.mimeTypeForNameAndData(name, 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()
  • KLocale has been split up: KLocale is now only about locale settings, while translation support has moved to KLocalizedString (ki18n framework). 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.
  • 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).
  • Make sure to call KAboutData::setApplicationData() from the main() of the application.
  • 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 orignal 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  
  • 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 factoiry changes are explained in this article.
  • KAuthorized::authorizeUrlAction and KAuthorized::allowUrlAction have been moved to a new KUrlAuthorized namespace.
  • KStringHandler::naturalCompare() is deprecated now, QCollator (QtCore) should be used from now on. If you still want the exact same old behavior, you can use it from kstringhandler_deprecated.h (KDE4Support),
  • KDebug is deprecated, use QDebug or QLogginCategory instead.
    • For non-categorized logging:
      • kDebug() -> qDebug()
      • kError() -> qCritical()
      • kFatal() -> qFatal()
      • kWarning() -> qWarning()
    • For categorized logging like kDebug(1221), see the kDebug -> qCDebug porting guide.

KDEUI Changes

  • KApplication/KUniqueApplication: use QApplication instead, but make sure to:
    • Call QCoreApplication::setApplicationName("...")
    • Call QCoreApplication::setApplicationVersion("...") (from the old KAboutData object)
    • Call QCoreApplication::setOrganizationDomain("kde.org")
    • Call QApplication::setApplicationDisplayName(i18n("...")) for GUI programs
    • Use KDBusService for DBus registration, and optional "unique" behavior
    • 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.
  • KLineEdit: Use QLineEdit instead, setClickMessage(...) becomes setPlaceholderText(...)
  • 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)
  • 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
  • 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.
  • KGlobalSettings::contextMenuKey is gone, reimplement QWidget::contextMenuEvent() instead.
  • KGlobalSettings::*Font methods are deprecated. Use QFontDatabase::systemFonts(). ::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 especifically read the settings:
         KConfigGroup g( KSharedConfig::openConfig(), "KDE" );     m_naturalSorting = g.readEntry("NaturalSorting", true);  
  • KMessageBox changes:
    • 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 now in kmessagebox_queued.h from kde4support framework
      • The remainder of the methods are now in kmessagebox.h from kwidgetsaddons
    • 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 moved to kde4support
  • KNotification: setComponentData(KComponentData) is now setComponentName(QString), only the component name was used.
  • KActionCollection and KXMLGUIClient: replace setComponentData with setComponentName and setComponentDisplayName
  • KAction is deprecated now, use QAction or QWidgetAction.
    • Shape and rocker gestures are now handled by KGestureMap. The existing KAction methods related to gesture handling delegate to KGestureMap.
  • 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
  • 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.
  • 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.
  • 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.
  • 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()-&gt;installNativeEventFilter(this);
    }
    virtual bool nativeEventFilter(const QByteArray &amp;eventType, void *message, long int*) Q_DECL_OVERRIDE
    {
        if (eventType != &quot;xcb_generic_event_t&quot;) {
            // only interested in XCB  events
            return false;
        }
        auto *event = static_cast&lt;xcb_generic_event_t*&gt;(message);
        switch (event-&gt;response_type &amp; 0x80) {
        case XCB_KEY_PRESS:
            auto *keyEvent = reinterpret_cast&lt;xcb_key_press_event_t*&gt;(event);
            // handle key press event...
            return true;
        case XCB_KEY_RELEASE:
            // ...
        }
        return false;
    }
};
  • KDialog: It has been deprecated and moved to kde4support. Prefer QDialog. Note that there Ctrl+Enter is not set by default for accepting dialogs, we'd suggest to add them explicitly, especially in cases where QTextEdit is used, since then it's very hard to accept the dialog without using the mouse. You can do so by using:
QDialogButtonBox* box = ...;
...;
button->setShortcut(Qt::CTRL | Qt::Key_Return);

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
  • KPixmapSequence now can only be instanced with a fullPath, to use XDG icons use KIconLoader::loadPixmapSequence.
  • 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);
  • 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*.
  • Method NETRootInfo::screenNumber has been removed.
  • Desktop argument in NETRootInfo::desktopGeometry() and NETRootInfo::setDesktopGeometry() has been removed.

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

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).

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(&amp;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 has changed from dnssd to kdnssd
* The namespace has changed from DNSSD to KDNSSD

Plasma Changes

libplasma has been replaced with libplasma2. See the libplasma2 porting notes.