diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 7e7487ba5..f4ef97053 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -43,6 +43,7 @@ add_subdirectory(shaders) add_subdirectory(task) add_subdirectory(threading) add_subdirectory(timeline) +add_subdirectory(ts) add_subdirectory(tool) add_subdirectory(ui) add_subdirectory(undo) @@ -62,11 +63,25 @@ if(APPLE) ) 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 "${QM_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(${OLIVE_TARGET} ${OLIVE_SOURCES} ${OLIVE_RESOURCES} - ${OLIVE_QM_FILES} ) if(APPLE) @@ -265,16 +280,6 @@ endif() # Set compiler 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) if(DOXYGEN_FOUND) diff --git a/app/common/commandlineparser.cpp b/app/common/commandlineparser.cpp index 9585a0c69..ab58322b1 100644 --- a/app/common/commandlineparser.cpp +++ b/app/common/commandlineparser.cpp @@ -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(); - options_.append({strings, description, o}); + options_.append({strings, description, o, takes_arg, arg_placeholder}); return o; } @@ -72,6 +72,12 @@ void CommandLineParser::Process(int argc, char **argv) if (!s.compare(arg_basename, Qt::CaseInsensitive)) { // Flag discovered! o.option->Set(); + + if (o.takes_arg && i+1 < argc) { + o.option->SetSetting(argv[i+1]); + i++; + } + matched_known = true; goto found_flag; } @@ -147,7 +153,11 @@ void CommandLineParser::PrintHelp(const char* filename) 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()); } diff --git a/app/common/commandlineparser.h b/app/common/commandlineparser.h index 10114d86a..6d1b3f5a3 100644 --- a/app/common/commandlineparser.h +++ b/app/common/commandlineparser.h @@ -33,7 +33,27 @@ public: 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: 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; - 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); @@ -90,6 +90,8 @@ private: QStringList args; QString description; Option* option; + bool takes_arg; + QString arg_placeholder; }; struct KnownPositionalArgument { diff --git a/app/config/config.cpp b/app/config/config.cpp index 2b317a51c..7eda39428 100644 --- a/app/config/config.cpp +++ b/app/config/config.cpp @@ -68,7 +68,7 @@ void Config::SetDefaults() SetEntryInternal(QStringLiteral("AudioScrubbing"), NodeParam::kBoolean, true); SetEntryInternal(QStringLiteral("AutorecoveryInterval"), NodeParam::kInt, 1); 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("EnableSeekToImport"), NodeParam::kBoolean, false); SetEntryInternal(QStringLiteral("EditToolAlsoSeeks"), NodeParam::kBoolean, false); diff --git a/app/core.cpp b/app/core.cpp index 791e8b174..73177df15 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -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 // main(). This will obviously break if not. instance_ = this; + + translator_ = new QTranslator(this); } Core *Core::instance() @@ -119,6 +121,9 @@ void Core::Start() // Load application config Config::Load(); + // Set locale based on either startup arg, config, or auto-detect + SetStartupLocale(); + // Declare custom types for Qt signal/slot system DeclareTypesForQt(); @@ -906,6 +911,34 @@ QString Core::GetRecentProjectsFilePath() 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) { if (p->filename().isEmpty()) { @@ -1307,6 +1340,18 @@ bool Core::ValidateFootageInLoadedProject(ProjectPtr project, const QString& pro 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() { return CloseAllProjects(true); diff --git a/app/core.h b/app/core.h index 62257a36a..8e891de28 100644 --- a/app/core.h +++ b/app/core.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "common/rational.h" #include "common/timecodefunctions.h" @@ -93,11 +94,23 @@ public: startup_project_ = p; } + const QString& startup_language() const + { + return startup_language_; + } + + void set_startup_language(const QString& s) + { + startup_language_ = s; + } + private: RunMode mode_; QString startup_project_; + QString startup_language_; + bool run_fullscreen_; }; @@ -273,6 +286,11 @@ public: */ bool ValidateFootageInLoadedProject(ProjectPtr project, const QString &project_saved_url); + /** + * @brief Changes the current language + */ + bool SetLanguage(const QString& locale); + static const uint kProjectVersion; public slots: @@ -431,6 +449,11 @@ private: */ static QString GetRecentProjectsFilePath(); + /** + * @brief Called only on startup to set the locale + */ + void SetStartupLocale(); + /** * @brief Saves a specific project */ @@ -527,6 +550,11 @@ private: */ static Core* instance_; + /** + * @brief Internal translator + */ + QTranslator* translator_; + private slots: void SaveAutorecovery(); diff --git a/app/dialog/preferences/tabs/preferencesgeneraltab.cpp b/app/dialog/preferences/tabs/preferencesgeneraltab.cpp index 520728c36..bb0edc144 100644 --- a/app/dialog/preferences/tabs/preferencesgeneraltab.cpp +++ b/app/dialog/preferences/tabs/preferencesgeneraltab.cpp @@ -25,6 +25,7 @@ #include #include "common/autoscroll.h" +#include "core.h" #include "dialog/sequence/sequence.h" #include "project/item/sequence/sequence.h" @@ -46,34 +47,23 @@ PreferencesGeneralTab::PreferencesGeneralTab() language_combobox_ = new QComboBox(); // 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); + } - /* - // add languages from file - QList translation_paths = get_language_paths(); + QString current_language = Config::Current()[QStringLiteral("Language")].toString(); + if (current_language.isEmpty()) { + // No configured language, use system language + current_language = QLocale::system().name(); - // iterate through all language search paths - for (int j=0;jaddItem(QLocale(locale_str).nativeLanguageName(), locale_relative_path); - - if (olive::config.language_file == locale_relative_path) { - language_combobox->setCurrentIndex(language_combobox->count() - 1); - } - } - } + // If we don't have a language for this, default to en_US + if (!languages.contains(current_language)) { + current_language = QStringLiteral("en_US"); } - */ + } + language_combobox_->setCurrentIndex(languages.indexOf(current_language)); general_layout->addWidget(language_combobox_, row, 1); @@ -112,11 +102,30 @@ PreferencesGeneralTab::PreferencesGeneralTab() 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 diff --git a/app/dialog/preferences/tabs/preferencesgeneraltab.h b/app/dialog/preferences/tabs/preferencesgeneraltab.h index 609d182c9..f8cea3b59 100644 --- a/app/dialog/preferences/tabs/preferencesgeneraltab.h +++ b/app/dialog/preferences/tabs/preferencesgeneraltab.h @@ -40,6 +40,8 @@ public: virtual void Accept() override; private: + void AddLanguage(const QString& locale_name); + QComboBox* language_combobox_; QComboBox* autoscroll_method_; diff --git a/app/main.cpp b/app/main.cpp index 3cfa34db2..1392e816c 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -94,6 +94,12 @@ int main(int argc, char *argv[]) parser.AddOption({QStringLiteral("x"), QStringLiteral("-export")}, 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 = parser.AddPositionalArgument(QStringLiteral("project"), 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); } + 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_startup_project(project_argument->GetSetting()); @@ -156,6 +170,7 @@ int main(int argc, char *argv[]) // Start core OLIVE_NAMESPACE::Core c(startup_params); + c.Start(); int ret = a->exec(); diff --git a/app/ts/CMakeLists.txt b/app/ts/CMakeLists.txt new file mode 100644 index 000000000..ba9b71d9c --- /dev/null +++ b/app/ts/CMakeLists.txt @@ -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 . + +set(OLIVE_TS_FILES + ts/en_US.ts + PARENT_SCOPE +) diff --git a/app/ts/en_US.ts b/app/ts/en_US.ts new file mode 100644 index 000000000..15dfc47ab --- /dev/null +++ b/app/ts/en_US.ts @@ -0,0 +1,4762 @@ + + + + + AboutDialog + + + About %1 + + + + + Olive is a non-linear video editor. This software is free and protected by the GNU GPL. + + + + + Olive Team is obliged to inform users that Olive source code is available for download from its website. + + + + + ActionSearch + + + Search for action... + + + + + AudioInput + + + Audio Input + + + + + Audio + + + + + Import an audio footage stream. + + + + + AudioMonitorPanel + + + Audio Monitor + + + + + AudioParams + + + %1 Hz + + + + + Mono + + + + + Stereo + + + + + 2.1 + + + + + 5.1 + + + + + 7.1 + + + + + Unknown (0x%1) + + + + + Block + + + Length + + + + + Media In + + + + + Enabled + + + + + Speed + + + + + BlurFilterNode + + + Blur + + + + + Blurs an image. + + + + + Input + + + + + Method + + + + + Box + + + + + Gaussian + + + + + Radius + + + + + Horizontal + + + + + Vertical + + + + + Repeat Edge Pixels + + + + + ClipBlock + + + Clip + + + + + A time-based node that represents a media source. + + + + + Buffer + + + + + ColorDialog + + + Select Color + + + + + ColorSpaceChooser + + + Color Management + + + + + Input: + + + + + Color Space: + + + + + Display: + + + + + View: + + + + + Look: + + + + + (None) + + + + + ColorValuesTab + + + Red + + + + + Green + + + + + Blue + + + + + ColorValuesWidget + + + Preview + + + + + Input + + + + + Reference + + + + + Display + + + + + Config + + + Error loading settings + + + + + Failed to load application settings. This session will use defaults. + +%1 + + + + + Error saving settings + + + + + Failed to save application settings. The application may lack write permissions to this location. + + + + + ConformTask + + + Conforming Audio %1:%2 + + + + + Core + + + Import error + + + + + Nothing to import + + + + + Importing... + + + + + Import footage... + + + + + Failed to import footage + + + + + Failed to find active Project panel + + + + + No Active Project + + + + + No project is currently open to set the properties for + + + + + Failed to create new folder + + + + + + Failed to find active project + + + + + New Folder + + + + + Failed to create new sequence + + + + + Possible image sequence detected + + + + + The file '%1' looks like it might be part of an image sequence. Would you like to import it as such? + + + + + You must specify a project file to export + + + + + Specified project does not exist + + + + + Project contains no sequences, nothing to export + + + + + This project has multiple sequences. Which do you wish to export? + + + + + Enter number (or %1 to cancel): + + + + + Invalid sequence number + + + + + Export succeeded + + + + + Export failed: %1 + + + + + Project failed to load: %1 + + + + + Failed to open startup file + + + + + The project "%1" doesn't exist. A new project will be started instead. + + + + + + Missing OpenTimelineIO Libraries + + + + + + This build was compiled without OpenTimelineIO and therefore cannot open OpenTimelineIO files. + + + + + Save Project + + + + + + Error + + + + + This Sequence is empty. There is nothing to export. + + + + + No valid sequence detected. + +Make sure a sequence is loaded and it has a connected Viewer node. + + + + + Olive Project + + + + + OpenTimelineIO + + + + + Save Project As + + + + + Load Project + + + + + Label Node + + + + + Set node label + + + + + Sequence %1 + + + + + Cannot open recent project + + + + + The project "%1" doesn't exist. Would you like to remove this file from the recent list? + + + + + Unsaved Changes + + + + + The project '%1' has unsaved changes. Would you like to save them? + + + + + Save + + + + + Save All + + + + + Don't Save + + + + + Don't Save All + + + + + Failed to cache sequence + + + + + No active viewer found with this sequence. + + + + + Open Project + + + + + CrashHandlerDialog + + + Olive + + + + + We're sorry, Olive has crashed. Please help us fix it by sending an error report. + + + + + Describe what you were doing in as much detail as possible. If you can, provide steps to reproduce this crash. + + + + + Crash Report: + + + + + Send Error Report + + + + + Don't Send + + + + + Waiting for crash report to be generated... + + + + + Upload Failed + + + + + Failed to send error report. Please try again later. + + + + + No Crash Summary + + + + + Are you sure you want to send an error report with no crash summary? + + + + + CrossDissolveTransition + + + Cross Dissolve + + + + + Smoothly transition between two clips. + + + + + CurvePanel + + + Curve Editor + + + + + CurveView + + + Zoom to Fit + + + + + CurveWidget + + + Linear + + + + + Bezier + + + + + Hold + + + + + DipToColorTransition + + + Dip To Color + + + + + Transition between clips by dipping to a color. + + + + + DiskCacheDialog + + + Disk Cache: %1 + + + + + Disk Cache Settings + + + + + Maximum Disk Cache: + + + + + %1 GB + + + + + + + Clear Disk Cache + + + + + Automatically clear disk cache on close + + + + + Are you sure you want to clear the disk cache in '%1'? + + + + + Disk Cache Cleared + + + + + Disk cache failed to fully clear. You may have to delete the cache files manually. + + + + + Disk Cache Partially Cleared + + + + + DiskManager + + + + Disk Cache Error + + + + + Unable to set custom application disk cache. Using default instead. + + + + + Disk Cache + + + + + You've chosen to change the default disk cache location. This will invalidate your current cache. Would you like to continue? + + + + + Failed to open disk cache at "%1". Try a different folder. + + + + + ElapsedCounterWidget + + + Elapsed: %1 + + + + + Remaining: %1 + + + + + ExportAdvancedVideoDialog + + + Advanced + + + + + Pixel + + + + + Pixel Format: + + + + + Performance + + + + + Threads: + + + + + ExportAudioTab + + + Codec: + + + + + Sample Rate: + + + + + Channel Layout: + + + + + Format: + + + + + ExportCodec + + + DNxHD + + + + + H.264 + + + + + H.265 + + + + + OpenEXR + + + + + PNG + + + + + ProRes + + + + + TIFF + + + + + MP2 + + + + + MP3 + + + + + AAC + + + + + PCM (Uncompressed) + + + + + Unknown + + + + + ExportDialog + + + Filename: + + + + + Browse for exported file filename + + + + + Preset: + + + + + Same As Source - High Quality + + + + + Same As Source - Medium Quality + + + + + Same As Source - Low Quality + + + + + Range: + + + + + Entire Sequence + + + + + In to Out + + + + + Format: + + + + + Export Video + + + + + Export Audio + + + + + Video + + + + + Audio + + + + + + Export + + + + + Preview + + + + + Invalid parameters + + + + + Both video and audio are disabled. There's nothing to export. + + + + + Invalid filename + + + + + The filename must contain the extension "%1". Would you like to append it automatically? + + + + + Failed to create output directory + + + + + The intended output directory doesn't exist and Olive couldn't create it. Please choose a different filename. + + + + + Confirm Overwrite + + + + + The file "%1" already exists. Do you want to overwrite it? + + + + + Invalid Parameters + + + + + Width and height must be multiples of 2. + + + + + ExportFormat + + + DNxHD + + + + + Matroska Video + + + + + MPEG-4 Video + + + + + OpenEXR + + + + + PNG + + + + + TIFF + + + + + QuickTime + + + + + Unknown + + + + + ExportTask + + + Exporting "%1" + + + + + Failed to create encoder + + + + + Failed to open file + + + + + Failed to overwrite "%1". Export has been saved as "%2" instead. + + + + + ExportVideoTab + + + Basic + + + + + Width: + + + + + Height: + + + + + Maintain Aspect Ratio: + + + + + Scaling Method: + + + + + Fit + + + + + Stretch + + + + + Crop + + + + + Frame Rate: + + + + + Pixel Aspect Ratio: + + + + + Interlacing: + + + + + Quality: + + + + + Codec + + + + + Codec: + + + + + Advanced + + + + + FloatSlider + + + %1 dB + + + + + %1% + + + + + Footage + + + %1 FPS + + + + + %1 Hz + + + + + Filename: %1 + + + + + This footage is not valid for use + + + + + FootagePropertiesDialog + + + "%1" Properties + + + + + Name: + + + + + Tracks: + + + + + FootageRelinkDialog + + + Footage + + + + + Filename + + + + + Actions + + + + + Browse + + + + + Relink Footage + + + + + Relink "%1" + + + + + All Files + + + + + FootageViewerPanel + + + Footage Viewer + + + + + GapBlock + + + Gap + + + + + A time-based node that represents an empty space. + + + + + H264BitRateSection + + + Target Bit Rate (Mbps): + + + + + Maximum Bit Rate (Mbps): + + + + + Two-Pass + + + + + H264FileSizeSection + + + Target File Size (MB): + + + + + Two-Pass + + + + + H264Section + + + Compression Method: + + + + + Constant Rate Factor + + + + + Target Bit Rate + + + + + Target File Size + + + + + ImageSection + + + Image Sequence: + + + + + ImportTool + + + Don't ask me again + + + + + No Active Sequence + + + + + No sequence is currently open. Would you like to create one? + + + + + Automatically Detect Parameters From Footage + + + + + Set Parameters Manually + + + + + InterlacedComboBox + + + None (Progressive) + + + + + Top-Field First + + + + + Bottom-Field First + + + + + KeyframePropertiesDialog + + + Keyframe Properties + + + + + In: + + + + + Out: + + + + + Linear + + + + + Hold + + + + + Bezier + + + + + KeyframeViewBase + + + Linear + + + + + Bezier + + + + + Hold + + + + + P&roperties + + + + + LoadOTIOTask + + + Failed to load OpenTimelineIO from file "%1" + + + + + Unknown OpenTimelineIO root element + + + + + Failed to load clip + + + + + MainMenu + + + &Save '%1' + + + + + Save '%1' &As + + + + + Close '%1' + + + + + Close All Except '%1' + + + + + &Save Project + + + + + Save Project &As + + + + + Close Project + + + + + Close All Except Current Project + + + + + (None) + + + + + &File + + + + + &New + + + + + &Open Project + + + + + Open &Recent + + + + + &Clear Recent List + + + + + Sa&ve All Projects + + + + + &Import... + + + + + &Export + + + + + &Media... + + + + + &Project Properties... + + + + + Close All Projects + + + + + E&xit + + + + + &Edit + + + + + Insert + + + + + Overwrite + + + + + Select &All + + + + + Deselect All + + + + + Ripple to In Point + + + + + Ripple to Out Point + + + + + Edit to In Point + + + + + Edit to Out Point + + + + + Delete In/Out Point + + + + + Ripple Delete In/Out Point + + + + + Set/Edit Marker + + + + + &View + + + + + Zoom In + + + + + Zoom Out + + + + + Increase Track Height + + + + + Decrease Track Height + + + + + Toggle Show All + + + + + Full Screen + + + + + Full Screen Viewer + + + + + &Playback + + + + + Go to Start + + + + + Previous Frame + + + + + Play/Pause + + + + + Play In to Out + + + + + Next Frame + + + + + Go to End + + + + + Go to Previous Cut + + + + + Go to Next Cut + + + + + Go to In Point + + + + + Go to Out Point + + + + + Shuttle Left + + + + + Shuttle Stop + + + + + Shuttle Right + + + + + Loop + + + + + &Sequence + + + + + Cache Entire Sequence + + + + + Cache Sequence In/Out + + + + + Maximize Panel + + + + + Lock Panels + + + + + Reset to Default Layout + + + + + &Tools + + + + + Pointer Tool + + + + + Edit Tool + + + + + Ripple Tool + + + + + Rolling Tool + + + + + Razor Tool + + + + + Slip Tool + + + + + Slide Tool + + + + + Hand Tool + + + + + Zoom Tool + + + + + Transition Tool + + + + + Enable Snapping + + + + + Preferences + + + + + &Help + + + + + A&ction Search + + + + + Send &Feedback... + + + + + &About... + + + + + MainStatusBar + + + Welcome to %1 %2 + + + + + Running %1 background tasks + + + + + MainWindow + + + Driver Warning + + + + + Olive has detected your system is using the Nouveau graphics driver. + +This driver is known to have stability and performance issues with Olive. It is highly recommended you install the proprietary NVIDIA driver before continuing to use Olive. + + + + + ManagedDisplayWidget + + + Color Space + + + + + No color manager connected + + + + + Display + + + + + View + + + + + Look + + + + + (None) + + + + + OpenColorIO Error + + + + + Failed to set color configuration: %1 + + + + + ManagedPixelSamplerWidget + + + Display + + + + + Reference + + + + + MathNode + + + Math + + + + + Perform a mathematical operation between two values. + + + + + Method + + + + + + Value + + + + + Add + + + + + Subtract + + + + + Multiply + + + + + Divide + + + + + Power + + + + + MatrixGenerator + + + Orthographic Matrix + + + + + Ortho + + + + + Generate an orthographic matrix using position, rotation, and scale. + + + + + Position + + + + + Rotation + + + + + Scale + + + + + Uniform Scale + + + + + Anchor Point + + + + + MediaInput + + + Footage + + + + + MenuShared + + + &Project + + + + + &Sequence + + + + + &Folder + + + + + Cu&t + + + + + Cop&y + + + + + &Paste + + + + + Paste Insert + + + + + Duplicate + + + + + Delete + + + + + Ripple Delete + + + + + Split + + + + + Set In Point + + + + + Set Out Point + + + + + Reset In Point + + + + + Reset Out Point + + + + + Clear In/Out Point + + + + + Add Default Transition + + + + + Link/Unlink + + + + + Enable/Disable + + + + + Nest + + + + + Frames + + + + + Drop Frame + + + + + Non-Drop Frame + + + + + Milliseconds + + + + + Seconds + + + + + MergeNode + + + Merge + + + + + Merge two textures together. + + + + + Base + + + + + Blend + + + + + Node + + + Input + + + + + Output + + + + + General + + + + + Math + + + + + Color + + + + + Filter + + + + + Timeline + + + + + Generator + + + + + Channel + + + + + Transition + + + + + Uncategorized + + + + + NodeCopyPasteWidget + + + Error pasting nodes + + + + + Failed to paste nodes: %1 + + + + + NodeFactory + + + None + + + + + NodeInput + + + Input + + + + + NodeOutput + + + Output + + + + + NodePanel + + + Node Editor + + + + + NodeParam + + + Value + + + + + None + + + + + Integer + + + + + Float + + + + + Rational + + + + + Boolean + + + + + Color + + + + + Matrix + + + + + Text + + + + + Font + + + + + File + + + + + Texture + + + + + Samples + + + + + Footage + + + + + Vector 2D + + + + + Vector 3D + + + + + Vector 4D + + + + + Unknown + + + + + NodeParamViewArrayWidget + + + + + + + + + %1 elements + + + + + NodeParamViewConnectedLabel + + + Connected to + + + + + Nothing + + + + + Disconnect + + + + + NodeParamViewItem + + + %1 (%2) + + + + + NodeParamViewItemBody + + + %1: + + + + + NodeParamViewKeyframeControl + + + Warning + + + + + Are you sure you want to disable keyframing on this value? This will clear all existing keyframes. + + + + + NodeTablePanel + + + Table View + + + + + NodeTableView + + + Type + + + + + Source + + + + + R/X + + + + + G/Y + + + + + B/Z + + + + + A/W + + + + + (unknown) + + + + + NodeTreeView + + + Nodes + + + + + NodeView + + + Label + + + + + Auto-Position + + + + + Smooth Edges + + + + + Filter + + + + + Show All + + + + + Show Selected Blocks Only + + + + + Direction + + + + + Top to Bottom + + + + + Bottom to Top + + + + + Left to Right + + + + + Right to Left + + + + + Add + + + + + NodeViewItem + + + %1... + + + + + PanNode + + + + Pan + + + + + Adjust the stereo panning of an audio source. + + + + + Samples + + + + + PanelWidget + + + %1: %2 + + + + + ParamPanel + + + Parameter Editor + + + + + (none) + + + + + (multiple) + + + + + PathWidget + + + Browse + + + + + Browse for path + + + + + PixelAspectRatioComboBox + + + Set Custom Pixel Aspect Ratio + + + + + Custom... + + + + + Custom (%1) + + + + + PixelSamplerPanel + + + Pixel Sampler + + + + + PixelSamplerWidget + + + Color + + + + + <html><font color='#FF8080'>R: %1</font><br><font color='#80FF80'>G: %2</font><br><font color='#8080FF'>B: %3</font><br>A: %4</html> + + + + + PolygonGenerator + + + Polygon + + + + + Generate a 2D polygon of any amount of points. + + + + + Points + + + + + Color + + + + + PreCacheTask + + + Pre-caching %1:%2 + + + + + PreferencesAppearanceTab + + + Theme + + + + + Node Color Scheme + + + + + PreferencesAudioTab + + + Output Device: + + + + + Input Device: + + + + + Sample Rate: + + + + + Audio Recording: + + + + + Mono + + + + + Stereo + + + + + Refresh Devices + + + + + Please wait... + + + + + Default + + + + + PreferencesBehaviorTab + + + Behavior + + + + + General + + + + + Enable hover focus + + + + + Panels will be considered focused when the mouse cursor is over them without having to click them. + + + + + Scroll wheel zooms by default instead of scrolling + + + + + Holding CTRL while using Olive toggles this setting + + + + + Audio + + + + + Enable audio scrubbing + + + + + Timeline + + + + + Auto-Seek to Imported Clips + + + + + Edit Tool Also Seeks + + + + + Edit Tool Selects Links + + + + + Enable Drag Files to Timeline + + + + + Invert Timeline Scroll Axes + + + + + Hold ALT on any UI element to switch scrolling axes + + + + + Seek Also Selects + + + + + Seek to the End of Pastes + + + + + Selecting Also Seeks + + + + + Playback + + + + + Ask For Name When Setting Marker + + + + + Automatically rewind at the end of a sequence + + + + + Project + + + + + Drop Files on Media to Replace + + + + + Nodes + + + + + Add Default Effects to New Clips + + + + + Auto-Scale By Default + + + + + Splitting Clips Copies Dependencies + + + + + Multiple clips can share the same nodes. Disable this to automatically share node dependencies among clips when copying or splitting them. + + + + + PreferencesDialog + + + Preferences + + + + + General + + + + + Appearance + + + + + Behavior + + + + + Disk + + + + + Audio + + + + + Keyboard + + + + + PreferencesDiskTab + + + Disk Management + + + + + Disk Cache Location: + + + + + Disk Cache Settings + + + + + Cache Behavior + + + + + Cache Ahead: + + + + + + %1 seconds + + + + + Cache Behind: + + + + + Disk Cache + + + + + Failed to set disk cache location. Access was denied. + + + + + PreferencesGeneralTab + + + Language: + + + + + Auto-Scroll Method: + + + + + None + + + + + Page Scrolling + + + + + Smooth Scrolling + + + + + Rectified Waveforms: + + + + + Default Still Image Length: + + + + + %1 seconds + + + + + %1 (%2) + + + + + PreferencesKeyboardTab + + + Search for action or shortcut + + + + + Action + + + + + Shortcut + + + + + Import + + + + + Export + + + + + Reset Selected + + + + + Reset All + + + + + Confirm Reset All Shortcuts + + + + + Are you sure you wish to reset all keyboard shortcuts to their defaults? + + + + + Import Keyboard Shortcuts + + + + + + Error saving shortcuts + + + + + Failed to open file for reading + + + + + Export Keyboard Shortcuts + + + + + Export Shortcuts + + + + + Shortcuts exported successfully + + + + + Failed to open file for writing + + + + + PresetManager + + + Save Preset + + + + + Set preset name: + + + + + Invalid preset name + + + + + You must enter a preset name + + + + + Preset exists + + + + + A preset with this name already exists. Would you like to replace it? + + + + + ProgressDialog + + + Cancel + + + + + Project + + + + (untitled) + + + + + ProjectExplorer + + + &New + + + + + &Import... + + + + + &Project Properties... + + + + + Open in New Tab + + + + + Open in New Window + + + + + Reveal in Explorer + + + + + Reveal in Finder + + + + + Reveal in File Manager + + + + + Pre-Cache + + + + + No sequences exist in project + + + + + For "%1" + + + + + P&roperties + + + + + Confirm Footage Deletion + + + + + The footage "%1" is currently used in the following sequence(s): + +%2 +What would you like to do with these clips? + + + + + Offline Footage + + + + + Delete Clips + + + + + ProjectExplorerNavigation + + + Go to parent folder + + + + + ProjectImportErrorDialog + + + Import Error + + + + + The following files failed to import. Olive likely does not support their formats. + + + + + ProjectImportTask + + + Importing %1 files + + + + + ProjectLoadBaseTask + + + Loading '%1' + + + + + ProjectLoadTask + + + This project is newer than this version of Olive and cannot be opened. + + + + + + This project is from a version of Olive that is no longer supported in this version. + + + + + Failed to read file "%1" for reading. + + + + + ProjectPanel + + + Folder + + + + + Project + + + + + (none) + + + + + ProjectPropertiesDialog + + + Project Properties for '%1' + + + + + OpenColorIO Configuration: + + + + + (default) + + + + + Default Input Color Space: + + + + + Browse + + + + + Color Management + + + + + Use Default Location + + + + + Store Alongside Project + + + + + Use Custom Location: + + + + + Disk Cache Settings + + + + + + "Store alignside project" functionality not implemented yet + + + + + Disk Cache + + + + + OpenColorIO Config Error + + + + + Failed to set OpenColorIO configuration: %1 + + + + + Invalid path + + + + + The cache path is invalid. Please check it and try again. + + + + + Browse for OpenColorIO configuration + + + + + ProjectSaveTask + + + Saving '%1' + + + + + Failed to write XML data + + + + + Failed to overwrite "%1". Project has been saved as "%2" instead. + + + + + Failed to open temporary file "%1" for writing. + + + + + ProjectToolbar + + + New... + + + + + Open Project + + + + + Save Project + + + + + Undo + + + + + Redo + + + + + Search media, markers, etc. + + + + + Switch to Tree View + + + + + Switch to List View + + + + + Switch to Icon View + + + + + ProjectViewModel + + + Name + + + + + Duration + + + + + Rate + + + + + Move Items + + + + + ProjectViewModel::MoveItemCommand + + + Move Item + + + + + ProjectViewModel::RenameItemCommand + + + Rename Item + + + + + RatioDialog + + + Enter custom ratio (e.g. "4:3", "16/9", etc.): + + + + + Invalid custom ratio + + + + + Failed to parse "%1" into an aspect ratio. Please format a rational fraction with a ':' or a '/' separator. + + + + + RenderCancelDialog + + + Waiting for workers to finish... + + + + + Renderer + + + + + RichTextDialog + + + B + + + + + Bold + + + + + I + + + + + Italic + + + + + U + + + + + Underline + + + + + S + + + + + Strikethrough + + + + + Font Family + + + + + Font Size + + + + + L + + + + + Left Align + + + + + C + + + + + Center Align + + + + + R + + + + + Right Align + + + + + J + + + + + Justify Align + + + + + SaveOTIOTask + + + Exporting project to OpenTimelineIO + + + + + Project contains no sequences to export. + + + + + Failed to serialize sequence "%1" + + + + + ScopePanel + + + Waveform + + + + + Histogram + + + + + Scope + + + + + Sequence + + + %1 FPS + + + + + SequenceDialog + + + Name: + + + + + New Sequence + + + + + Editing "%1" + + + + + Error editing Sequence + + + + + Please enter a name for this Sequence. + + + + + SequenceDialogParameterTab + + + Video + + + + + Width: + + + + + Height: + + + + + Frame Rate: + + + + + Pixel Aspect Ratio: + + + + + Interlacing: + + + + + Audio + + + + + Sample Rate: + + + + + Channels: + + + + + Preview + + + + + Resolution: + + + + + Quality: + + + + + Save Preset + + + + + (%1x%2) + + + + + SequenceDialogPresetTab + + + Preset + + + + + My Presets + + + + + 4K UHD + + + + + 1080p + + + + + 720p + + + + + NTSC + + + + + PAL + + + + + %1 23.976 FPS + + + + + %1 25 FPS + + + + + %1 29.97 FPS + + + + + %1 50 FPS + + + + + %1 59.94 FPS + + + + + %1 Standard + + + + + %1 Widescreen + + + + + Delete Preset + + + + + SequenceViewerPanel + + + Sequence Viewer + + + + + SliderBase + + + Invalid Value + + + + + The entered value is not valid for this field. + + + + + SolidGenerator + + + Solid + + + + + Generate a solid color. + + + + + Color + + + + + Stream + + + %1: Audio - %2 Channels, %3Hz + + + + + %1: Unknown + + + + + %1: Image - %2x%3 + + + + + %1: Video - %2x%3 + + + + + StringSlider + + + (none) + + + + + StrokeFilterNode + + + Stroke + + + + + Creates a stroke outline around an image. + + + + + Input + + + + + Color + + + + + Radius + + + + + Opacity + + + + + Inner + + + + + Task + + + Task + + + + + Unknown error + + + + + TaskDialog + + + Task Failed + + + + + TaskManagerPanel + + + Task Manager + + + + + TaskViewItem + + + Error: %1 + + + + + TextGenerator + + + Sample Text + + + + + + Text + + + + + Generate rich text. + + + + + Font + + + + + Font Size + + + + + Color + + + + + Vertical Align + + + + + Top + + + + + Center + + + + + Bottom + + + + + TimeBasedPanel + + + (none) + + + + + TimeBasedWidget + + + Set Marker + + + + + Marker name: + + + + + TimeInput + + + Time + + + + + Generates the time (in seconds) at this frame + + + + + TimelinePanel + + + Timeline + + + + + TimelineViewBlockItem + + + %1 + +In: %2 +Out: %3 +Length: %4 + + + + + TimelineWidget + + + + Properties + + + + + Use Audio Time Units + + + + + Tool + + + Empty + + + + + Bars + + + + + Solid + + + + + Title + + + + + Tone + + + + + Unknown + + + + + ToolPanel + + + Tools + + + + + Toolbar + + + Pointer Tool + + + + + Edit Tool + + + + + Ripple Tool + + + + + Rolling Tool + + + + + Razor Tool + + + + + Slip Tool + + + + + Slide Tool + + + + + Hand Tool + + + + + Zoom Tool + + + + + Transition Tool + + + + + Record Tool + + + + + Add Tool + + + + + Toggle Snapping + + + + + TrackOutput + + + Track + + + + + Node for representing and processing a single array of Blocks sorted by time. Also represents the end of a Sequence. + + + + + Blocks + + + + + Muted + + + + + Video %1 + + + + + Audio %1 + + + + + Subtitle %1 + + + + + Track %1 + + + + + TrackViewItem + + + M + + + + + L + + + + + TransitionBlock + + + From + + + + + To + + + + + Curve + + + + + Linear + + + + + Exponential + + + + + Logarithmic + + + + + TrigonometryNode + + + Trigonometry + + + + + Perform a trigonometry operation on a value. + + + + + Sine + + + + + Cosine + + + + + Tangent + + + + + Inverse Sine + + + + + Inverse Cosine + + + + + Inverse Tangent + + + + + Hyperbolic Sine + + + + + Hyperbolic Cosine + + + + + Hyperbolic Tangent + + + + + Method + + + + + VideoDividerComboBox + + + Full + + + + + 1/%1 + + + + + VideoInput + + + Video Input + + + + + Video + + + + + Import a video footage stream. + + + + + VideoParams + + + 8-bit + + + + + 16-bit Integer + + + + + Half-Float (16-bit) + + + + + Full-Float (32-bit) + + + + + Unknown (0x%1) + + + + + %1 FPS + + + + + Square Pixels (%1) + + + + + NTSC Standard (%1) + + + + + NTSC Widescreen (%1) + + + + + PAL Standard (%1) + + + + + PAL Widescreen (%1) + + + + + HD Anamorphic 1080 (%1) + + + + + VideoStreamProperties + + + Pixel Aspect: + + + + + Interlacing: + + + + + Color Space: + + + + + Default (%1) + + + + + Premultiplied Alpha + + + + + Image Sequence + + + + + Start Index: + + + + + End Index: + + + + + Frame Rate: + + + + + Invalid Configuration + + + + + Image sequence end index must be a value higher than the start index. + + + + + ViewerOutput + + + Viewer + + + + + Interface between a Viewer panel and the node system. + + + + + Texture + + + + + Samples + + + + + Video Tracks + + + + + Audio Tracks + + + + + Subtitle Tracks + + + + + ViewerPanel + + + Viewer + + + + + ViewerWidget + + + Error + + + + + No in or out points are set to cache. + + + + + + Safe Margins + + + + + Zoom + + + + + Fit + + + + + %1% + + + + + Full Screen + + + + + Screen %1: %2x%3 + + + + + Deinterlace + + + + + Scopes + + + + + Cache + + + + + Auto-Cache + + + + + Pause Auto-Cache During Playback + + + + + Cache Entire Sequence + + + + + Cache Sequence In/Out + + + + + Off + + + + + On + + + + + Custom Aspect + + + + + Show Audio Waveform + + + + + VolumeNode + + + + Volume + + + + + Adjusts the volume of an audio source. + + + + + Samples + + + + + main + + + Show this help text + + + + + Show application version + + + + + Start in full-screen mode + + + + + Export only (No GUI) + + + + + Override language with file + + + + + Project to open on startup + + + + diff --git a/app/ts/translations.qrc.in b/app/ts/translations.qrc.in new file mode 100644 index 000000000..c86dc346d --- /dev/null +++ b/app/ts/translations.qrc.in @@ -0,0 +1,5 @@ + + + @QRC_BODY@ + + diff --git a/app/widget/panel/panel.h b/app/widget/panel/panel.h index 1d25f5eba..ae98c464a 100644 --- a/app/widget/panel/panel.h +++ b/app/widget/panel/panel.h @@ -31,7 +31,8 @@ OLIVE_NAMESPACE_ENTER /** * @brief A widget that is always dockable within the MainWindow. */ -class PanelWidget : public QDockWidget { +class PanelWidget : public QDockWidget +{ Q_OBJECT public: /** diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index 6846c469e..91e03a8ba 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -49,7 +49,8 @@ OLIVE_NAMESPACE_ENTER /** * @brief Olive's main window responsible for docking widgets and the main menu bar. */ -class MainWindow : public QMainWindow { +class MainWindow : public QMainWindow +{ Q_OBJECT public: MainWindow(QWidget *parent = nullptr);