Porting Applications to KDE 4.0

Note

All modules should build from /trunk/KDE/kdelibs; there is no snapshot branch any longer. Major changes happen on Mondays (in any timezone) so expect rapid changes during that time. Things should be generally stable otherwise, but this is the development area, so there are no guarantees.

This document contains the changes you have to apply to programs written for KDE 3.x when you want to port them to KDE 4.0.
As a start you should have a look at doc/html/porting4.html in the Qt package, or this page online.

Table of Contents

Getting started

Return to the Table of Contents

Global Changes

Return to the Table of Contents

Changes in kab

Return to the Table of Contents

Changes in kdefx

KPixmap

Return to the Table of Contents

Changes in kdecore

Header file names

KAboutData

See also the I18N section below.

KAccel

KAccelAction

KAccelBase

KApplication

KAudioPlayer

Removed, use now Phonon::AudioPlayer

KCatalogue

KCharsets

KCodecs

KComboBox

KCompletion

KConfigBackend

KConfigBase

KConfigGroupSaver

The class KConfigGroupSaver has been deprecated, instead use KConfigGroup. The difference is a KConfigGroupSaver object directly affects the config object it is acting on, while a KConfigGroup object only ensures the entries read or written through it are in the correct group.

Instead of:
KConfig *config = KGlobal::config();
KConfigGroupSaver saver(config, "group name");
  ...
config->readXXX("entry name");
should be rewritten as:
KSharedConfig::Ptr config = KGlobal::config();
KConfigGroup cg(config, "group name");
  ...
cg.readXXX("entry name");

KCmdLineArgs

KDesktopFile

KExtendedSocket

KFilterDev

KGlobal

KGlobalAccel

KGlobalSettings

KIcon

KIconLoader

KInstance

KIPC

KKey

KKeyNative

KKeySequence

KLibFactory

KLocale

See also the I18N section below.

KMacroExpander

KMD5

KMimeSourceFactory

KNetwork::KResolver

KNetwork::K*Socket

KNotifyClient

KPalette

KPixmapSplitter

KProcess

KRegExp

KSaveFile

KShortcut

KShortcutList and derivatives

KSortableValueList

KStdAccel

KStandardDirs

KStringHandler

KStyle

KTempDir

KTempFile

KURL

KURLDrag

KVMAllocator

KWin

locate

NETRootInfo

Return to the Table of Contents

Changes in kdeui

KAboutContainer

KAboutContributor

KAboutDialog

KAboutWidget

KAction

Making KAction a subclass of QAction (actually QWidgetAction) brings KDE more into line with the Qt way of creating user interfaces, improves accessibility, and removes code duplication.

QAction in Qt4 is a true 1st class citizen - all QWidgets now have a list of associated actions, and QToolBar, QMenu etc. all use this list directly to show the graphical items (widgets, entries in the menu, etc). This has replaced all usage of integers as "id"s. There is also a new QEvent (QActionEvent), and the corresponding virtual protected function in QWidget, actionEvent().

KActionCollection

KActionSelector

KActionSeparator

KActiveLabel

KAnimWidget

KAuthIcon

KBugReport

KButtonBox

Replaced by KDialogButtonBox. Add the role parameter to the addButton function. Or check if it can't be achieved using KDialog

KCharSelectTable

KColorCells

KColorDrag

KConfigDialog

KContextMenuManager

KDatePicker

KDateTable

KDateWidget

KDialog

KDialogBase

KDockWindow

KDualColorButton

KEdit

KEditListBox

KGradientSelector

KGUIItem

KIcon

KInputDialog

KIntNumInput, KDoubleNumInput, KDoubleSpinBox

KJanusWidget

KKeyDialog

KKeyChooser

KLed

KLineEdit

KLineEditDlg

KListAction

KListBox

KMainWindow

KMainWindowInterface

KPassivePopup

KPasswordEdit

KPasswordDialog

KPasswordDialog dlg(parent);
dlg.setPrompt( prompt );
dlg.setWindowTitle( caption );
if( dlg.exec() != QDialog::Accepted )
    return;
use( dlg.password() );

KPixmapIO

KPopupMenu

KPopupTitle

KProgress

KProgressDialog

KPushButton

KRadioAction

KRecentFilesAction

KRootPixmap

KSelectAction

KHSSelector

KSeparator

KSessionManaged

KSharedPixmap

KStatusBar

KStandardAction

KStandardGuiItem

KSyntaxHighlighter

KSystemTray

KTabBar

KTabCtl

KTextBrowser

KTextEdit

KTimeWidget

KTimezoneWidget

KToggleAction

KToggleFullScreenAction

KToolBar

KToolBarButton

KToolBarLabelAction

KToolBarRadioGroup

KToolBarSeparator

KURLLabel

KValueSelector

KWidgetAction

KWindowListMenu

KWizard

Return to the Table of Contents

Changes in kio

KArchive/KTar/KZip/KAr

KBookmark classes

KDirLister class

KDESasl class

KFileDialog,KDirselectDialog,KUrlRequesterDlg,KCustomMenuEditor,KUrlBarItemDialog

KFileDialog, KFileView, KDirOperator

KFileDialog

KFileItemList

KFileMetaInfo

KFileOpenWithHandler

KIconButton

