attempted to implement localization loading

This commit is contained in:
itsmattkc
2020-11-17 16:04:09 +11:00
parent 8a64ef75d9
commit b9724e3910
14 changed files with 4972 additions and 67 deletions
+16 -11
View File
@@ -43,6 +43,7 @@ add_subdirectory(shaders)
add_subdirectory(task) add_subdirectory(task)
add_subdirectory(threading) add_subdirectory(threading)
add_subdirectory(timeline) add_subdirectory(timeline)
add_subdirectory(ts)
add_subdirectory(tool) add_subdirectory(tool)
add_subdirectory(ui) add_subdirectory(ui)
add_subdirectory(undo) add_subdirectory(undo)
@@ -62,11 +63,25 @@ if(APPLE)
) )
endif() endif()
# Add translations
qt5_add_translation(OLIVE_QM_FILES ${OLIVE_TS_FILES})
set(QRC_BODY "")
foreach(QM_FILE ${OLIVE_QM_FILES})
get_filename_component(QM_FILENAME_COMPONENT ${QM_FILE} NAME_WE)
string(APPEND QRC_BODY "<file alias=\"${QM_FILENAME_COMPONENT}\">${QM_FILE}</file>\n")
endforeach()
configure_file(ts/translations.qrc.in ts/translations.qrc @ONLY)
set(OLIVE_RESOURCES
${OLIVE_RESOURCES}
${CMAKE_CURRENT_BINARY_DIR}/ts/translations.qrc
)
# Add executable # Add executable
add_executable(${OLIVE_TARGET} add_executable(${OLIVE_TARGET}
${OLIVE_SOURCES} ${OLIVE_SOURCES}
${OLIVE_RESOURCES} ${OLIVE_RESOURCES}
${OLIVE_QM_FILES}
) )
if(APPLE) if(APPLE)
@@ -265,16 +280,6 @@ endif()
# Set compiler definitions # Set compiler definitions
target_compile_definitions(${OLIVE_TARGET} PRIVATE ${OLIVE_DEFINITIONS}) target_compile_definitions(${OLIVE_TARGET} PRIVATE ${OLIVE_DEFINITIONS})
set(OLIVE_TS_FILES
# FIXME: Empty variable
)
if(UPDATE_TS)
qt5_create_translation(OLIVE_QM_FILES ${CMAKE_SOURCE_DIR} ${OLIVE_TS_FILES})
else()
qt5_add_translation(OLIVE_QM_FILES ${OLIVE_TS_FILES})
endif()
add_subdirectory(packaging) add_subdirectory(packaging)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
+13 -3
View File
@@ -34,11 +34,11 @@ CommandLineParser::~CommandLineParser()
} }
} }
const CommandLineParser::Option *CommandLineParser::AddOption(const QStringList &strings, const QString &description) const CommandLineParser::Option *CommandLineParser::AddOption(const QStringList &strings, const QString &description, bool takes_arg, const QString &arg_placeholder)
{ {
Option* o = new Option(); Option* o = new Option();
options_.append({strings, description, o}); options_.append({strings, description, o, takes_arg, arg_placeholder});
return o; return o;
} }
@@ -72,6 +72,12 @@ void CommandLineParser::Process(int argc, char **argv)
if (!s.compare(arg_basename, Qt::CaseInsensitive)) { if (!s.compare(arg_basename, Qt::CaseInsensitive)) {
// Flag discovered! // Flag discovered!
o.option->Set(); o.option->Set();
if (o.takes_arg && i+1 < argc) {
o.option->SetSetting(argv[i+1]);
i++;
}
matched_known = true; matched_known = true;
goto found_flag; goto found_flag;
} }
@@ -147,7 +153,11 @@ void CommandLineParser::PrintHelp(const char* filename)
all_args.append(this_arg); all_args.append(this_arg);
} }
printf(" %s\n", all_args.toUtf8().constData()); if (o.arg_placeholder.isEmpty()) {
printf(" %s\n", all_args.toUtf8().constData());
} else {
printf(" %s <%s>\n", all_args.toUtf8().constData(), o.arg_placeholder.toUtf8().constData());
}
printf(" %s\n\n", o.description.toUtf8().constData()); printf(" %s\n\n", o.description.toUtf8().constData());
} }
+24 -22
View File
@@ -33,7 +33,27 @@ public:
DISABLE_COPY_MOVE(CommandLineParser) DISABLE_COPY_MOVE(CommandLineParser)
class Option { class PositionalArgument
{
public:
PositionalArgument() = default;
const QString& GetSetting() const
{
return setting_;
}
void SetSetting(const QString& s)
{
setting_ = s;
}
private:
QString setting_;
};
class Option : public PositionalArgument {
public: public:
Option() Option()
{ {
@@ -55,29 +75,9 @@ public:
}; };
class PositionalArgument
{
public:
PositionalArgument() = default;
const QString& GetSetting() const
{
return setting_;
}
void SetSetting(const QString& s)
{
setting_ = s;
}
private:
QString setting_;
};
CommandLineParser() = default; CommandLineParser() = default;
const Option* AddOption(const QStringList& strings, const QString& description); const Option* AddOption(const QStringList& strings, const QString& description, bool takes_arg = false, const QString& arg_placeholder = QString());
const PositionalArgument* AddPositionalArgument(const QString& name, const QString& description, bool required = false); const PositionalArgument* AddPositionalArgument(const QString& name, const QString& description, bool required = false);
@@ -90,6 +90,8 @@ private:
QStringList args; QStringList args;
QString description; QString description;
Option* option; Option* option;
bool takes_arg;
QString arg_placeholder;
}; };
struct KnownPositionalArgument { struct KnownPositionalArgument {
+1 -1
View File
@@ -68,7 +68,7 @@ void Config::SetDefaults()
SetEntryInternal(QStringLiteral("AudioScrubbing"), NodeParam::kBoolean, true); SetEntryInternal(QStringLiteral("AudioScrubbing"), NodeParam::kBoolean, true);
SetEntryInternal(QStringLiteral("AutorecoveryInterval"), NodeParam::kInt, 1); SetEntryInternal(QStringLiteral("AutorecoveryInterval"), NodeParam::kInt, 1);
SetEntryInternal(QStringLiteral("DiskCacheSaveInterval"), NodeParam::kInt, 10000); SetEntryInternal(QStringLiteral("DiskCacheSaveInterval"), NodeParam::kInt, 10000);
SetEntryInternal(QStringLiteral("Language"), NodeParam::kString, QLocale::system().name()); SetEntryInternal(QStringLiteral("Language"), NodeParam::kString, QString());
SetEntryInternal(QStringLiteral("ScrollZooms"), NodeParam::kBoolean, false); SetEntryInternal(QStringLiteral("ScrollZooms"), NodeParam::kBoolean, false);
SetEntryInternal(QStringLiteral("EnableSeekToImport"), NodeParam::kBoolean, false); SetEntryInternal(QStringLiteral("EnableSeekToImport"), NodeParam::kBoolean, false);
SetEntryInternal(QStringLiteral("EditToolAlsoSeeks"), NodeParam::kBoolean, false); SetEntryInternal(QStringLiteral("EditToolAlsoSeeks"), NodeParam::kBoolean, false);
+45
View File
@@ -83,6 +83,8 @@ Core::Core(const CoreParams& params) :
// Store reference to this object, making the assumption that Core will only ever be made in // Store reference to this object, making the assumption that Core will only ever be made in
// main(). This will obviously break if not. // main(). This will obviously break if not.
instance_ = this; instance_ = this;
translator_ = new QTranslator(this);
} }
Core *Core::instance() Core *Core::instance()
@@ -119,6 +121,9 @@ void Core::Start()
// Load application config // Load application config
Config::Load(); Config::Load();
// Set locale based on either startup arg, config, or auto-detect
SetStartupLocale();
// Declare custom types for Qt signal/slot system // Declare custom types for Qt signal/slot system
DeclareTypesForQt(); DeclareTypesForQt();
@@ -906,6 +911,34 @@ QString Core::GetRecentProjectsFilePath()
return QDir(FileFunctions::GetConfigurationLocation()).filePath(QStringLiteral("recent")); return QDir(FileFunctions::GetConfigurationLocation()).filePath(QStringLiteral("recent"));
} }
void Core::SetStartupLocale()
{
// Set language
if (!core_params_.startup_language().isEmpty()) {
if (translator_->load(core_params_.startup_language())) {
if (QApplication::installTranslator(translator_)) {
qDebug() << "Successfully installed language at" << translator_->filePath();
} else {
qDebug() << "Failed to install translator";
}
return;
} else {
qWarning() << "Failed to load translation file. Falling back to defaults.";
}
}
QString use_locale = Config::Current()[QStringLiteral("Language")].toString();
if (use_locale.isEmpty()) {
// No configured locale, auto-detect the system's locale
use_locale = QLocale::system().name();
}
if (!SetLanguage(use_locale)) {
qWarning() << "Trying to use locale" << use_locale << "but couldn't find a translation for it";
}
}
bool Core::SaveProject(ProjectPtr p) bool Core::SaveProject(ProjectPtr p)
{ {
if (p->filename().isEmpty()) { if (p->filename().isEmpty()) {
@@ -1307,6 +1340,18 @@ bool Core::ValidateFootageInLoadedProject(ProjectPtr project, const QString& pro
return true; return true;
} }
bool Core::SetLanguage(const QString &locale)
{
QApplication::removeTranslator(translator_);
QString resource_path = QStringLiteral(":/ts/%1").arg(locale);
if (translator_->load(resource_path) && QApplication::installTranslator(translator_)) {
return true;
}
return false;
}
bool Core::CloseAllProjects() bool Core::CloseAllProjects()
{ {
return CloseAllProjects(true); return CloseAllProjects(true);
+28
View File
@@ -24,6 +24,7 @@
#include <QFileInfoList> #include <QFileInfoList>
#include <QList> #include <QList>
#include <QTimer> #include <QTimer>
#include <QTranslator>
#include "common/rational.h" #include "common/rational.h"
#include "common/timecodefunctions.h" #include "common/timecodefunctions.h"
@@ -93,11 +94,23 @@ public:
startup_project_ = p; startup_project_ = p;
} }
const QString& startup_language() const
{
return startup_language_;
}
void set_startup_language(const QString& s)
{
startup_language_ = s;
}
private: private:
RunMode mode_; RunMode mode_;
QString startup_project_; QString startup_project_;
QString startup_language_;
bool run_fullscreen_; bool run_fullscreen_;
}; };
@@ -273,6 +286,11 @@ public:
*/ */
bool ValidateFootageInLoadedProject(ProjectPtr project, const QString &project_saved_url); bool ValidateFootageInLoadedProject(ProjectPtr project, const QString &project_saved_url);
/**
* @brief Changes the current language
*/
bool SetLanguage(const QString& locale);
static const uint kProjectVersion; static const uint kProjectVersion;
public slots: public slots:
@@ -431,6 +449,11 @@ private:
*/ */
static QString GetRecentProjectsFilePath(); static QString GetRecentProjectsFilePath();
/**
* @brief Called only on startup to set the locale
*/
void SetStartupLocale();
/** /**
* @brief Saves a specific project * @brief Saves a specific project
*/ */
@@ -527,6 +550,11 @@ private:
*/ */
static Core* instance_; static Core* instance_;
/**
* @brief Internal translator
*/
QTranslator* translator_;
private slots: private slots:
void SaveAutorecovery(); void SaveAutorecovery();
@@ -25,6 +25,7 @@
#include <QPushButton> #include <QPushButton>
#include "common/autoscroll.h" #include "common/autoscroll.h"
#include "core.h"
#include "dialog/sequence/sequence.h" #include "dialog/sequence/sequence.h"
#include "project/item/sequence/sequence.h" #include "project/item/sequence/sequence.h"
@@ -46,34 +47,23 @@ PreferencesGeneralTab::PreferencesGeneralTab()
language_combobox_ = new QComboBox(); language_combobox_ = new QComboBox();
// Add default language (en-US) // Add default language (en-US)
language_combobox_->addItem(QLocale("en_US").nativeLanguageName()); QDir language_dir(QStringLiteral(":/ts"));
QStringList languages = language_dir.entryList();
foreach (const QString& l, languages) {
AddLanguage(l);
}
/* QString current_language = Config::Current()[QStringLiteral("Language")].toString();
// add languages from file if (current_language.isEmpty()) {
QList<QString> translation_paths = get_language_paths(); // No configured language, use system language
current_language = QLocale::system().name();
// iterate through all language search paths // If we don't have a language for this, default to en_US
for (int j=0;j<translation_paths.size();j++) { if (!languages.contains(current_language)) {
QDir translation_dir(translation_paths.at(j)); current_language = QStringLiteral("en_US");
if (translation_dir.exists()) {
QStringList translation_files = translation_dir.entryList({"*.qm"}, QDir::Files | QDir::NoDotAndDotDot);
for (int i=0;i<translation_files.size();i++) {
// get path of translation relative to the application path
QString locale_full_path = translation_dir.filePath(translation_files.at(i));
QString locale_relative_path = QDir(get_app_path()).relativeFilePath(locale_full_path);
QFileInfo locale_file(translation_files.at(i));
QString locale_file_basename = locale_file.baseName();
QString locale_str = locale_file_basename.mid(locale_file_basename.lastIndexOf('_')+1);
language_combobox->addItem(QLocale(locale_str).nativeLanguageName(), locale_relative_path);
if (olive::config.language_file == locale_relative_path) {
language_combobox->setCurrentIndex(language_combobox->count() - 1);
}
}
}
} }
*/ }
language_combobox_->setCurrentIndex(languages.indexOf(current_language));
general_layout->addWidget(language_combobox_, row, 1); general_layout->addWidget(language_combobox_, row, 1);
@@ -112,11 +102,30 @@ PreferencesGeneralTab::PreferencesGeneralTab()
void PreferencesGeneralTab::Accept() void PreferencesGeneralTab::Accept()
{ {
Config::Current()["RectifiedWaveforms"] = rectified_waveforms_->isChecked(); Config::Current()[QStringLiteral("RectifiedWaveforms")] = rectified_waveforms_->isChecked();
Config::Current()["Autoscroll"] = autoscroll_method_->currentData(); Config::Current()[QStringLiteral("Autoscroll")] = autoscroll_method_->currentData();
Config::Current()["DefaultStillLength"] = QVariant::fromValue(rational::fromDouble(default_still_length_->GetValue())); Config::Current()[QStringLiteral("DefaultStillLength")] = QVariant::fromValue(rational::fromDouble(default_still_length_->GetValue()));
QString set_language = language_combobox_->currentData().toString();
if (QLocale::system().name() == set_language) {
// Language is set to the system, assume this is effectively "auto"
set_language = QString();
}
// If the language has changed, set it now
if (Config::Current()[QStringLiteral("Language")].toString() != set_language) {
Config::Current()[QStringLiteral("Language")] = set_language;
Core::instance()->SetLanguage(set_language.isEmpty() ? QLocale::system().name() : set_language);
}
}
void PreferencesGeneralTab::AddLanguage(const QString &locale_name)
{
language_combobox_->addItem(tr("%1 (%2)").arg(QLocale(locale_name).nativeLanguageName(),
locale_name));;
language_combobox_->setItemData(language_combobox_->count() - 1, locale_name);
} }
OLIVE_NAMESPACE_EXIT OLIVE_NAMESPACE_EXIT
@@ -40,6 +40,8 @@ public:
virtual void Accept() override; virtual void Accept() override;
private: private:
void AddLanguage(const QString& locale_name);
QComboBox* language_combobox_; QComboBox* language_combobox_;
QComboBox* autoscroll_method_; QComboBox* autoscroll_method_;
+15
View File
@@ -94,6 +94,12 @@ int main(int argc, char *argv[])
parser.AddOption({QStringLiteral("x"), QStringLiteral("-export")}, parser.AddOption({QStringLiteral("x"), QStringLiteral("-export")},
QCoreApplication::translate("main", "Export only (No GUI)")); QCoreApplication::translate("main", "Export only (No GUI)"));
const CommandLineParser::Option* ts_option =
parser.AddOption({QStringLiteral("-ts")},
QCoreApplication::translate("main", "Override language with file"),
true,
QCoreApplication::translate("main", "qm-file"));
const CommandLineParser::PositionalArgument* project_argument = const CommandLineParser::PositionalArgument* project_argument =
parser.AddPositionalArgument(QStringLiteral("project"), parser.AddPositionalArgument(QStringLiteral("project"),
QCoreApplication::translate("main", "Project to open on startup")); QCoreApplication::translate("main", "Project to open on startup"));
@@ -116,6 +122,14 @@ int main(int argc, char *argv[])
startup_params.set_run_mode(OLIVE_NAMESPACE::Core::CoreParams::kHeadlessExport); startup_params.set_run_mode(OLIVE_NAMESPACE::Core::CoreParams::kHeadlessExport);
} }
if (ts_option->IsSet()) {
if (ts_option->GetSetting().isEmpty()) {
qWarning() << "--ts was set but no translation file was provided";
} else {
startup_params.set_startup_language(ts_option->GetSetting());
}
}
startup_params.set_fullscreen(fullscreen_option->IsSet()); startup_params.set_fullscreen(fullscreen_option->IsSet());
startup_params.set_startup_project(project_argument->GetSetting()); startup_params.set_startup_project(project_argument->GetSetting());
@@ -156,6 +170,7 @@ int main(int argc, char *argv[])
// Start core // Start core
OLIVE_NAMESPACE::Core c(startup_params); OLIVE_NAMESPACE::Core c(startup_params);
c.Start(); c.Start();
int ret = a->exec(); int ret = a->exec();
+20
View File
@@ -0,0 +1,20 @@
# Olive - Non-Linear Video Editor
# Copyright (C) 2019 Olive Team
#
# 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 3 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/>.
set(OLIVE_TS_FILES
ts/en_US.ts
PARENT_SCOPE
)
+4762
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/ts">
@QRC_BODY@
</qresource>
</RCC>
+2 -1
View File
@@ -31,7 +31,8 @@ OLIVE_NAMESPACE_ENTER
/** /**
* @brief A widget that is always dockable within the MainWindow. * @brief A widget that is always dockable within the MainWindow.
*/ */
class PanelWidget : public QDockWidget { class PanelWidget : public QDockWidget
{
Q_OBJECT Q_OBJECT
public: public:
/** /**
+2 -1
View File
@@ -49,7 +49,8 @@ OLIVE_NAMESPACE_ENTER
/** /**
* @brief Olive's main window responsible for docking widgets and the main menu bar. * @brief Olive's main window responsible for docking widgets and the main menu bar.
*/ */
class MainWindow : public QMainWindow { class MainWindow : public QMainWindow
{
Q_OBJECT Q_OBJECT
public: public:
MainWindow(QWidget *parent = nullptr); MainWindow(QWidget *parent = nullptr);