From 5cafffed4cb6bccd7d68d28be1b7fbb36971158b Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 27 Jun 2013 19:57:23 +0200 Subject: [PATCH] Initial localization switching. --- CMakeLists.txt | 4 ++ localization/rssguard_cs.ts | 2 +- localization/rssguard_en.ts | 2 +- src/core/defs.h.in | 3 +- src/core/localization.cpp | 71 +++++++++++++++++++++++++++++++++-- src/core/localization.h | 23 +++++++++++- src/gui/formsettings.cpp | 75 ++++++++++++++++++++++++++++++++++++- src/gui/formsettings.h | 3 ++ src/gui/formsettings.ui | 41 +++++++++++++++++++- src/main.cpp | 4 ++ 10 files changed, 216 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59ea95a55..198f77c0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,6 +286,8 @@ if(WIN32) RUNTIME DESTINATION ./) install(DIRECTORY resources/graphics/themes/mini-oxygen DESTINATION ./themes) + install(DIRECTORY resources/graphics/flags + DESTINATION ./) install(FILES resources/graphics/${APP_LOW_NAME}_128.png DESTINATION ./ RENAME ${APP_LOW_NAME}.png) @@ -302,6 +304,8 @@ elseif(UNIX) RUNTIME DESTINATION bin) install(DIRECTORY resources/graphics/themes/mini-oxygen DESTINATION share/${APP_LOW_NAME}/themes) + install(DIRECTORY resources/graphics/flags + DESTINATION share/${APP_LOW_NAME}/) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/resources/desktop/${APP_LOW_NAME}.desktop DESTINATION share/applications) install(FILES resources/graphics/${APP_LOW_NAME}_128.png diff --git a/localization/rssguard_cs.ts b/localization/rssguard_cs.ts index 49d1ecb7b..98e240f8c 100644 --- a/localization/rssguard_cs.ts +++ b/localization/rssguard_cs.ts @@ -92,7 +92,7 @@ LANG_EMAIL Email of translator - optional. - martinrotter@users.sourceforge.net + rotter.martinos@gmail.com diff --git a/localization/rssguard_en.ts b/localization/rssguard_en.ts index 188040f57..92f81d0ef 100644 --- a/localization/rssguard_en.ts +++ b/localization/rssguard_en.ts @@ -92,7 +92,7 @@ LANG_EMAIL Email of translator - optional. - martinrotter@users.sourceforge.net + rotter.martinos@gmail.com diff --git a/src/core/defs.h.in b/src/core/defs.h.in index dfc5fa7d9..292926b51 100644 --- a/src/core/defs.h.in +++ b/src/core/defs.h.in @@ -17,7 +17,6 @@ #define APP_CFG_PATH "data/config/config.ini" #define APP_CFG_GUI "gui" #define APP_CFG_GEN "main" -#define APP_CFG_LANG "localization" #define APP_DB_PATH "data/storage/database.db" #define APP_PREFIX "@CMAKE_INSTALL_PREFIX@" @@ -32,6 +31,7 @@ #define APP_SKIN_PATH APP_PREFIX + QString("/share/rssguard/skins") #define APP_INFO_PATH APP_PREFIX + QString("/share/rssguard/information") #define APP_THEME_PATH APP_PREFIX + QString("/share/rssguard/themes") +#define APP_FLAGS_PATH APP_PREFIX + QString("/share/rssguard/flags") #define APP_ICON_PATH APP_PREFIX + QString("/share/icons/hicolor/128x128/apps/@APP_LOW_NAME@.png") #define APP_ICON_PLAIN_PATH APP_PREFIX + QString("/share/icons/hicolor/128x128/apps/@APP_LOW_NAME@_plain.png") #elif defined(Q_OS_WIN) @@ -39,6 +39,7 @@ #define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins") #define APP_INFO_PATH QApplication::applicationDirPath() #define APP_THEME_PATH QApplication::applicationDirPath() + QString("/themes") +#define APP_FLAGS_PATH QApplication::applicationDirPath() + QString("/flags") #define APP_ICON_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@.png") #define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@_plain.png") #endif diff --git a/src/core/localization.cpp b/src/core/localization.cpp index b33d609c6..3765a6e2f 100644 --- a/src/core/localization.cpp +++ b/src/core/localization.cpp @@ -1,6 +1,71 @@ -#include "localization.h" +#include +#include +#include + +#include "qtsingleapplication/qtsingleapplication.h" +#include "core/localization.h" +#include "core/defs.h" +#include "core/settings.h" -Localization::Localization() -{ +Localization::Localization() { +} + +QList Localization::getInstalledLanguages() { + QList languages; + QDir file_dir(APP_LANG_PATH); + QFileInfoList file_list = file_dir.entryInfoList(QStringList() << "rssguard_*.qm", + QDir::Files, + QDir::Name); + QTranslator translator; + + foreach (QFileInfo file, file_list) { + if (translator.load(file.absoluteFilePath())) { + Language new_language; + new_language.m_name = translator.translate("QObject", "LANG_NAME"); + new_language.m_code = translator.translate("QObject", "LANG_ABBREV"); + new_language.m_version = translator.translate("QObject", "LANG_VERSION"); + new_language.m_author = translator.translate("QObject", "LANG_AUTHOR"); + new_language.m_email = translator.translate("QObject", "LANG_EMAIL"); + + languages << new_language; + } + } + + return languages; +} + +void Localization::set(const QString &locale_name) { + Settings::getInstance()->setValue(APP_CFG_GEN, + "language", + locale_name); +} + +void Localization::load() { + // Obtain all needed data. + QString locale_name = Settings::getInstance()->value(APP_CFG_GEN, + "language", + "en").toString(); + QTranslator qt_translator, app_translator; + + // Load localizations and setup locales. + if (app_translator.load(QString("rssguard_%1.qm").arg(locale_name), + APP_LANG_PATH)) { + qDebug("Application localization %s loaded successfully. Setting up locale.", + qPrintable(locale_name)); + QLocale::setDefault(QLocale(locale_name)); + } + else { + qDebug("Application localization %s was not loaded.", qPrintable(locale_name)); + } + + if (qt_translator.load(QString("qt_%1.qm").arg(locale_name), + APP_LANG_PATH)) { + qDebug("Qt localization %s loaded successfully. Setting up locale.", + qPrintable(locale_name)); + QLocale::setDefault(QLocale(locale_name)); + } + else { + qDebug("Qt localization %s was not loaded.", qPrintable(locale_name)); + } } diff --git a/src/core/localization.h b/src/core/localization.h index f7f909731..0391bbed1 100644 --- a/src/core/localization.h +++ b/src/core/localization.h @@ -1,12 +1,31 @@ #ifndef LOCALIZATION_H #define LOCALIZATION_H +#include -class Localization -{ + +struct Language { + QString m_name; + QString m_code; + QString m_version; + QString m_author; + QString m_email; +}; + +class Localization { // TODO: Finish implementation of this class. private: Localization(); + + public: + // Sets up localization strings and locale from application settings. + static void load(); + + static void set(const QString &locale_name); + + // Returns list of installed application localizations. + // This list is used ie. in settings dialog. + static QList getInstalledLanguages(); }; #endif // LOCALIZATION_H diff --git a/src/gui/formsettings.cpp b/src/gui/formsettings.cpp index 293a76fd8..05b44c143 100644 --- a/src/gui/formsettings.cpp +++ b/src/gui/formsettings.cpp @@ -1,9 +1,13 @@ +#include +#include + #include "gui/formsettings.h" #include "gui/themefactory.h" #include "gui/systemtrayicon.h" #include "gui/formmain.h" #include "core/settings.h" #include "core/defs.h" +#include "core/localization.h" #include "core/systemfactory.h" @@ -14,12 +18,28 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog); setWindowIcon(ThemeFactory::fromTheme("preferences-system")); + // Setup behavior. + m_ui->m_treeLanguages->setColumnCount(5); + m_ui->m_treeLanguages->setHeaderHidden(false); + m_ui->m_treeLanguages->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + m_ui->m_treeLanguages->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + m_ui->m_treeLanguages->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + m_ui->m_treeLanguages->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); + m_ui->m_treeLanguages->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents); + m_ui->m_treeLanguages->setHeaderLabels(QStringList() + << tr("Language") + << tr("Code") + << tr("Version") + << tr("Author") + << tr("Email")); + // Establish needed connections. connect(this, &FormSettings::accepted, this, &FormSettings::saveSettings); // Load all settings. loadGeneral(); loadInterface(); + loadLanguage(); } FormSettings::~FormSettings() { @@ -30,9 +50,60 @@ void FormSettings::saveSettings() { // Save all settings. saveGeneral(); saveInterface(); + saveLanguage(); +} - // Make sure that settings is synced. - Settings::getInstance()->checkSettings(); +void FormSettings::loadLanguage() { + QList languages = Localization::getInstalledLanguages(); + + foreach (Language lang, languages) { + QTreeWidgetItem *item = new QTreeWidgetItem(m_ui->m_treeLanguages); + item->setText(0, lang.m_name); + item->setText(1, lang.m_code); + item->setText(2, lang.m_version); + item->setText(3, lang.m_author); + item->setText(4, lang.m_email); + item->setIcon(0, QIcon(APP_FLAGS_PATH + "/" + lang.m_code + ".png")); + } + + QList matching_items = m_ui->m_treeLanguages->findItems(Settings::getInstance()->value(APP_CFG_GEN, + "language", + "en").toString(), + Qt::MatchExactly, + 1); + if (!matching_items.isEmpty()) { + m_ui->m_treeLanguages->setCurrentItem(matching_items[0]); + } +} + +void FormSettings::saveLanguage() { + QString actual_lang = Settings::getInstance()->value(APP_CFG_GEN, + "language", + "en").toString(); + QString new_lang = m_ui->m_treeLanguages->currentItem()->text(1); + + if (new_lang != actual_lang) { + Settings::getInstance()->setValue(APP_CFG_GEN, "language", new_lang); + + QMessageBox msg_question(this); + msg_question.setText(tr("Language of Qonverter was changed. Note that changes will take effect on next Qonverter start.")); + msg_question.setInformativeText(tr("Do you want to restart now?")); + msg_question.setWindowTitle(tr("Language changed")); + msg_question.setIcon(QMessageBox::Question); + msg_question.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msg_question.setDefaultButton(QMessageBox::Yes); + + if (msg_question.exec() == QMessageBox::Yes) { + if (!QProcess::startDetached(qApp->applicationFilePath())) { + QMessageBox::warning(this, + tr("Problem with RSS Guard restart"), + tr("Qonverter couldn't be restarted, please restart it manually for changes to take effect.")); + } + else { + qApp->quit(); + } + } + } } void FormSettings::loadGeneral() { diff --git a/src/gui/formsettings.h b/src/gui/formsettings.h index 95729f7a5..9573c7487 100644 --- a/src/gui/formsettings.h +++ b/src/gui/formsettings.h @@ -27,6 +27,9 @@ class FormSettings : public QDialog { void loadGeneral(); void saveGeneral(); + + void loadLanguage(); + void saveLanguage(); private: Ui::FormSettings *m_ui; diff --git a/src/gui/formsettings.ui b/src/gui/formsettings.ui index 8212f94fe..68a2fa08c 100644 --- a/src/gui/formsettings.ui +++ b/src/gui/formsettings.ui @@ -45,7 +45,7 @@ - 1 + 2 @@ -202,7 +202,44 @@ - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QAbstractItemView::NoEditTriggers + + + 0 + + + false + + + true + + + false + + + 0 + + + + + diff --git a/src/main.cpp b/src/main.cpp index 63577ac45..0a7f13d88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "core/defs.h" #include "core/debugging.h" +#include "core/localization.h" #include "core/settings.h" #include "gui/themefactory.h" #include "gui/formmain.h" @@ -57,6 +58,9 @@ int main(int argc, char *argv[]) { // Add an extra path for non-system icon themes. ThemeFactory::setupSearchPaths(); + // Load localization and setup locale. + Localization::load(); + // These settings needs to be set before any QSettings object. QtSingleApplication::setApplicationName(APP_NAME); QtSingleApplication::setApplicationVersion(APP_VERSION);