mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Add initial support for translations.
This commit is contained in:
parent
becd3a0019
commit
28694ae687
8
.tx/config
Normal file
8
.tx/config
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[main]
|
||||||
|
host = https://www.transifex.com
|
||||||
|
|
||||||
|
[keepassx.keepassx_ents]
|
||||||
|
source_file = share/translations/keepassx_en.ts
|
||||||
|
file_filter = share/translations/keepassx_<lang>.ts
|
||||||
|
source_lang = en
|
||||||
|
type = QT
|
@ -13,6 +13,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
add_subdirectory(translations)
|
||||||
|
|
||||||
file(GLOB DATABASE_ICONS icons/database/*.png)
|
file(GLOB DATABASE_ICONS icons/database/*.png)
|
||||||
|
|
||||||
install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
|
install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
|
||||||
|
26
share/translations/CMakeLists.txt
Normal file
26
share/translations/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
#
|
||||||
|
# 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 or (at your option)
|
||||||
|
# version 3 of the License.
|
||||||
|
#
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
file(GLOB TRANSLATION_FILES *.ts)
|
||||||
|
get_filename_component(TRANSLATION_EN_ABS keepassx_en.ts ABSOLUTE)
|
||||||
|
list(REMOVE_ITEM TRANSLATION_FILES keepassx_en.ts)
|
||||||
|
list(REMOVE_ITEM TRANSLATION_FILES ${TRANSLATION_EN_ABS})
|
||||||
|
message(STATUS ${TRANSLATION_FILES})
|
||||||
|
|
||||||
|
qt4_add_translation(QM_FILES ${TRANSLATION_FILES})
|
||||||
|
|
||||||
|
install(FILES ${QM_FILES} DESTINATION ${DATA_INSTALL_DIR}/translations)
|
||||||
|
add_custom_target(translations DEPENDS ${QM_FILES})
|
||||||
|
add_dependencies(${PROGNAME} translations)
|
1175
share/translations/keepassx_de.ts
Normal file
1175
share/translations/keepassx_de.ts
Normal file
File diff suppressed because it is too large
Load Diff
1189
share/translations/keepassx_en.ts
Normal file
1189
share/translations/keepassx_en.ts
Normal file
File diff suppressed because it is too large
Load Diff
41
share/translations/keepassx_en_plurals.ts
Normal file
41
share/translations/keepassx_en_plurals.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.0" language="en_US">
|
||||||
|
<context>
|
||||||
|
<name>DatabaseWidget</name>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>Do you really want to move %n entry(s) to the recycle bin?</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>Do you really want to move %n entry to the recycle bin?</numerusform>
|
||||||
|
<numerusform>Do you really want to move %n entries to the recycle bin?</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>EditEntryWidget</name>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%n week(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%n week</numerusform>
|
||||||
|
<numerusform>%n weeks</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>%n month(s)</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>%n month</numerusform>
|
||||||
|
<numerusform>%n months</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>EditWidgetIcons</name>
|
||||||
|
<message numerus="yes">
|
||||||
|
<source>Can't delete icon. Still used by %n item(s).</source>
|
||||||
|
<translation>
|
||||||
|
<numerusform>Can't delete icon. Still used by %n item.</numerusform>
|
||||||
|
<numerusform>Can't delete icon. Still used by %n items.</numerusform>
|
||||||
|
</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
8
share/translations/update.sh
Executable file
8
share/translations/update.sh
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
BASEDIR=$(dirname $0)
|
||||||
|
|
||||||
|
cd $BASEDIR/../..
|
||||||
|
|
||||||
|
lupdate -no-ui-lines -disable-heuristic similartext -locations none -no-obsolete src -ts share/translations/keepassx_en.ts
|
||||||
|
lupdate -no-ui-lines -disable-heuristic similartext -locations none -pluralonly src -ts share/translations/keepassx_en_plurals.ts
|
@ -50,6 +50,7 @@ set(keepassx_SOURCES
|
|||||||
core/TimeInfo.cpp
|
core/TimeInfo.cpp
|
||||||
core/ToDbExporter.cpp
|
core/ToDbExporter.cpp
|
||||||
core/Tools.cpp
|
core/Tools.cpp
|
||||||
|
core/Translator.cpp
|
||||||
core/Uuid.cpp
|
core/Uuid.cpp
|
||||||
core/qcommandlineoption.cpp
|
core/qcommandlineoption.cpp
|
||||||
core/qcommandlineparser.cpp
|
core/qcommandlineparser.cpp
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#define KEEPASSX_VERSION "${KEEPASSX_VERSION}"
|
#define KEEPASSX_VERSION "${KEEPASSX_VERSION}"
|
||||||
|
|
||||||
#define KEEPASSX_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
|
#define KEEPASSX_SOURCE_DIR "${CMAKE_SOURCE_DIR}"
|
||||||
|
#define KEEPASSX_BINARY_DIR "${CMAKE_BINARY_DIR}"
|
||||||
|
|
||||||
#define KEEPASSX_PLUGIN_DIR "${PLUGIN_INSTALL_DIR}"
|
#define KEEPASSX_PLUGIN_DIR "${PLUGIN_INSTALL_DIR}"
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ void Config::init(const QString& fileName)
|
|||||||
m_defaults.insert("security/lockdatabaseidlesec", 10);
|
m_defaults.insert("security/lockdatabaseidlesec", 10);
|
||||||
m_defaults.insert("security/passwordscleartext", false);
|
m_defaults.insert("security/passwordscleartext", false);
|
||||||
m_defaults.insert("security/autotypeask", true);
|
m_defaults.insert("security/autotypeask", true);
|
||||||
|
m_defaults.insert("GUI/Language", "system");
|
||||||
}
|
}
|
||||||
|
|
||||||
Config* Config::instance()
|
Config* Config::instance()
|
||||||
|
120
src/core/Translator.cpp
Normal file
120
src/core/Translator.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 or (at your option)
|
||||||
|
* version 3 of the License.
|
||||||
|
*
|
||||||
|
* 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 "Translator.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QLibraryInfo>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
|
#include "config-keepassx.h"
|
||||||
|
#include "core/Config.h"
|
||||||
|
#include "core/FilePath.h"
|
||||||
|
|
||||||
|
void Translator::installTranslator()
|
||||||
|
{
|
||||||
|
QString language = config()->get("GUI/Language").toString();
|
||||||
|
if (language == "system" || language.isEmpty()) {
|
||||||
|
language = QLocale::system().name();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!installTranslator(language)) {
|
||||||
|
// English fallback still needs translations for plurals
|
||||||
|
if (!installTranslator("en_plurals")) {
|
||||||
|
qWarning("Couldn't load translations.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
installQtTranslator(language);
|
||||||
|
|
||||||
|
availableLanguages();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPair<QString, QString> > Translator::availableLanguages()
|
||||||
|
{
|
||||||
|
QStringList paths;
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
paths.append(QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR));
|
||||||
|
#endif
|
||||||
|
paths.append(filePath()->dataPath("translations"));
|
||||||
|
|
||||||
|
QList<QPair<QString, QString> > languages;
|
||||||
|
languages.append(QPair<QString, QString>("system", "System default"));
|
||||||
|
|
||||||
|
QRegExp regExp("keepassx_([a-zA-Z_]+)\\.qm", Qt::CaseInsensitive, QRegExp::RegExp2);
|
||||||
|
Q_FOREACH (const QString& path, paths) {
|
||||||
|
Q_FOREACH (const QString& filename, QDir(path).entryList()) {
|
||||||
|
if (regExp.exactMatch(filename)) {
|
||||||
|
QString langcode = regExp.cap(1);
|
||||||
|
if (langcode == "en_plurals") {
|
||||||
|
langcode = "en";
|
||||||
|
}
|
||||||
|
|
||||||
|
languages.append(QPair<QString, QString>(langcode,
|
||||||
|
QLocale::languageToString(QLocale(langcode).language())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Translator::installTranslator(const QString& language)
|
||||||
|
{
|
||||||
|
QStringList paths;
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
paths.append(QString("%1/share/translations").arg(KEEPASSX_BINARY_DIR));
|
||||||
|
#endif
|
||||||
|
paths.append(filePath()->dataPath("translations"));
|
||||||
|
|
||||||
|
Q_FOREACH (const QString& path, paths) {
|
||||||
|
if (installTranslator(language, path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Translator::installTranslator(const QString& language, const QString& path)
|
||||||
|
{
|
||||||
|
QTranslator* translator = new QTranslator(qApp);
|
||||||
|
if (translator->load(QString("keepassx_").append(language), path)) {
|
||||||
|
QCoreApplication::installTranslator(translator);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete translator;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Translator::installQtTranslator(const QString& language)
|
||||||
|
{
|
||||||
|
QTranslator* qtTranslator = new QTranslator(qApp);
|
||||||
|
if (qtTranslator->load(QString("%1/qt_%2").arg(QLibraryInfo::location(QLibraryInfo::TranslationsPath), language))) {
|
||||||
|
QCoreApplication::installTranslator(qtTranslator);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete qtTranslator;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
36
src/core/Translator.h
Normal file
36
src/core/Translator.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
|
*
|
||||||
|
* 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 or (at your option)
|
||||||
|
* version 3 of the License.
|
||||||
|
*
|
||||||
|
* 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 KEEPASSX_TRANSLATOR_H
|
||||||
|
#define KEEPASSX_TRANSLATOR_H
|
||||||
|
|
||||||
|
#include <QPair>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class Translator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void installTranslator();
|
||||||
|
static QList<QPair<QString, QString> > availableLanguages();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool installTranslator(const QString& language);
|
||||||
|
static bool installTranslator(const QString& language, const QString& path);
|
||||||
|
static bool installQtTranslator(const QString& language);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KEEPASSX_TRANSLATOR_H
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "autotype/AutoType.h"
|
#include "autotype/AutoType.h"
|
||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
|
#include "core/Translator.h"
|
||||||
|
|
||||||
SettingsWidget::SettingsWidget(QWidget* parent)
|
SettingsWidget::SettingsWidget(QWidget* parent)
|
||||||
: EditWidget(parent)
|
: EditWidget(parent)
|
||||||
@ -69,6 +70,15 @@ void SettingsWidget::loadSettings()
|
|||||||
m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool());
|
m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool());
|
||||||
m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get("AutoTypeEntryTitleMatch").toBool());
|
m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get("AutoTypeEntryTitleMatch").toBool());
|
||||||
|
|
||||||
|
QList<QPair<QString, QString> > languages = Translator::availableLanguages();
|
||||||
|
for (int i = 0; i < languages.size(); i++) {
|
||||||
|
m_generalUi->languageComboBox->addItem(languages[i].second, languages[i].first);
|
||||||
|
}
|
||||||
|
int defaultIndex = m_generalUi->languageComboBox->findData(config()->get("GUI/Language"));
|
||||||
|
if (defaultIndex > 0) {
|
||||||
|
m_generalUi->languageComboBox->setCurrentIndex(defaultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
if (autoType()->isAvailable()) {
|
if (autoType()->isAvailable()) {
|
||||||
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
|
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
|
||||||
m_globalAutoTypeModifiers = static_cast<Qt::KeyboardModifiers>(config()->get("GlobalAutoTypeModifiers").toInt());
|
m_globalAutoTypeModifiers = static_cast<Qt::KeyboardModifiers>(config()->get("GlobalAutoTypeModifiers").toInt());
|
||||||
@ -105,6 +115,8 @@ void SettingsWidget::saveSettings()
|
|||||||
m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
|
m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
|
||||||
config()->set("AutoTypeEntryTitleMatch",
|
config()->set("AutoTypeEntryTitleMatch",
|
||||||
m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
|
m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
|
||||||
|
int currentLangIndex = m_generalUi->languageComboBox->currentIndex();
|
||||||
|
config()->set("GUI/Language", m_generalUi->languageComboBox->itemData(currentLangIndex).toString());
|
||||||
if (autoType()->isAvailable()) {
|
if (autoType()->isAvailable()) {
|
||||||
config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
|
config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
|
||||||
config()->set("GlobalAutoTypeModifiers",
|
config()->set("GlobalAutoTypeModifiers",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>456</width>
|
<width>456</width>
|
||||||
<height>230</height>
|
<height>288</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
@ -86,6 +86,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QLabel" name="languageLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Language</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QComboBox" name="languageComboBox"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
#include "core/qcommandlineparser.h"
|
#include "core/qcommandlineparser.h"
|
||||||
#include "core/Tools.h"
|
#include "core/Tools.h"
|
||||||
|
#include "core/Translator.h"
|
||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
#include "gui/Application.h"
|
#include "gui/Application.h"
|
||||||
#include "gui/MainWindow.h"
|
#include "gui/MainWindow.h"
|
||||||
@ -66,6 +67,8 @@ int main(int argc, char** argv)
|
|||||||
Config::createConfigFromFile(parser.value(configOption));
|
Config::createConfigFromFile(parser.value(configOption));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Translator::installTranslator();
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
// Don't show menu icons on OSX
|
// Don't show menu icons on OSX
|
||||||
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
|
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||||
|
Loading…
Reference in New Issue
Block a user