[kcmkwin/deco] Support loading translations for UI loaded configs

Qml based Aurorae themes can provided a ui file which gets loaded at
runtime. Obviously such a ui file is not translated. This introduces
quite a hack to load the translated strings.

First of all a new property is added to the service file for
specifying the translation domain to be used for the config UI. If
such a translation domain is set we extract all string properties of
the loaded UI and pass them through ki18nd.
This commit is contained in:
Martin Gräßlin 2014-06-06 08:07:56 +02:00
parent e73f6b2278
commit d0c83ddbf3
9 changed files with 132 additions and 1 deletions

View file

@ -51,3 +51,6 @@ Comment[zh_TW]=KWin 視窗裝飾
[PropertyDef::X-Plasma-MainScript]
Type=QString
[PropertyDef::X-KWin-Config-TranslationDomain]
Type=QString

View file

@ -141,5 +141,6 @@ X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-ServiceTypes=KWin/Decoration
X-KWin-Config-TranslationDomain=kwin_clients
Type=Service

View file

@ -4,6 +4,7 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kcmkwindecoration\")
# need a header file from Aurorae sources
include_directories(
${KWIN_SOURCE_DIR}/clients/aurorae/src/lib
../utils/
)
set(AURORAE_SOURCE_DIR ${KWIN_SOURCE_DIR}/clients/aurorae/src/lib/)
@ -15,6 +16,7 @@ set(kcm_kwindecoration_PART_SRCS
configdialog.cpp
preview.cpp
decorationmodel.cpp
../utils/uitranslator.cpp
${AURORAE_SOURCE_DIR}/auroraetheme.cpp
${AURORAE_SOURCE_DIR}/themeconfig.cpp
)

View file

@ -119,6 +119,7 @@ void DecorationModel::findDecorations()
data.type = DecorationModelData::QmlDecoration;
data.auroraeName = service->property("X-KDE-PluginInfo-Name").toString();
QString scriptName = service->property("X-Plasma-MainScript").toString();
data.configTranslationDomain = service->property(QStringLiteral("X-KWin-Config-TranslationDomain")).toString();
data.qmlPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/decorations/" + data.auroraeName + "/contents/" + scriptName);
if (data.qmlPath.isEmpty()) {
// not a valid QML theme
@ -251,6 +252,8 @@ QVariant DecorationModel::data(const QModelIndex& index, int role) const
return m_decorations[ index.row()].qmlPath;
case CloseOnDblClickRole:
return m_decorations[index.row()].closeDblClick;
case ConfigTranslationDomain:
return m_decorations[index.row()].configTranslationDomain;
default:
return QVariant();
}

View file

