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.
-
The "const char *name" arguments in the constructors of QObject derived classes
have been removed (not of all classes yet). Use setObjectName() instead if the object name is really necessary.
- The define KDE_DEPRECATED must be used now at the start of the declaration
(but still after an eventual "static", "inline" or "virtual" keyword).
KDE_DEPRECATED does not work with constructors, use KDE_CONSTRUCTOR_DEPRECATED
instead.
KPixmap
- Removed. Use QPixmap instead.
Header file names
- kuniqueapp.h => kuniqueapplication.h
- klargefile.h => kde_file.h
- kcatalogue.h => kcatalog.h
- kaccelmanager.h => kacceleratormanager.h
KAboutData
- KAboutData::setTranslator needs different parameters now.
(Please see the corresponding Doxygen comment for the current state.)
See also the I18N section below.
KAccel
- Removed. Replaced by the new KAction/QAction framework.
- See KActionCollection::setAssociatedWidget() if you need the old KAccel widget-binding behavior.
KAccelAction
- Removed. Replaced by the new KAction/QAction framework.
- [Old note] KDE3 supported 3 modifier key shortcuts and 4 modifier key (3+META) shortcuts, because earlier versions of Qt3 didn't
support a META modifier/WIN key. This is changed, so now all shortcuts can be 4 modifier key. All instances of
shortcut3 and shortcut4 have been reduced just to "shortcut".
- [Old note] The constructor, init(), and insert() functions now only take only KShortcut "default" argument instead of two
- [Old note] Removed shortcutDefault3() and shortcutDefault4(). Use shortcutDefault() instead
KAccelBase
- Removed. Replaced by the new KAction/QAction framework.
KApplication
- kapp->isRestored() is now qApp->isSessionRestored()
- kapp->keyboardMouseState() has been removed, its functionality is now provided
by QApplication::keyboardModifiers() and QApplication::mouseButtons()
- random() has been moved to the KRandom class
- For using the kiosk restriction/authorization system you have to use the functions provided in KAuthorized now
- invoke* has been moved to ktoolinvocation. there are static methods invoke*, if you want to use slots as before connect to the invoke* slots of KToolInvocation::self()
- startService*, kdeinitExec* -> KToolInvocation
- static void addCmdLineOptions(); moveto KCmdLineArgs::addStdCmdLineOptions
- kapp->getDisplay() has been removed, its functionality is now provided
by QX11Info::display()
- cut,copy,paste, clear and selectAll were moved to KStdAction
- guiEnabled() was removed, QApplication::type() should be used instead.
- ref()/deref() was moved to KGlobal (as static methods)
- geometryArgument was removed, please use:
QString geometry;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
if (args && args->isSet("geometry"))
geometry = args->getOption("geometry");
- installSigpipeHandler() was removed.
- propagateSessionManager() and requestShutDown() have been moved into the kworkspace library (kdebase/workspace/lib).
- The shutDown() signal has been removed, use QApplication's signal aboutToQuit()
- enableStyles(), disableStyles(), and the constructor argument has been removed.
- installKDEPropertyMap has been moved into k3sqlpropertymap.h and renamed to kInstallKDEPropertyMap. It can be used to keep old code that uses the Q3Data* classes working.For new code, use User in the meta object to determine which Q_PROPERTY to use for any widget.
const QMetaObject *metaObject = widget->metaObject();
for (int i = 0; i < metaObject->propertyCount(); ++i) {
const QMetaProperty metaProperty = metaObject->property(i);
if (metaProperty.isUser()) {
QString propertyToUse = metaProperty.name();
break;
}
}
- caption() has moved to KInstance
- makeStdCaption(const QString&, bool, bool) has moved to KInstance and changed signature to makeStdCaption(const QString&, CaptionFlags)
KAudioPlayer
Removed, use now Phonon::AudioPlayer
KCatalogue
- Has been renamed to KCatalog. Method name parts with "catalogue" have been also renamed to contain "catalog".
KCharsets
- KCharsets::codecForName cannot use glibc's i18n data anymore.
(Note: this feature was new in KDE 3.5 but never publicly announced.)
- TODO: see which member functions can be removed
- TODO: simplification of the encoding list tables
(simply name and description, no need of two tables and an lists of aliases.
KCodecs
- All methods using a QCString removed. The methods use QByteArray now.
- Header renamed to kcodecs.h
KComboBox
- void setURLDropsEnabled() -> void setUrlDropsEnabled()
- bool isURLDropsEnabled() -> bool urlDropsEnabled()
- void setEditURL() -> void setEditUrl()
- void addURL( ... ) -> void addUrl( ... )
- void insertURL( ... ) -> void insertUrl( ... )
- void changeURL( ... ) -> void changeUrl( ... )
KCompletion
- enableSounds() was removed, use setSoundsEnabled()
- disableSounds() was removed, use setSoundsEnabled()
- isSoundsEnabled() -> soundsEnabled()
KConfigBackend
- Removed filename(), use fileName()
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:
KConfig *config = KGlobal::config();
KConfigGroup cg(config, "group name");
...
cg.readXXX("entry name");
KCmdLineArgs
- static void init(int _argc, char **_argv, const char *_appname, const char *_description, const char *_version, bool noKApp = false) KDE_DEPRECATED; -> static void init(int _argc, char **_argv, const char *_appname, const char* programName, const char *_description, const char *_version, bool noKApp = false);
- noKApp parameter is gone, instead: Q_FLAGS(StdCmdLineArgs)
KDesktopFile
- QString filename() const -> QString fileName() const
- more standards compliant. See
Desktop Entry Spec
- .kdelnk files are no longer supported, rename to .desktop.
- deprecated header [KDE Desktop Entry], change to [Desktop Entry]
- type FSDev is no longer supported, change to FSDevice
KExtendedSocket
- This class has been removed. Use KNetwork::KStreamSocket or KNetwork::KServerSocket instead.
KGlobal
- "int kasciistricmp( const char *str1, const char *str2 )" has been moved into kascii.h
KGlobalAccel
- bool useFourModifierKeys() has been removed (we always use four modifier keys now).
- Now a singleton
- You shouldn't need to access this class much... just use setGlobalShortcut() in KAction.
KGlobalSettings
- deprecated "static QString trashPath()" has been removed. use KIO::trash instead
KIcon
- Renamed and deprecated to K3Icon
- Replacement is KIcon - now in kdeui
KKey
- Removed. Use plain ints as the Qt key code instead.
- When replacing KKey(QKeyEvent*), you need to OR the event->key() and event->modifiers() to get the replacement.
- The QtWIN enum has been removed. Use Qt::META or Qt::MetaModifier instead.
- modFlagLabel() was removed, use either KKeyServer::modToStringUser(), or QKeySequence(Qt::yourmodifier).toString()
KKeyNative
- Removed. Use plain ints as the Qt key code instead.
KKeySequence
- Removed, use QKeySequence instead.
- Note that QKeySequence expects multiple shortcuts to be separated by ", " (i.e. a comma then a space) in converting from text.
KLibFactory
KLocale
- QString formatNumber(const QString &numStr) const -> QString formatNumber(const QString &numStr, bool round=true, int precision=2) const;
- bool weekStartsMonday() const -> int weekStartDay() const
- QString monthName(int i, bool shortName = false) const -> QString KCalendarSystem::monthName (int month, int year, bool shortName = false) const = 0; or QString KCalendarSystem::monthName (const QDate & date, bool shortName = false ) const = 0;
- QString weekDayName(int i, bool shortName = false) const -> calendar()->weekDayName
- QString monthNamePossessive(int i, bool shortName = false) const -> calendar()->monthNamePossessive()
- void setWeekStartsMonday(bool start) -> setWeekStartDay
- languages() -> languageList()
- formatMoney(const QString &numStr) -> QString formatMoney(double num, const QString & currency = QString::null, int digits = -1) const;
- charset() -> gone
- setCharset() -> gone
- removeCatalogue was renamed to removeCatalog
See also the I18N section below.
KMacroExpander
- KMacroExpander now takes a QHash and not a QMap
KMD5
KNetwork::KResolver
- the signal finished(KResolverResults) is now finished(const KNetwork::KResolverResults&)
KNetwork::K*Socket
- readBlock, writeBlock and peekBlock are now called simply read, write and peek
- connect() now has an extra parameter (QIODevice::OpenMode)
KNotifyClient
- Replaced by KNotification. The API is quite similar, but the config file need to be updated. See KNotification documentation
KPalette
- color(int), colorName(int) and colorName(const QColor&) have been made const.
KPixmapSplitter
KProcess
- setExecutable() was removed in favor of using operator <<
- getPid() was removed for just pid()
KRegExp
- This class has been removed. Use QRegExp instead
KSaveFile
- KSaveFile has been modified from its KDE 3.x behavior to allow for new backup methods:
- KSaveFile::backupFile() will use the backup behavior specified in KConfig.
- KSaveFile::simpleBackupFile() will emulate the KDE 3.x behavior
- KSaveFile::numberedBackupFile() will create a numbered set of backup files (default: 10)
- KSaveFile::rcsBackupFile() will use rcs to maintain the backup file
KShortcut
- Now implicitly shared and reentrant
- Only uses QKeySequences now
KShortcutList and derivatives
- Removed - no longer needed
- Saving and loading of shortcuts now performed in KActionCollection, KGlobalAccel, and KStdAccel.
KSortableValueList
- Has been ported to QList, renamed to KSortableList and the header is ksortablelist.h
KStdAccel
- Removed deprecated methods
- Removed WhatThis, use WhatsThis
- shortcutDefault3() and shortcutDefault4() have been removed, use shortcutDefault() instead
KStringHandler
- static QString ljust( const QString &text , int width ) -> QString::leftJustified
- static QString rjust( const QString &text , int width ) -> QString::rightJustified
- matchFilename -> matchFileName
- static QString word( const QString &text , int pos ) -> QString::section
- ::randomString() has been moved to KRandom::randomString()
KStyle
KTempDir
- existing() was removed, use exists() instead
KURL
- Has been renamed to KUrl, but a typedef is available for source compatibility
- KUrl inherits QUrl now, but the API offered by KUrl is mostly unchanged
- filename() has been removed, use fileName() instead
- isMalformed -> !isValid()
- prettyURL(0,KUrl::StripFileProtocol) -> pathOrURL()
- fromPathOrURL() is deprecated, use the KUrl(str) constructor which now accepts both paths and urls
- htmlURL() had to be removed, please use Qt::escape(url.prettyURL()) now, with #include <QTextDocument>.
This requires libQtGui, which is why it can't be in KUrl anymore.
- url(0,106) or any other use of the 'mib enum' for encoding has been removed. QUrl is UTF8 based, and the world is becoming more and more utf8 based as well, the old encoding hacks inside urls should disappear.
- Runtime behavior change: port() used to return 0 if no port was specified. It now returns -1 in that case, or you can use port(defaultPort) to set what it should return if no port was specified.
- adjustPath(), path(), encodedPathAndQuery() , url() , prettyUrl() was taking a int argument for handling trailing slash that has been replaced by an enum AdjustPathOption (0 => KUrl::LeaveTrailingSlash, 1 => KUrl::AddTrailingSlash, -1 => KUrl::RemoveTrailingSlash).
- cleanPath(), queryItems(), fileName(), directory(), equals() now take a QFlags argument instead of boolean
- *URL* renamed to *Url*:
- hasSubURL() -> hasSubUrl()
- prettyURL() -> prettyUrl()
- pathOrURL() -> pathOrUrl()
- upURL() -> upUrl()
- isRelativeURL() -> isRelativeUrl()
- relativeURL() -> relativeUrl()
KURLDrag
- This class has been moved to kde3support. Use KUrl::populateMimeData() and
KUrl::List::populateMimeData() in the drag/copy side,
and the static methods KUrl::List::canDecode() and KUrl::List::fromMimeData()
in the drop/paste side.
Example: Replace KURL::List uriList;
if ( KURLDrag::canDecode(e) && KURLDrag::decode( e, uriList ) ) {
by KUrl::List uriList = KUrl::List::fromMimeData( e->mimeData() );
if ( !uriList.isEmpty() ) {
KVMAllocator
- The two old copy methods are removed, copyBlock equivalents are renamed to copy
KWin
- appStarted() removed, use KStartupInfo::appStarted() instead
- info(WId win) removed, use windowInfo() instead
- struct Info was removed, use WindowInfo instead
locate
- locate moved into the namespace KStandardDirs
NETRootInfo
- NETRootInfo(Display *display, Window supportWindow, const char *wmName,unsigned long properties, int screen = -1, bool doActivate = true) ->
NETRootInfo(Display *display, Window supportWindow, const char *wmName,
const unsigned long properties[], int properties_size,
int screen = -1, bool doActivate = true); old properties is the first element of the new array
- unsigned long supported() -> const unsigned long* supportedProperties() const;
- unsigned long properties() const -> gone
- WindowType windowType() -> WindowType windowType( unsigned long supported_types ) const;
- kactionclasses.h went away, use the several kxxxaction.h instead
- kcolordlg.h went away, use kcolordialog.h
- kcolorbtn.h went away, use kcolorbutton.h
- kdatapik.h went away, use kdatepicker.h
- kdualcolorbtn.h went away, use kdualcolorbutton.h
- kpassdlg.h went away, use kpassworddialog.h
- kxmlgui.h went away, use kxmlguifactory.h
- kfontcombo.h went away, use QFontComboBox
KAboutContainer
- KAboutContainer constructor int args have been replaced by Qt::Alignment
- addTitle int args replaced by Qt::Alignment
- addImage int args replaced by Qt::Alignment
KAboutContributor
- void setURL( const QString& ) -> void setUrl( const QString& )
- QString getName( void ) const -> QString name() const
- QString getEmail( void ) const -> QString email() const
- QString getURL( void ) const -> QString url() const
- QString getWork( void ) const -> QString work() const
- signal void openURL() -> void openUrl()
KAboutDialog
KAboutWidget
- signal void openURL() -> void openUrl()
- void openURLSlot() -> void openUrlSlot()
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().
- KAction is now a subclass of QWidgetAction.
- Don't use setIconSet() anymore, use setIcon(KIcon(iconName)) instead
- New constructors more closely model QAction (old constructors deprecated)
- Constructors now take a QString instead of const char* for action names
- You should never rename the objectName() of a KAction - as KActionCollection holds a map, and it is not told of name changes (thus the setObjectName() functions are made private)
- "icon" property is now a QIcon, use iconName() / setIconName() for KDE named icons
- KShortcuts supported by shortcut/setShortcut (hides QAction's shortcut/setShortcut). Automatically sets alternateShortcuts() in QAction.
- plug(), unplug() deprecated - use QWidget::addAction() and QWidget::removeAction() instead (To provide custom widgets for toolbars, use the facilities from QWidgetAction, the parent class)
- containerCount(), container() deprecated - use associatedWidgets() instead
- activated(), activated(int) signals deprecated - use triggered() signal instead
- activate() is now trigger(), as in QAction
- there is a replacement for activation providing keyboard + mouse states, see triggered(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) [currently buggy]
- plugAccel(), unplugAccel(), kaccelCount() removed - they have no use now (accelerator management is inside Qt)
- itemId(), getToolButtonID() removed - actions no longer have ids, basically the QAction* is its replacement
- setGroup() / group() removed - use QActionGroup instead (setActionGroup() / actionGroup())
- ActivationReason has been removed (not supported by Qt). For a surrogate, you can connect to QMenu::triggered(QAction*), QToolBar::actionTriggered(QAction*), etc.
- setters are no longer slots; where they were used as such, an intermediary will be required
- New feature from Qt: statusTip() / setStatusTip(). Usually this will be the same as the tooltip. It appears in the status bar whenever the action is hovered in a QMenu. A porting convenience is being investigated for automatic toolTip() -> statusTip(), but the best solution is to set both.
- New feature: globalShortcut() and globalShortcutAllowed(). Automatically communicates with KGlobalAccel to register a global shortcut (i.e. one that does not need the application to have focus to be activated).
- setShortcut() now defaults to setting the default shortcut as well (as it was by far the most common use case). To just set the custom shortcut, use setShortcut(myShortcut, KAction::CustomShortcut)
- Porting example:
The following code
KAction *action = new KAction( i18n( "Copy" ), "copy_icon", Qt::Key_F6, this, SLOT( copy() ),
actionCollection(), "copy_name" );
should be rewritten as
KAction *action = new KAction( i18n( "Copy" ), actionCollection(), "copy_name" );
action->setShortcut( Qt::Key_F6 );
action->setIcon( KIcon( "copy_icon" ) );
connect( action, SIGNAL( triggered() ), this, SLOT( copy() ) );
If the first argument is a KGuiItem, use KGuiItem::text() and KGuiItem::iconName().
KActionCollection
- constructor (QWidget* watch, ..) and setWidget() replaced by {set|add|remove}AssociatedWidget() - allows actions to respond to matching key presses on a widget level (basically a convenience method to have all actions in the collection added to the associated widget(s) and their shortcut scopes set to Qt::WidgetShortcut).
- *AutoConnectShortcuts removed - irrelevant
- *accel() removed - irrelevant (KAccel no longer handles key presses)
- New functions setConfigGroup(), setConfigGlobal(), configGroup(), configIsGlobal() - the action collection now stores the group whether the config is global. referenced in readSettings() / writeSettings()
- readShortcutSettings() and writeShortcutSettings() renamed without the "Shortcut". Set the configGroup() with setConfigGroup() either prior to each call, or (preferably) at the creation time of the action collection.
- {set}HighlightingEnabled(), {connect|disconnect}Highlight() removed - highlighting is always enabled now
- actionHighlighted(), actionStatusText(), clearStatusText() removed - use QAction::setStatusTip() as a replacement. QStatusBars belonging to QMainWindow automatically get the statusTip() applied to them when they are moused over in a QMenu, via a QStatusTipEvent.
- groups() removed (now using QActionGroups) - see actionGroups() (and actionsWithoutGroup()) for replacement
- actions( const QString& group ) removed - use actionGroups() instead, and then QActionGroup::actions()
- action(int), count() deprecated - use actions() directly
- action(const char* name, const char* className) removed: action(const QString& name), actions(const QString& name), actionOfType<Class>(const QString& name), actionsOfType<Class>(const QString& name) are the replacements
KActionSelector
- Q3ListBox -> QListWidget
- selectedListBox -> selectedListWidget
- availableListBox -> availableListWidget
KActionSeparator
- Renamed to KSeparatorAction
- Note that you need to create multiple separator actions if you want to insert multiple separators into a widget, unlike with KDE3.
KActiveLabel
- Use QLabel instead. This class will probably move to kde3support.
- QLabel::setOpenExternalLinks(true) and QLabel::setTextInteractionFlags(Qt::LinksAccessibleByMouse|QtLinksAccessibleByKeyboard) for labels with hyperlinks.
- QLabel::setTextInteractionFlags(Qt::TextSelectableByMouse|QtTextSelectableByKeyboard) for labels whose text should be selectable by user.
- QLabel::setOpenExternalLinks(true) and QLabel::setTextInteractionFlags(Qt::TextBrowserInteraction) for both features.
- Inherits from KTextBrowser instead of Q3TextBrowser
- You don't need anymore to disconnect the linkClicked signal to handle manually link, use KTextBrowser::setNotifyClick(true)
- linkClicked -> KTextBrowser::urlClick
KAnimWidget
- Renamed to KAnimatedButton
- Now a subclass of QToolButton, acts in a much more standard fashion
- size(), setSize() replaced by iconSize() + setIconSize()
- Call updateIcons() whenever you change the iconSize() (the setter is non virtual :(
KAuthIcon
KBugReport
- void updateURL() -> void updateUrl()
KButtonBox
Replaced by KDialogButtonBox. Add the role parameter to the addButton function. Or check if it can't be achieved using KDialog
KCharSelectTable
- There is no separation between focused and selected item anymore, only between selected and activated.
- Signal focusItemChanged is not emitted with the currently selected/focused character, not with the most recent activated one.
- Signal highlighted(...) has been removed.
- Protected members gotoleft/right/up/down are gone. If you really need to simulate them, use the qitemselectionmodel
KColorDrag
- has been moved as K3ColorDrag to kde3support
- use QMimeData directly instead or KColorMimeData, which closest resembles KColorDrag
KConfigDialog
KContextMenuManager
- KContextMenuManager::insert() :
Old code:
KContextMenuManager::insert(widget, menu);
New code:
widget->setContextMenuPolicy(Qt::ActionsContextMenu);
widget->addActions(menu->actions());
- Otherwise consider handling the context menu in a contextMenuEvent() handler, which Qt
calls automatically on a right-mouse-button click or on activation by the context menu key.
There's no need to do anything in mousePressEvent/mouseReleaseEvent/keyPressEvent.
KDatePicker
- signal void dateChanged(QDate); was replaced by void dateChanged( const QDate&);
- signal void dateEntered(QDate); was replaced by void dateEntered( const QDate&);
- signal void dateSelected(QDate); was replaced by void dateSelected( const QDate&)
- changed the order of the constructor's parameter
- removed getData() method. Use date() instead
- removed protected slot void selectWeekClicked()
KDateTable
- signal void dateChanged(QDate); was replaced by void dateChanged(const QDate&);
- changed the order of the constructor's parameter
- removed getData() method. Use date() instead
KDateWidget
- signal void changed(QDate); was changed by void changed(const QDate&)
KDialog
- Simplified ctor.
The following ctor
KDialog dlg( parent, i18n("my caption"), modal, Ok | Cancel | User1, Ok, false, i18n("Share File"))
should be rewritten as
KDialog dlg( parent );
dlg.setCaption( i18n("my caption") );
dlg.setModal( modal );
dlg.setButtons( Ok | Cancel | User1 );
dlg.setButtonGuiItem( User1, i18n("Share File") );
dlg.setDefaultButton( Ok );
dlg.showButtonSeparator( false );
- setButtonMask() -> setButtons() and setButtonGuiItem()
- setButtonBoxOrientation() -> setButtonsOrientation()
- setButtonOKText, setButtonApplyText , setButtonCancelText -> setButtonText( ButtonCode, const QString& )
- don't overide anymore slotFoo(). You now need to connect to FooClicked signal.
Or reimplement accept() and reject() to intercept the Ok and Cancel button
- enableButtonOK -> enableButtonOk (lower case 'k')
- enableButtonSeparator -> showButtonSeparator
KDialogBase
- Deprecated. Use KDialog or KPageDialog instead.
- If the KDialogBase is Swallow or Plain mode you should replace it with KDialog, for
all other modes use KPageDialog
Replace
QWidget *page = plainPage();
with
QWidget *page = new QWidget( this );
setMainWidget( page );
All makeXXXMainWidget() methods can be replaced by the following schema:
KVBox *mainWidget = makeVBoxMainWidget();
replace with
KVBox *mainWidget = new KVBox( this );
setMainWidget( mainWidget );
- If you use a KPageDialog, the following steps must be taken...
Replace ctor
KDialogBase dlg( Tabbed, 0, parent, name, modal, i18n( "my caption" ), ... )
with
KPageDialog dlg( parent );
dlg.setFaceType( KPageDialog::Tabbed );
dlg.setObjectName( name );
dlg.setModal( modal );
dlg.setCaption( i18n( "my caption" ) );
...
All addXXXPage() methods can be replaced by the following schema:
KVBox *page = addVBoxPage( i18n( "My Title" ), i18n( "My Header" ), QPixmap( "image" ) );
replace with
KVBox *page = new KVBox();
KPageWidgetItem *item = addPage( page, i18n( "My Title" ) );
item->setHeader( i18n( "My Header" ) );
item->setIcon( KIcon( "image" ) );
KDockWindow
- This class is obsolete, it is provided for compatibility only.
Use KSystemTrayIcon instead.
KDualColorButton
KEdit
- The signal gotUrlDrop was removed, nobody used it, and it's easy to do in the application
if needed (see the KURLDrag section)
KEditListBox
- void insertStrList(const QStrList* list, int index=-1) and void insertStrList(const QStrList& list, int index=-1) have been deprecated, use QStringList or const char** instead
KGradientSelector
- Reversed the value range, if orientation is horizontal. Now minimum is on the left and maximum on the right side.
KGUIItem
- Don't use setIconSet anymore, use setIcon instead, there is no compatibility class or function
KIcon
- New class (old one renamed to K3Icon)
- Thin wrapper around QIcon which creates a KIconEngine corresponding to the kde named icon
KInputDialog
- static QString KInputDialog::text( const QString &caption,...) was replaced by QString KInputDialog::getText( const QString &caption,...)
KIntNumInput, KDoubleNumInput, KDoubleSpinBox
- Qt::Alignment for label alignment instead of int
- setMinValue(min) -> setMinimum(min) / minValue() -> minimum()
- setMaxValue(min) -> setMaximum(min) / maxValue() -> maximum()
KJanusWidget
- Deprecated. Use KPageWidget instead
KKeyDialog
- removed KDE2 deprecated functions
- Added new constructor parameter: KKeyChooser::ActionTypes types. Allows you to filter the types of actions shown in the dialog.
KKeyChooser
- Added new constructor parameter: ActionTypes types. Allows you to filter the types of actions shown in the dialog.
- Removed all functions dealing with old classes KShortcutList, KGlobalAccel (kde3 version)
KLed
- int ensureRoundLed() -> virtual int ledWidth() const
- virtual void paintRound() -> virtual void paintRaised()
KLineEdit
- void cursorAtEnd() removed, use QLineEdit::end(false) instead
- unused protected slots removed: void slotAboutToShow() and void slotCancelled()
- void setEnableSqueezedText( bool enable ) -> void setSqueezedTextEnabled( bool enable )
- void setURLDropsEnabled() -> void setUrlDropsEnabled()
- bool isURLDropsEnabled() -> bool urlDropsEnabled()
- void setURL() -> void setUrl()
KLineEditDlg
- Was deprecated, has been removed. Use KInputDialog instead.
KListAction
- Deleted - as per comments, did not add anything to KSelectAction
KMainWindow
- getMemberList() was replaced by memberList() and memberList was renamed to mMemberList and made it private
- sizeForCentralWidgetSize(QSize size) returned the size the main window should have so that the central widget will be of size. You normally don't need this, the recommended way to achieve a certain central widget size is as follows.
* Override sizeHint() in the central widget so that it returns the desired size.
* Call updateGeometry() in the central widget whenever the desired size changes. This ensures that the new sizeHint() is properly propagated to any parent layout.
* Now call adjustSize() in the main window to resize the main window such that the central widget will become the desired size.
- Ported to QMainWindow
- accel() removed - KAccel no longer needed
KMainWindowInterface
- functionsDynamic() now returns a DCOPCStringList
- function processDynamic arguments uses DCOPCString instead of QCString :
bool processDynamic(const DCOPCString &fun, const QByteArray &data, DCOPCString& replyType, QByteArray &replyData);
- actions() now returns a DCOPCString
KPassivePopup
- clicked single now emits a const QPoint reference
KPasswdEdit
- KPasswordEdit(QWidget *parent, const char *name, int echoMode) ; was deprecated
KPasswordDialog
- kpassdlg.h was renamed kpassworddialog.h.
KPixmapIO
- The class is dumped, use QPixmap.toImage() and QPixmap::fromImage()
KPopupMenu
- Renamed to KMenu to reflect change in Qt
- indexes replaced by QAction*
- title, titlePixmap, and changeTitle removed - use QAction::text(), QAction::icon(), QAction::setText() and QAction::setIcon
- contextMenuFocusItem changed to contextMenuFocusAction in line with the change from indexes to actions
KPopupTitle
- Removed - QMenu doesn't accept widgets, and QAction allows specification of font, icon etc... and gradients / background pixmaps weren't even working in KDE3
KProgress
- KProgress has been renamed to KProgressBar (#include <kprogressbar.h> instead of #include <kprogress.h>)
- QProgressBar is mostly enough. KProgressBar only necessary if setFormat(const QString & format) or advance(int offset) is needed.
- KProgressBar inherits from QProgressBar. QProgressBar has changed a lot in Qt4 ( setTotalSteps(totalSteps) -> setRange(0, totalSteps), setProgress -> setValue, percentageChanged -> valueChanged ). For more details see QProgressBar class reference.
KProgressDialog
- #include <kprogressdialog.h> instead of #include <kprogress.h>
- See KProgress API changes
KPushButton
- Don't use setIconSet anymore, use setIcon instead, there is no compatibility class or function
KRadioAction
- Deleted - use KAction (or KToggleAction if you need different text/icons for the selected state) instead, in combination with an exclusive QActionGroup
KRecentFilesAction
- clearURLList() removed, use clear() instead
- *URL* -> *Url* as per KDE naming policy
- the maxItem property is now an int (was a uint) (affects all accessors methods)
KRootPixmap
KSelectAction
- now allows for combo box or button with popup menu when inserted to a toolbar
- popupMenu() removed, use menu() instead
- {set|}removeAmpersandsInCombo() removed - was deprecated
KHSSelector
- Renamed to KHueSaturationSelector, moved to kxyselector.h
KSeparator
- KSeparator now uses Qt::Vertical and Qt::Horizontal rather then QFrame's HFrame and VFrame.
KSharedPixmap
KStatusBar
- The unused BarStatus enum was removed.
- The 'permanent' bool has been removed in favor of more explicit naming.
insertItem(text,id,true) -> insertPermanentItem(text,id),
insertFixedItem(text,id,true) -> insertPermanentFixedItem(text,id)
KStdAction
- showToolbar() methods have been removed, see KMainWindow::setStandardToolBarMenuEnabled()
KSyntaxHighlighter
- Use K3SyntaxHighlighter because it used Q3TextEdit or use KSyntaxHighlighter when your application will use QTextEdit
KSystemTray
- Renamed to KSystemTrayIcon for consistency with its actual purpose and naming in Qt (QSystemTrayIcon)
- Is now a subclass of QSystemTrayIcon and not QLabel. Therefore it is not a widget anymore. Otherwise, it behaves the same as in KDE3 when it comes to managing a parent window's visibility and providing an action collection to display in the context menu.
KTabBar
- colors, close buttons on individual tabs not working at the moment
- The old insertTab and removeTab have been removed, use addTab / insertTab / removeTab from QTabBar instead (uses indices, not QTab*s)
KTabCtl
KTextBrowser
- Inherits from QTextBrowser instead of Q3TextBrowser
KTextEdit
- void highLightWord() -> void highlightWord()
KTimeWidget
KTimezoneWidget
- Renamed to KTimeZoneWidget
KToggleAction
- setExclusiveGroup() / exclusiveGroup() removed, use setActionGroup() and QActionGroup::setExclusive() for exclusivity (imitates the deleted KRadioAction class)
- in comparison with KAction, adds setCheckedState() and sets this action to checkable
KToggleFullScreenAction
- Simplified constructor
Replace
KToggleFullScreenAction( const KShortcut &cut, const QObject* receiver, const char* slot,
KActionCollection* parent, QWidget* window, const QString& name )
with
KToggleFullScreenAction( QWidget* window, KActionCollection* parent, const QString& name )
See KAction how to port the other arguments.
KToolBar
- Ported to QToolBar
- IconText, iconText(), setIconText() replaced by QToolBar::toolButtonStyle() et. al.
- BarPosition, barPos(), setBarPos() replaced by Qt::ToolBarArea settings in QMainWindow; Unmanaged, Floating, and Flat are no longer supported (use QDockWidget if you need floating toolbars)
- fullSize(), setFullSize() removed as now handled in QMainWindow - add or insert a tool bar break before (not needed for the first toolbar) and after the toolbar using QMainWindow::{add|insert}ToolBarBreak() to have the toolbar take up all available horizontal space
- iconSize(), setIconSize() now a QToolBar property, and a QSize instead of an int - convenience function setIconDimensions() takes an int instead
- insert*() and all associated item-manipulation methods removed - all done through actions now. Compatibility layer possible however so far I haven't found the functions to be used much in KDE programs (mostly it's taken care of by xmlgui instead)
- flat(), setFlat() replaced by movable(), setMovable() (old "flat" concept equivalent to not movable)
- layout-related methods removed (done by QToolBar's layout)
- alignItemRight() removed (as above), replacement is to add a KToolBarSpacerAction before the action you want to be aligned right (or if you have a custom action already, just create a container widget and insert a QSpacerItem on the left of your custom widget (see KonqLogoAction in kdebase/konqueror/konq_actions.cc)
- enum BarStatus and bool enable(BarStatus stat) have been
removed
- void enableMoving(bool flag) and void enableFloating (bool
flag) have been removed in favor of setMovingEnabled(bool)
- int maxHeight()/int maxWidth() removed in favor of
maximumHeight()/maximumWidth()
- void setMaxHeight (int h) and void setMaxWidth (int dw)
removed in favor of setMaximumHeight()/setMaximumWidth()
- void setEnableContextMenu(bool enable = true) -> void setContextMenuEnabled(bool enable = true)
KToolBarButton
- Deleted - all done by QToolButton now
KToolBarLabelAction
- Simplified constructors:
Replace
KToolBarLabelAction( const QString &text,
const KShortcut &cut,
const QObject *receiver, const char *slot,
KActionCollection *parent, const QString& name )
with
KToolBarLabelAction( const QString &text,
KActionCollection *parent, const QString& name )
and
KToolBarLabelAction( QAction *buddy, const QString &text,
const KShortcut &cut,
const QObject *receiver, const char *slot,
KActionCollection *parent, const QString& name )
with
KToolBarLabelAction( QAction *buddy, const QString &text,
KActionCollection *parent, const QString& name )
See KAction for how to port the other arguments.
KToolBarRadioGroup
- Deleted - all done by QToolButton now
KToolBarSeparator
- Deleted - use QAction::setSeparator()
KURLLabel
- renamed to KUrlLabel
- void setAltPixmap() -> void setAlternatePixmap()
- QPixmap* altPixmap() -> QPixmap* alternatePixmap()
- void setGlow() -> void setGlowEnabled()
- void setFloat() -> void setFloatEnabled()
- void setURL() -> void setUrl()
- signal: void enteredURL( ... ) -> void enteredUrl( ... )
- signal: void leftURL( ... ) -> void leftUrl( ... )
- signal: void leftClickedURL( ... ) -> void leftClickedUrl( ... )
- signal: void rightClickedURL( ... ) -> void rightClickedUrl( ... )
- signal: void middleClickedURL( ... ) -> void middleClickedUrl( ... )
KValueSelector
- Renamed to KColorValueSelector, moved to kcolorvalueselector.h
KWidgetAction
- Removed, instead use a KAction or QWidgetAction and utilise its widget-setting capabilities.
KWizard
- Moved to kde3support and renamed to K3Wizard.
- Use KAssistantDialog instead (having similar API).
KArchive/KTar/KZip/KAr
- All sizes and file offsets now use qint64 (similar to QIODevice)
- The API has changed for subclasses: there is a KArchive constructor that takes a filename, and which provides KSaveFile support automatically, writeDir is doWriteDir, prepareWriting is doPrepareWriting etc.
- API changes for users of the class: isOpened() was renamed to isOpen(),
doneWriting() to finishWriting(), and the order of the arguments for writeFile() is more usual:
data comes before size.
- KTarDirectory -> KArchiveDirectory
- KTarFile -> KArchiveFile
- KTarEntry -> KArchiveEntry
- KTarGz -> KTar
KBookmark classes
- KBookmarkDrag class has been moved to kde3support. Use KBookmark::populateMimeData() and
KBookmark::List::populateMimeData() in the drag/copy side,
and the static methods KBookmark::List::canDecode() and KBookmark::List::fromMimeData()
in the drop/paste side.
KDESasl class
- This class is removed due to its inflexiblity, use cyrus-sasl or the upcoming QCA SASL implementation
KFileDialog,KDirselectDialog,KUrlRequesterDlg,KCustomMenuEditor,KUrlBarItemDialog
- are KDialogBases no more, now they are a KDialogs
- no more name and modal parameters in the constructors
KFileDialog, KFileView, KDirOperator
- instead of KConfig* + QString group everywhere KConfigGroup is used now
KFileDialog
KFileItemList
KFileMetaInfo
- KFileMetaInfo::KiloBytes has been renamed KFileMetaInfo::KibiBytes (1 KiB = 1024 B)
KFileOpenWithHandler
- This class has been removed, it was just a workaround for a dependency problem,
just remove any instance of it.
KIconButton
- signal void iconChanged(QString); replaced by void iconChanged(const QString &);
KIconDialog
- signal void newIconName(QString); replaced by void newIconName(const QString &);
KImageIO classes
- The KImageIO plugins are converted to Qt's imageformat plugins. The KImageIO class
now a lightweight version to query the installed plugins without actually loading them.
- .kimgio files are converted to .desktop files, and contains regular KDE services,
with ServiceType as QImageIOPlugins
- KImageIO::registerFormats() removed, simply remove this from your code
- Instead of mimeType(filename), you should use KMimeType
- Instead of canRead() and canWrite() you can use types(mode).contains(typename)
KIO:: global methods
- KIO::convertSizeFromKB is now KIO::convertSizeFromKiB since it takes a value in KiB (1 KiB = 1024 B)
KIO::Job
- For Job subclasses: removeSubjob doesn't terminate the parent job anymore, add
if ( !hasSubjobs() ) emitResult();
to emulate the old behavior that.
- subjobs is now private. This means you should replace subjobs.remove(job) with removeSubjob(job),
and subjobs.isEmpty() with !hasSubjobs()
job->showErrorDialog(QWidget*)
becomes job->ui()->showErrorMessage()
. The parent QWidget should be set immediately after creating the job by job->ui()->setWindow(QWidget*)
job->setAutoErrorHandlingEnabled(bool,QWidget*)
becomes job->ui()->setAutoErrorHandlingEnabled(bool)
job->isAutoErrorHandlingEnabled()
becomes job->ui()->isAutoErrorHandlingEnabled()
job->setAutoWarningHandlingEnabled(bool)
becomes job->ui()->setAutoWarningHandlingEnabled(bool)
job->isAutoWarningHandlingEnabled()
becomes job->ui()->isAutoWarningHandlingEnabled()
job->setWindow(QWidget*)
becomes job->ui()->setWindow(QWidget*)
job->window()
becomes job->ui()->window()
job->setInteractive( false )
becomes job->setUiDelegate( 0 )
KIO::UDSEntry
- UDSEntry is now a hash instead of a list. Use the methods stringValue()
and numberValue() to retrieve fields directly, no loop is needed anymore.
See the UDSEntry documentation for code examples.
- Also note that UDSEntryListConstIterator is now UDSEntryList::ConstIterator;
see the UDSEntryList documentation for a full code example of iterating through
a listDir result.
- For kioslaves: replace every three lines like
atom.m_uds = KIO::UDS_SIZE;
atom.m_long = buff.st_size;
entry.append( atom );
with the line entry.insert( KIO::UDS_SIZE, buff.st_size );
KMimeType
- KMimeType::pixmap() has been deprecated (for core/gui separation), use icon() or icon(url)
and KIconLoader::loadMimeTypeIcon with that icon name.
- KMimeType::pixmapForURL > KIO::pixmapForURL
- KMimeType::comment(KUrl,bool) > KIO::comment(KUrl)
- KMimeType::diagnoseFileName has been replaced with KMimeType::extractKnownExtension which returns the extension only, not the pattern
- KMimeType::mimeType(someName) now behaves like KServiceType::serviceType(someName), i.e. it returns 0 if that name doesn't exist,
instead of returning the application/octet-stream mimetype. Test for null!
- iconForURL has been deprecated, will possibly be removed for KDE 4.0 final, use iconNameForURL instead
KProtocolInfo
- Many static methods have been moved to KProtocolManager (which is in kio)
so that kprotocolinfo itself could be moved to kdecore:
- KProtocolInfo::supportsListing(url or protocol) -> KProtocolManager::supportsListing(url)
- KProtocolInfo::supportsReading(url or protocol) -> KProtocolManager::supportsReading(url)
- KProtocolInfo::supportsDeleting(url or protocol) -> KProtocolManager::supportsDeleting(url)
- etc.
- The deprecated methods taking a QString protocol as input have been removed, make sure
to pass a KUrl to most methods instead.
KRun
- the constructor needs a second parameter (a widget) now
KURLBar
KURLCombo
- Renamed to KUrlCombo
- All usage of QPixmap has been replaced by usage of QIcon
- getPixmap() --> getIcon()
KURLCompletion
- Renamed to KUrlCompletion
KURLPixmapProvider
- Renamed to KUrlPixmapProvider
KURLRequester
- renamed to KUrlRequester
- setCaption is gone, use setWindowTitle instead
- Renamed setURL() to setUrl(), per KDE naming policy
- Ported to use KUrl instead of QString. Thus, the constructors, setUrl(), url(), and urlChanged() all use KUrl.
- Removed showLocalProtocol() and setShowLocalProtocol(); this is now always false (the user never sees file:///)
KService
- KService::rebuildKSycoca -> KBuildSycocaProgressDialog::rebuildKSycoca
KServiceType
- KServiceType::offers() -> KServiceTypeTrader::self()->query()
- The behavior of KServiceType::serviceType() has changed: it now only returns real service types, and no more mimetypes. For mimetypes, use KMimeType::mimeType().
- Similarly, allServiceTypes() only returns real service types, no more mimetypes.
KServiceTypeProfile
- This class has been moved to kservicetypeprofile.h and is mostly internal now. Use KTrader or KMimeTypeTrader instead.
- KServiceTypeProfile::preferredService is now KMimeTypeTrader::self()->preferredService or KTrader::self()->preferredService
- KServiceTypeProfile::offers is now KMimeTypeTrader::self()->query or KTrader::self()->query
KTrader
- KTrader has been split up into two classes: KServiceTypeTrader and KMimeTypeTrader.
- So KTrader::query() should be ported to KMimeTypeTrader::query() when it's about mimetypes
(finding the application or part for a given mimetype), and to KServiceTypeTrader::query() when
it's about pure service types (plugins, kcmodules, etc.)
- In other terms, KTrader::query(1 or 2 args) -> KServiceTypeTypeTrader::query and
KTrader::query(4 args but the last one was always QString::null) -> KMimeTypeTrader::query
- In both cases, query() now returns KService::List instead of an OfferList, adjust the type of the variable
- Constraints like "'RenameDlg/Plugin' in ServiceTypes" should be turned into
KMimeTypeTrader::self()->query(mimetype,"RenameDlg/Plugin")
PasswordDialog
- void setEnableUserField( bool enable, bool=false ) removed use :setUserReadOnly( !enable )
RenameDlg
- void b0Pressed() renamed to void cancelPressed()
- void b1Pressed() renamed to void renamePressed()
- void b2Pressed() renamed to void skipPressed()
- void b3Pressed() renamed to void autoSkipPressed()
- void b4Pressed() renamed to void overwritePressed()
- void b5Pressed() renamed to void overwriteAllPressed()
- void b6Pressed() renamed to void resumePressed()
- void b7Pressed() renamed to void resumeAllPressed()
- void b8Pressed() renamed to void suggestNewNamePressed()
UIServer
- QByteArray openPassDlg( const KIO::AuthInfo >info ); removed. Use KIO::PasswordDialog::getNameAndPassword
BrowserRun
- BrowserRun::isExecutable obsoleted by KRun::isExecutable
- suggestedFilename -> suggestedFileName
ComponentFactory
- createInstanceFromFactory is now KLibFactory::create<T>
- createInstanceFromLibrary is now KLibLoader::createInstance<T>
- createInstanceFromService is now KService::createInstance<T>
- createInstanceFromQuery is now KServiceTypeTrader::createInstanceFromQuery<T>
- All the error codes like KParts::ComponentFactory::ErrNoServiceFound have moved to KLibLoader
- The class KDEDModule is now part of libkdecore so that kded modules can link without undefined symbols.
A number of apparently unused methods in KDEDModule have been commented out, contact
kde-core-devel if you need those after all.
- Note that the signature for the create_xyz() call has changed, simply remove all arguments from it,
and from your kded module's constructor
KSpell
- The Button enum in KCModule only contains the Help, Default and Apply
values. The other buttons are not optional. If your KCM specified the button
flags just remove everything except those three.
- The functions setRootOnlyMsg, rootOnlyMsg, setUseRootOnlyMsg and
useRootOnlyMsg have been renamed to
setRootOnlyMessage, rootOnlyMessage, setUseRootOnlyMessage and
useRootOnlyMessage.
- KCModules need to have Type=Service and ServiceTypes=KCModule in the
.desktop file now - was Type=Application before
- KCModules that should show up in KControl or kcmshell --list need to have
X-KDE-ParentApp=kcontrol or kinfocenter
- If the KCModule should be used by kcminit you have to add KCModuleInit to
ServiceTypes (i.e. ServiceTypes=KCModule,KCModuleInit then)
- The kcm_ prefix in X-KDE-Library is now optional (in KDE3 the
X-KDE-Library value was automatically prefixed with kcm_)
- If the kcminit code is in a different lib than the other KCM code the
X-KDE-Init-Library was used. The library name has to be prefixed with kcminit_
now, but the prefix is optional in the .desktop file.
- The kcminit symbol now has to be prefixed with kcminit_ (in the code). The
rest of the symbol name is specified with X-KDE-Init-Symbol (was X-KDE-Init
before).
- It is now possible to use multiple K_EXPORT_GENERIC_FACTORY calls in one
library. The first parameter to the macro has to be the same as
X-KDE-FactoryName then.
- KCModule does no longer take a name argument, but directly a KInstance (having the correct
name for the translations to work.
- The X-KDE-RunAsRoot and X-KDE-IsHiddenByDefault keys are removed.
- KCModules will not be embedded running with root privileges anymore.
Instead the GUI code will run with user privileges as every other KCM. Only in
order to write or call programs should the KCM elevate its privileges.
- KDockWidgets -> kde3support K3DockWidget
- KParts::DockWindow -> kde3support KParts::DockWindow3
- KMDI* --> kdeSupport K3MDI*
libkmid
- Moved to kdemultimedia, where (at the moment) it is only used by kmid.
libkscreensaver
- Moved to kdebase/workspace/kscreensaver
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:
- If you define your own keywords (-k parameter of xgettext), you probably
need to adapt them, as xgettext does not automatically know about the
1, 2 or 3 parameter versions.
- You cannot have two similar messages, one being a normal message and
the other the singular form of a plural-form messages. For Gettext, this is
the same message and therefore this creates problems. (Note: there is not
any similar problems when you use contexts.)
- As in Gettext 0.15-pre, contexts are supposed to be short, please consider
using a special comment instead of a context to give long hints to translators.
The special comment starts with //i18n: ot /*i18n: and must be before
the message code. (Note: this is not new to KDE4, but very seldomly used in
KDE3.)
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 type int
, double
, QString
, QChar
(and perhaps more in the future).
Context and plural calls now have different names, i18nc
and i18np
, and take arguments in the same way:
i18nc("Player name - score", "%1 - %2", playerName, score);
i18np("1 image in album %1", "%n images in album %1", n, albumName);
There is one new variant, the context-plural call:
i18ncp("Personal file", "1 file", "%n files", n);
i18n*
calls are realized as templates, and so will take at most some finite number of arguments.
Notes on placeholder substitution:
- Placeholders are substituted in one pass, so no need to worry about argument itself containing a placeholder.
- All same-numbered placeholders are substituted with same argument. This is in contrast to what single-argument
arg
methods of QString
do.
- Always provide exactly as many arguments as there are unique placeholders. Otherwise you will get error marks in messages at runtime (when compiled in debug mode). The only exception is plural placeholder, which need not be present in singular form.
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("1 file found", "%n files found").subs(n).toString();
ki18ncp("Personal file", "1 file", "%n files").subs(n).toString();
Extra notes on placeholder substitution for ki18n*
calls:
- Plural placeholder
%n
will be substituted by the first supplied argument. If you give non-number as the first argument, you will get a runtime error mark in the message (in debug mode).
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!