You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

328 lines
14 KiB

/*
* Copyright 2010, 2014 John Layt <john@layt.net>
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "kcmtranslations.h"
#include "../formats/writeexports.h"
#include <KAboutData>
#include <KActionSelector>
#include <KLocalizedString>
#include <KMessageBox>
#include <KPluginFactory>
#include <KMessageWidget>
#include <QListWidget>
#include <QListWidgetItem>
#include <QStandardPaths>
#include "ui_kcmtranslationswidget.h"
K_PLUGIN_FACTORY(KCMTranslationsFactory, registerPlugin<KCMTranslations>();)
KCMTranslations::KCMTranslations(QWidget *parent, const QVariantList &args)
: KCModule(parent, args),
m_ui(new Ui::KCMTranslationsWidget),
m_messageWidget(0)
{
KAboutData *about = new KAboutData(QStringLiteral("KCMTranslations"),
i18n("Translations"),
QString(),
i18n("Configure Plasma translations"),
KAboutLicense::GPL);
about->addAuthor(i18n("John Layt"), i18n("Maintainer"), QStringLiteral("jlayt@kde.net"));
setAboutData(about);
m_ui->setupUi(this);
// Get the current config
m_config = KConfigGroup(KSharedConfig::openConfig(configFile), "Translations");
// Set up UI to respond to user changing the translation selection
connect(m_ui->m_selectTranslations, &KActionSelector::added, this, &KCMTranslations::changedTranslationsSelected);
connect(m_ui->m_selectTranslations, &KActionSelector::removed, this, &KCMTranslations::changedTranslationsAvailable);
connect(m_ui->m_selectTranslations, &KActionSelector::movedUp, this, &KCMTranslations::changedTranslationsSelected);
connect(m_ui->m_selectTranslations, &KActionSelector::movedDown, this, &KCMTranslations::changedTranslationsSelected);
// If user clicks the Install button, trigger distro specific install routine
connect(m_ui->m_buttonTranslationsInstall, &QPushButton::clicked, this, &KCMTranslations::installTranslations);
// Hide the Install button, this will be activated by those distros that support this feature.
m_ui->m_buttonTranslationsInstall->setHidden(true);
}
KCMTranslations::~KCMTranslations()
{
delete m_ui;
}
// Reimp
// Load == User has clicked on Reset to restore saved settings
// Also gets called automatically called after constructor
void KCMTranslations::load()
{
// Get the currently installed translations for Plasma
// TODO May want to later add all installed .po files on system?
m_installedTranslations.clear();
m_installedTranslations = KLocalizedString::availableDomainTranslations("systemsettings").toList();
// Load the current user translations
loadTranslations();
// Check if any of the current user translations are no longer installed
// If any missing remove them and save the settings, then tell the user
QStringList missingLanguages;
QStringList availableLanguages;
if (!m_config.isEntryImmutable(lcLanguage)) {
foreach (const QString &languageCode, m_kcmTranslations) {
if (m_installedTranslations.contains(languageCode)) {
availableLanguages.append(languageCode);
} else {
missingLanguages.append(languageCode);
}
}
m_config.writeEntry(lcLanguage, availableLanguages.join(QStringLiteral(":")));
m_config.sync();
m_config.config()->reparseConfiguration();
loadTranslations();
}
// Then update all the widgets to use the new settings
initWidgets();
if (missingLanguages.count()) {
const QString txt = i18ncp("%1 is the language code",
"The translation files for the language with the code '%2' "
"could not be found. The "
"language has been removed from your configuration. "
"If you want to add it back, please install the "
"localization files for it and add the language again.",
"The translation files for the languages with the codes "
"'%2' could not be found. These "
"languages have been removed from your configuration. "
"If you want to add them back, please install the "
"localization files for it and the languages again.",
missingLanguages.count(),
missingLanguages.join("', '"));
m_messageWidget = new KMessageWidget(this);
m_messageWidget->setMessageType(KMessageWidget::Information);
m_messageWidget->setWordWrap(true);
m_messageWidget->setText(txt);
m_ui->verticalLayout->insertWidget(0, m_messageWidget);
}
}
// Reimp
// Save the new LANGUAGE setting
void KCMTranslations::save()
{
m_config.writeEntry(lcLanguage, m_kcmTranslations.join(QStringLiteral(":")), KConfig::Persistent | KConfig::Global);
m_config.sync();
KMessageBox::information(this,
i18n("Your changes will take effect the next time you log in."),
i18n("Applying Language Settings"),
QStringLiteral("LanguageChangesApplyOnlyToNewlyStartedPrograms"));
load();
writeExports();
}
// Reimp
// Defaults == User has clicked on Defaults to load default settings
// We interpret this to mean the default LANG setting
void KCMTranslations::defaults()
{
// Get the users LANG setting, or if empty the system LANG
KConfigGroup formatsConfig = KConfigGroup(KSharedConfig::openConfig(configFile), "Formats");
QString lang = formatsConfig.readEntry("LANG", QString());
if (lang.isEmpty() || !m_installedTranslations.contains(lang)) {
lang = QLocale::system().name();
}
if (!m_installedTranslations.contains(lang)) {
lang = QStringLiteral("en_US");
}
// Use the available lang as the default
m_kcmTranslations.clear();
m_kcmTranslations.append(lang);
// The update all the widgets to use the new language
initWidgets();
}
void KCMTranslations::loadTranslations()
{
// Load the user translations
m_configTranslations = m_config.readEntry(lcLanguage, QString());
m_kcmTranslations.clear();
m_kcmTranslations = m_configTranslations.split(':', QString::SkipEmptyParts);
}
QString KCMTranslations::quickHelp() const
{
return i18n("<h1>Translations</h1>\n"
"<p>Here you can set your preferred language for translating the "
"user interface of your applications. You can choose a single "
"language, or a list of languages to be applied in sequence. Only "
"language translations that are installed on your system will "
"be listed as available. If your language is not listed then "
"you will need to install it first.</p>");
}
void KCMTranslations::initWidgets()
{
initTranslations();
initTranslationsInstall();
// Init the KCM "Apply" button
emit changed(m_kcmTranslations.join(QStringLiteral(":")) != m_configTranslations);
}
void KCMTranslations::initTranslations()
{
m_ui->m_selectTranslations->blockSignals(true);
m_ui->m_selectTranslations->setAvailableLabel(i18n("Available Languages:"));
QString availableHelp = i18n("This is the list of installed KDE Plasma language "
"translations not currently being used. <br />To use a language "
"translation move it to the 'Preferred Languages' list in "
"the order of preference. <br />If no suitable languages are "
"listed, then you may need to install more language packages "
"using your usual installation method.");
m_ui->m_selectTranslations->availableListWidget()->setToolTip(availableHelp);
m_ui->m_selectTranslations->availableListWidget()->setWhatsThis(availableHelp);
m_ui->m_selectTranslations->setSelectedLabel(i18n("Preferred Languages:"));
QString selectedHelp = i18n("This is the list of installed KDE Plasma language "
"translations currently being used, listed in order of "
"preference. <br />If a translation is not available for the "
"first language in the list, the next language will be used. <br /> "
"If no other translations are available then US English will "
"be used.");
m_ui->m_selectTranslations->selectedListWidget()->setToolTip(selectedHelp);
m_ui->m_selectTranslations->selectedListWidget()->setWhatsThis(selectedHelp);
// Clear the selector before reloading
m_ui->m_selectTranslations->availableListWidget()->clear();
m_ui->m_selectTranslations->selectedListWidget()->clear();
// Load each user selected language into the selected list
foreach (const QString &languageCode, m_kcmTranslations) {
QListWidgetItem *listItem = new QListWidgetItem(m_ui->m_selectTranslations->selectedListWidget());
// TODO This gives the name in the language itself, not in current language, need new QLocale api for that
QString label = QLocale(languageCode).nativeLanguageName();
if (label.isEmpty()) {
label = languageCode;
}
listItem->setText(label);
listItem->setData(Qt::UserRole, languageCode);
}
// Load all the available languages the user hasn't selected into the available list
foreach (const QString &languageCode, m_installedTranslations) {
if (!m_kcmTranslations.contains(languageCode)) {
QListWidgetItem *listItem = new QListWidgetItem(m_ui->m_selectTranslations->availableListWidget());
// TODO This gives the name in the language itself, not in current language, need new QLocale api for that
const QLocale l(languageCode);
QString label = l.nativeLanguageName();
if (label.isEmpty()) {
label = languageCode;
} else if (languageCode.contains(QStringLiteral("@"))) {
label = i18nc("%1 is language name, %2 is language code name", "%1 (%2)", label, languageCode);
} else if (l.name() != languageCode) {
if (m_installedTranslations.contains(l.name())) {
// KDE languageCode got translated by QLocale to a locale code we also have on the list
// Currently only this happens with pt that gets trasnated to pt_BR
if (languageCode == QLatin1String("pt")) {
label = QLocale(QStringLiteral("pt_PT")).nativeLanguageName();
} else {
qWarning() << "Language code morphed into another existing language code, please report" << languageCode << l.name();
label = i18nc("%1 is language name, %2 is language code name", "%1 (%2)", label, languageCode);
}
}
}
listItem->setText(label);
listItem->setData(Qt::UserRole, languageCode);
}
}
m_ui->m_selectTranslations->availableListWidget()->sortItems();
// Default to selecting the first Selected language,
// otherwise the first Available language,
// otherwise no languages so disable all buttons
if (m_ui->m_selectTranslations->selectedListWidget()->count() > 0) {
m_ui->m_selectTranslations->selectedListWidget()->setCurrentRow(0);
} else if (m_ui->m_selectTranslations->availableListWidget()->count() > 0) {
m_ui->m_selectTranslations->availableListWidget()->setCurrentRow(0);
}
// If the setting is locked down by Kiosk, then don't let the user make any changes
if (m_config.isEntryImmutable(lcLanguage)) {
m_ui->m_selectTranslations->setEnabled(false);
}
m_ui->m_selectTranslations->blockSignals(false);
}
void KCMTranslations::changedTranslationsAvailable(QListWidgetItem *item)
{
Q_UNUSED(item);
m_ui->m_selectTranslations->availableListWidget()->sortItems();
int row = m_ui->m_selectTranslations->availableListWidget()->currentRow();
changedTranslations();
m_ui->m_selectTranslations->availableListWidget()->setCurrentRow(row);
}
void KCMTranslations::changedTranslationsSelected(QListWidgetItem *item)
{
Q_UNUSED(item);
int row = m_ui->m_selectTranslations->selectedListWidget()->currentRow();
changedTranslations();
m_ui->m_selectTranslations->selectedListWidget()->setCurrentRow(row);
}
void KCMTranslations::changedTranslations()
{
// Read the list of all Selected translations from the selector widget
m_kcmTranslations.clear();
for (int i = 0; i < m_ui->m_selectTranslations->selectedListWidget()->count(); ++i) {
m_kcmTranslations.append(m_ui->m_selectTranslations->selectedListWidget()->item(i)->data(Qt::UserRole).toString());
}
initWidgets();
}
void KCMTranslations::initTranslationsInstall()
{
m_ui->m_buttonTranslationsInstall->blockSignals(true);
m_ui->m_buttonTranslationsInstall->setText(i18n("Install more languages"));
QString helpText = i18n("<p>Click here to install more languages</p>");
m_ui->m_buttonTranslationsInstall->setToolTip(helpText);
m_ui->m_buttonTranslationsInstall->setWhatsThis(helpText);
m_ui->m_buttonTranslationsInstall->blockSignals(false);
}
void KCMTranslations::installTranslations()
{
// User has clicked Install Languages button, trigger distro specific install routine
}
#include "kcmtranslations.moc"