@ -56,6 +56,7 @@ public:
QString license;
QString auroraeName;
QString qmlPath;
QString configTranslationDomain;
KDecorationDefines::BorderSize borderSize;
KDecorationDefines::BorderSize buttonSize;
/**
@ -88,7 +89,8 @@ public:
BorderSizesRole = Qt::UserRole + 12,
ButtonSizeRole = Qt::UserRole + 13,
QmlMainScriptRole = Qt::UserRole + 14,
CloseOnDblClickRole = Qt::UserRole + 15
CloseOnDblClickRole = Qt::UserRole + 15,
ConfigTranslationDomain = Qt::UserRole + 16
};
explicit DecorationModel(KSharedConfigPtr config, QObject* parent = nullptr);
~DecorationModel();

View file

@ -34,6 +34,7 @@
#include "decorationmodel.h"
#include "auroraetheme.h"
#include "preview.h"
#include "uitranslator.h"
// Qt
#include <QtDBus/QtDBus>
#include <QSortFilterProxyModel>
@ -79,6 +80,7 @@ KWinDecorationModule::KWinDecorationModule(QWidget* parent, const QVariantList &
, m_configLoaded(false)
, m_decorationButtons(new DecorationButtons(this))
, m_listView(new QQuickView())
, m_translator(new KLocalizedTranslator(this))
{
qmlRegisterType<Aurorae::AuroraeTheme>("org.kde.kwin.aurorae", 0, 1, "AuroraeTheme");
qmlRegisterType<PreviewItem>("org.kde.kwin.kcmdecoration", 0, 1, "PreviewItem");
@ -99,6 +101,8 @@ KWinDecorationModule::KWinDecorationModule(QWidget* parent, const QVariantList &
i18n("(c) 2001 Karol Szwed"));
about->addAuthor(i18n("Karol Szwed"), QString(), "gallium@kde.org");
setAboutData(about);
QCoreApplication::instance()->installTranslator(m_translator);
}
@ -403,15 +407,22 @@ void KWinDecorationModule::slotConfigureDecoration()
KConfigGroup configGroup = auroraeConfig->group(packageName);
KConfigLoader *skeleton = new KConfigLoader(configGroup, &configFile, dlg);
// load the ui file
m_translator->setTranslationDomain(index.data(DecorationModel::ConfigTranslationDomain).toString());
QUiLoader *loader = new QUiLoader(dlg);
loader->setLanguageChangeEnabled(true);
QFile uiFile(uiPath);
uiFile.open(QFile::ReadOnly);
QWidget *customConfigForm = loader->load(&uiFile, form);
m_translator->addContextToMonitor(customConfigForm->objectName());
uiFile.close();
form->layout()->addWidget(customConfigForm);
// connect the ui file with the skeleton
configManager = new KConfigDialogManager(customConfigForm, skeleton);
configManager->updateWidgets();
// send a custom event to the translator to retranslate using our translator
QEvent le(QEvent::LanguageChange);
QCoreApplication::sendEvent(customConfigForm, &le);
}
}
if (dlg->exec() == QDialog::Accepted) {

View file

@ -44,6 +44,7 @@ namespace KWin
{
class DecorationModel;
class KLocalizedTranslator;
class KWinDecorationForm : public QWidget, public Ui::KWinDecorationForm
{
@ -133,6 +134,8 @@ private:
DecorationButtons *m_decorationButtons;
QScopedPointer<QQuickView> m_listView;
KLocalizedTranslator *m_translator;
};
} //namespace

View file

@ -0,0 +1,58 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "uitranslator.h"
// frameworks
#include <KLocalizedString>
// Qt
#include <QComboBox>
#include <QMetaObject>
#include <QMetaProperty>
namespace KWin
{
KLocalizedTranslator::KLocalizedTranslator(QObject* parent)
: QTranslator(parent)
{
}
void KLocalizedTranslator::setTranslationDomain(const QString &translationDomain)
{
m_translationDomain = translationDomain;
}
void KLocalizedTranslator::addContextToMonitor(const QString &context)
{
m_monitoredContexts.insert(context);
}
QString KLocalizedTranslator::translate(const char *context, const char *sourceText, const char *disambiguation, int n) const
{
if (m_translationDomain.isEmpty() || !m_monitoredContexts.contains(QString::fromUtf8(context))) {
return QTranslator::translate(context, sourceText, disambiguation, n);
}
if (qstrlen(disambiguation) == 0) {
return ki18nd(m_translationDomain.toUtf8().constData(), sourceText).toString();
} else {
return ki18ndc(m_translationDomain.toUtf8().constData(), disambiguation, sourceText).toString();
}
}
} // namespace KWin

View file

@ -0,0 +1,48 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2014 Martin Gräßlin <mgraesslin@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_KCMUTILS_UITRANSLATOR_H
#define KWIN_KCMUTILS_UITRANSLATOR_H
#include <QSet>
#include <QTranslator>
class QWidget;
namespace KWin
{
class KLocalizedTranslator : public QTranslator
{
Q_OBJECT
public:
explicit KLocalizedTranslator(QObject *parent = 0);
QString translate(const char *context, const char *sourceText, const char *disambiguation = 0, int n = -1) const override;
void setTranslationDomain(const QString &translationDomain);
void addContextToMonitor(const QString &context);
private:
QString m_translationDomain;
QSet<QString> m_monitoredContexts;
};
}
#endif