KIconDialog

KImageIO classes

KIO:: global methods

KIO::Job

KIO::UDSEntry

KIO::RenameDialog

KIO::RenameDialogPlugin

KIO::PasswordDialog

KIO::SkipDialog

KIO::Observer

KIO::SlaveBase

KMimeMagic

KMimeType

KMimeTypeResolver

KOpenWithDlg

KPropertiesDialog

KPropertiesDialogPlugin

KProtocolInfo

KRun

KURLBar

KURLCombo

KURLCompletion

KURLPixmapProvider

KURLRequester

KService

KServiceType

KServiceTypeProfile

KTrader

PasswordDialog

UIServer

Return to the Table of Contents

Changes in kparts

BrowserRun

ComponentFactory

Return to the Table of Contents

Changes in kded

Return to the Table of Contents

Changes in kspell

KSpell

Return to the Table of Contents

API-cleanups in KHTML

Return to the Table of Contents

Changes in kfile

KUrlRequesterDialog

Return to the Table of Contents

Changes in KControl

Return to the Table of Contents

Panel Applets and Extensions

Return to the Table of Contents

libkmid

KScreensaver

libkscreensaver

Return to the Table of Contents

I18N

Messages.sh files

Instead of the "messages" target of the Makefile.am files, KDE4 uses now Bash scripts with Messages.sh file names. The Perl script branches/work/kde4-l10n/scripts/conversion/Makefile2Messages.pl can be used as an half-automatic conversion. (Please verify the result!)

rc.cpp file

The rc.cpp is now always generated. It is mandatory to have it as parameter of the $XGETTEXT if you are using the class KAboutData and if you are not explicitly setting KAboutData::setTranslator.

Gettext 0.15-pre

Scripty uses xgettext 0.15-pre (the development version) for extracting messages out of code. This is a huge step from the former xgettext 0.10.35-kde used in KDE3.

Important changes:

i18n calls

The basic call, a message without arguments, context or plural, remains as is:

i18n("Just plain info");

If there are arguments, arg methods are no longer used to substitute the placeholders. Instead, arguments are added to the call:

i18n("%1 has scored %2", playerName, score);

Arguments can be of several integer types, double, QString, QChar (and perhaps more in the future).

Context call now has a different name, i18nc, and takes arguments in the same way:

i18nc("Player name - score", "%1 - %2", playerName, score);

Plural call is renamed to i18np and does away with %n placeholder, all being numbered instead:

i18np("One image in album %2", "%1 images in album %2", n, albumName);

The plural form is decided by first integer-valued argument.

There is one new call variant, the context-plural call:

i18ncp("Personal file", "One file", "%1 files", n);

i18n* calls are realized as templates, and so will take at most some finite number of arguments.

Notes on placeholder substitution:

Sometimes you might need old-style syntax for argument substitution. For example, when there are many arguments, or, more importantly, when it is convenient to defer substitution of arguments. This is possible using new ki18n call, with subs methods for argument substitution and toString method for finalization:

KLocalizedString ks = ki18n("The Foo-machine reported: %1");
case (fooErrCode) {
    ERR_OXI: ks.subs(i18n("Out of oxidizer")); break;
    ERR_HYD: ks.subs(i18n("Out of hydrazine")); break;
    ERR_PIL: ks.subs(i18n("Out of pilots")); break;
    default: ks.subs(i18n("Unknown catastrophe"));
}
QString scream = ks.toString();

Note that ki18n returns object of type KLocalizedString, hence the toString method for conversion to plain QString. The ki18n call should be used rarely; the previous example can as well be rewritten to:

QString problem;
case (fooErrCode) {
    ERR_OXI: problem = i18n("Out of oxidizer"); break;
    ...
}
QString scream = i18n("The Foo-machine reported: %1", problem);

Another case when you might want to use ki18n is if you want to format arguments. subs methods can take formatting arguments, similar to those of arg methods in QString. You should never use methods other than subs to format numbers in localized messages:

i18n("Rounds: %1", myNumberFormat(n, 8)); // bad, number not localized
ki18n("Rounds: %1").subs(n, 8).toString(); // good, number is localized

There is a context, plural and context-plural variant of ki18n as well:

ki18nc("No function", "None").toString();
ki18np("One file found", "%1 files found").subs(n).toString();
ki18ncp("Personal file", "One file", "%1 files").subs(n).toString();

If you need translation using locale (KLocale object) other than the default, you can use overloaded toString method which takes pointer to locale object (this replaces KLocale::translate(...) from KDE3):

KLocale *myLocale;
...
ki18n("Welcome").toString(myLocale);

There is a script for semi-automatic conversion of KDE 3 code, i18nk34conv.pl in branches/work/kde4-l10n/scripts/conversion/. It will convert most of the calls automatically, and mark the places that need manual review. There is also the script i18ncheckarg.pl in branches/work/kde4-l10n/scripts, which will check whether placeholders and arguments match. Use it to catch and correct deferred substitutions (like in the examples above). Both these scripts you can just run without any arguments in top directory of your sources (but you can also specify paths or filenames as arguments). Do not run conversion script twice on same sources!

Return to the Table of Contents

Changes in KSSL

KSSLCertDialog

KSSLInfoDialog

Return to the Table of Contents