From 95565e6ab0b9d6c66cb1e84e95dd9b1ca0d2b5d6 Mon Sep 17 00:00:00 2001 From: Richard Bailey Date: Fri, 13 Aug 2021 16:48:35 +0100 Subject: [PATCH 1/3] get UI text by ID rather than magic strings --- .../src/reaper_adm/CMakeLists.txt | 2 + .../src/reaper_adm/pluginmain.cpp | 65 +++++++++++++------ .../src/reaper_adm/ui_text.cpp | 24 +++++++ reaper-adm-extension/src/reaper_adm/ui_text.h | 25 +++++++ 4 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 reaper-adm-extension/src/reaper_adm/ui_text.cpp create mode 100644 reaper-adm-extension/src/reaper_adm/ui_text.h diff --git a/reaper-adm-extension/src/reaper_adm/CMakeLists.txt b/reaper-adm-extension/src/reaper_adm/CMakeLists.txt index 7dadf3eb7..21934fc5f 100644 --- a/reaper-adm-extension/src/reaper_adm/CMakeLists.txt +++ b/reaper-adm-extension/src/reaper_adm/CMakeLists.txt @@ -67,6 +67,7 @@ set(EXTENSION_SOURCES reaperguid.cpp reaperhost.cpp track.cpp + ui_text.cpp coordinate_conversion/coord_conv.cpp progress/importdialog.cpp progress/importlistener.cpp @@ -142,6 +143,7 @@ set(EXTENSION_HEADERS reaper_plugin_functions.h resource.h track.h + ui_text.h win_mem_debug.h win_nonblock_msg.h coordinate_conversion/coord_conv.cpp diff --git a/reaper-adm-extension/src/reaper_adm/pluginmain.cpp b/reaper-adm-extension/src/reaper_adm/pluginmain.cpp index be3bf69d4..8b365c852 100644 --- a/reaper-adm-extension/src/reaper_adm/pluginmain.cpp +++ b/reaper-adm-extension/src/reaper_adm/pluginmain.cpp @@ -7,11 +7,10 @@ #include "reaperapi.h" #include "actionmanager.h" #include "menu.h" -#include "admmetadata.h" #include "importaction.h" -#include "exportaction.h" #include "pluginsuite.h" #include "pluginregistry.h" +#include "ui_text.h" #ifdef WIN32 #include "win_nonblock_msg.h" @@ -70,6 +69,9 @@ const std::map defaultMenuPositions = { } #endif +using eps::TextID; +using eps::uiText; + extern "C" { int REAPER_PLUGIN_DLL_EXPORT REAPER_PLUGIN_ENTRYPOINT(REAPER_PLUGIN_HINSTANCE hInstance, reaper_plugin_info_t *rec) { @@ -77,11 +79,14 @@ extern "C" { std::unique_ptr reaper; auto nonBlockingMessage = [rec](const char* text) { + auto title = uiText(TextID::EXTENSION_ERROR_TITLE); #ifdef WIN32 - // Windows version of Reaper locks up if you try show a message box during splash - winhelpers::NonBlockingMessageBox(text, "ADM Extension Error", MB_ICONEXCLAMATION); + // Windows version of Reaper locks up if you try show a message box during + // splash + winhelpers::NonBlockingMessageBox(text, title.c_str(), + MB_ICONEXCLAMATION); #else - MessageBox(rec->hwnd_main, text, "ADM Extension Error", MB_OK); + MessageBox(rec->hwnd_main, text, title.c_str(), MB_OK); #endif }; @@ -108,7 +113,8 @@ extern "C" { // Item right-click menu - auto admContextMenu = std::make_unique("ADM"); + auto admContextMenu = + std::make_unique(uiText(TextID::CONTEXT_MENU)); auto admContextMenuUpdateCallback = [api](MenuItem& item) { int numMediaItems = api->CountSelectedMediaItems(0); if (numMediaItems == 1) { // For now, lets just deal with one selection @@ -125,7 +131,7 @@ extern "C" { admContextMenu->updateCallback = admContextMenuUpdateCallback; for (auto& pluginSuite : *pluginRegistry->getPluginSuites()) { - std::string actionName("Explode using "); + auto actionName = uiText(TextID::EXPLODE_ACTION_PREFIX); actionName += pluginSuite.first; std::string actionSID("ADM_EXPLODE_"); actionSID += std::to_string(actionCounter++); @@ -140,7 +146,11 @@ extern "C" { importer.import(mediaItem, api); } else { - api.ShowMessageBox("Please select a source before running this action.", "ADM: Explode to Takes", 0); + api.ShowMessageBox( + uiText(TextID::EXPLODE_ERROR_DESCRIPTION) + .c_str(), + uiText(TextID::EXPLODE_ERROR_TITLE).c_str(), + 0); } }); explodeAction->setEnabled(pluginSuite.second->pluginSuiteUsable(*api)); @@ -156,13 +166,14 @@ extern "C" { defaultMenuPositions.at("Group"), *api)); // File menu - auto admFileMenu = std::make_unique("Create project from ADM file"); - auto admFileMenuUpdateCallback = [api](MenuItem& item) {}; + auto admFileMenu = + std::make_unique(uiText(TextID::CREATE_PROJECT_MENU)); + auto admFileMenuUpdateCallback = [api](MenuItem& item) {}; admFileMenu->updateCallback = admFileMenuUpdateCallback; for (auto& pluginSuite : *pluginRegistry->getPluginSuites()) { - std::string actionName("Create from ADM using "); - actionName += pluginSuite.first; + std::string actionName(uiText(TextID::CREATE_PROJECT_ACTION_PREFIX)); + actionName += pluginSuite.first; std::string actionSID("ADM_CREATE_PROJECT_"); actionSID += std::to_string(actionCounter++); @@ -180,12 +191,21 @@ extern "C" { auto filenameStr = std::string(filename); filenameStr += "/.wav"; memcpy(filename, filenameStr.data(), filenameStr.length() + 1); - if(api.GetUserFileNameForRead(filename, "ADM File to Open", "wav")) { - filenameStr = std::string(filename); + if (api.GetUserFileNameForRead( + filename, + uiText(TextID::CREATE_PROJECT_FILE_PROMPT) + .c_str(), + "wav")) { + filenameStr = std::string(filename); if(ImportAction::canMediaExplode_QuickCheck(api, filenameStr)) { importer.import(filenameStr, api); } else { - api.ShowMessageBox("Error: This file can not be imported.", "ADM Open", 0); + api.ShowMessageBox( + uiText(TextID::CREATE_PROJECT_ERROR_DESCRIPTION) + .c_str(), + uiText(TextID::CREATE_PROJECT_ERROR_TITLE) + .c_str(), + 0); } } } @@ -208,12 +228,13 @@ extern "C" { // Insert menu - auto admInsertMenu = std::make_unique("Import ADM file in to current project"); + auto admInsertMenu = + std::make_unique(uiText(TextID::IMPORT_MENU)); auto admInsertMenuUpdateCallback = [api](MenuItem& item) {}; admInsertMenu->updateCallback = admInsertMenuUpdateCallback; for (auto& pluginSuite : *pluginRegistry->getPluginSuites()) { - std::string actionName("Import ADM file using "); + std::string actionName(uiText(TextID::IMPORT_ACTION_PREFIX)); actionName += pluginSuite.first; std::string actionSID("ADM_IMPORT_"); actionSID += std::to_string(actionCounter++); @@ -229,12 +250,16 @@ extern "C" { auto filenameStr = std::string(filename); filenameStr += "/.wav"; memcpy(filename, filenameStr.data(), filenameStr.length() + 1); - if (api.GetUserFileNameForRead(filename, "ADM File to Import", "wav")) { - filenameStr = std::string(filename); + if (api.GetUserFileNameForRead( + filename, uiText(TextID::IMPORT_FILE_PROMPT).c_str(), + "wav")) { + filenameStr = std::string(filename); if(ImportAction::canMediaExplode_QuickCheck(api, filenameStr)) { importer.import(filenameStr, api); } else { - api.ShowMessageBox("Error: This file can not be imported.", "ADM Import", 0); + api.ShowMessageBox( + uiText(TextID::IMPORT_ERROR_DESCRIPTION).c_str(), + uiText(TextID::IMPORT_ERROR_TITLE).c_str(), 0); } } }); diff --git a/reaper-adm-extension/src/reaper_adm/ui_text.cpp b/reaper-adm-extension/src/reaper_adm/ui_text.cpp new file mode 100644 index 000000000..28e8dba0a --- /dev/null +++ b/reaper-adm-extension/src/reaper_adm/ui_text.cpp @@ -0,0 +1,24 @@ +#include "ui_text.h" +#include +#include + +std::string eps::uiText(eps::TextID item) { + static std::unordered_map dictionary { + {TextID::EXTENSION_ERROR_TITLE, "ADM Extension Error"}, + {TextID::CONTEXT_MENU, "ADM"}, + {TextID::EXPLODE_ACTION_PREFIX, "Explode using "}, + {TextID::EXPLODE_ERROR_TITLE, "ADM: Explode to Takes"}, + {TextID::EXPLODE_ERROR_DESCRIPTION, "Please select a source before running this action."}, + {TextID::CREATE_PROJECT_MENU, "Create project from ADM file"}, + {TextID::CREATE_PROJECT_ACTION_PREFIX, "Create from ADM using "}, + {TextID::CREATE_PROJECT_FILE_PROMPT, "ADM File to Open"}, + {TextID::CREATE_PROJECT_ERROR_TITLE, "Import ADM file in to current project"}, + {TextID::CREATE_PROJECT_ERROR_DESCRIPTION, "Error: This file can not be imported."}, + {TextID::IMPORT_MENU, "ADM File to Import"}, + {TextID::IMPORT_ACTION_PREFIX, "Import ADM file using "}, + {TextID::IMPORT_ERROR_TITLE, "Error: This file can not be imported."}, + {TextID::IMPORT_ERROR_DESCRIPTION, "ADM Import"} + }; + assert(dictionary.find(item) != dictionary.end()); + return(dictionary.find(item) == dictionary.end()) ? "" : dictionary[item]; +} diff --git a/reaper-adm-extension/src/reaper_adm/ui_text.h b/reaper-adm-extension/src/reaper_adm/ui_text.h new file mode 100644 index 000000000..09954b49a --- /dev/null +++ b/reaper-adm-extension/src/reaper_adm/ui_text.h @@ -0,0 +1,25 @@ +#pragma once +#include + +namespace eps { + +enum class TextID { + EXTENSION_ERROR_TITLE, + CONTEXT_MENU, + EXPLODE_ACTION_PREFIX, + EXPLODE_ERROR_TITLE, + EXPLODE_ERROR_DESCRIPTION, + CREATE_PROJECT_ACTION_PREFIX, + CREATE_PROJECT_MENU, + CREATE_PROJECT_FILE_PROMPT, + CREATE_PROJECT_ERROR_TITLE, + CREATE_PROJECT_ERROR_DESCRIPTION, + IMPORT_MENU, + IMPORT_ACTION_PREFIX, + IMPORT_FILE_PROMPT, + IMPORT_ERROR_TITLE, + IMPORT_ERROR_DESCRIPTION +}; + +std::string uiText(TextID item); +} From 7a840695fe6c028947cedf613114b9d13f53f77e Mon Sep 17 00:00:00 2001 From: Richard Bailey Date: Mon, 16 Aug 2021 15:47:23 +0100 Subject: [PATCH 2/3] Add fmt as explicit dependency Was previously included via spdlog, this makes it available to project --- CMakeLists.txt | 1 + ear-production-suite-plugins/lib/CMakeLists.txt | 7 ++++--- reaper-adm-extension/src/reaper_adm/CMakeLists.txt | 1 + vcpkg.json | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb6ebe3bd..7af3264d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ if(UNIX) endif() include(check_nng) find_package(nng REQUIRED QUIET) +find_package(fmt REQUIRED QUIET) add_subdirectory(submodules) set(EPS_SHARED_DIR ${CMAKE_CURRENT_SOURCE_DIR}/shared) diff --git a/ear-production-suite-plugins/lib/CMakeLists.txt b/ear-production-suite-plugins/lib/CMakeLists.txt index 8ba3960cb..1dd9b116d 100644 --- a/ear-production-suite-plugins/lib/CMakeLists.txt +++ b/ear-production-suite-plugins/lib/CMakeLists.txt @@ -109,13 +109,14 @@ target_link_libraries(ear-plugin-base PUBLIC Boost::boost protobuf::libprotobuf nng::nng + fmt::fmt spdlog::spdlog bw64 adm Eigen3::Eigen) -if(SPDLOG_FMT_EXTERNAL) - target_link_libraries(ear-plugin-base PUBLIC fmt::fmt) -endif() + +target_compile_definitions(ear-plugin-base PUBLIC + SPDLOG_FMT_EXTERNAL) target_include_directories(ear-plugin-base PUBLIC # Headers used from source/build location: diff --git a/reaper-adm-extension/src/reaper_adm/CMakeLists.txt b/reaper-adm-extension/src/reaper_adm/CMakeLists.txt index 21934fc5f..2f9f4fe30 100644 --- a/reaper-adm-extension/src/reaper_adm/CMakeLists.txt +++ b/reaper-adm-extension/src/reaper_adm/CMakeLists.txt @@ -200,6 +200,7 @@ target_include_directories(reaper_adm_object target_link_libraries(reaper_adm_dependencies INTERFACE $ + fmt::fmt IRT::bw64 adm WDL::swell diff --git a/vcpkg.json b/vcpkg.json index fe4f21a09..83cbe86e2 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -5,6 +5,7 @@ "dependencies": [ "protobuf", "nng", + "fmt", "spdlog", "yaml-cpp", "boost-algorithm", @@ -22,4 +23,4 @@ "boost-uuid", "boost-variant" ] -} \ No newline at end of file +} From 9008ab0df01d70fe98c791a27ed2cc87abad298b Mon Sep 17 00:00:00 2001 From: Richard Bailey Date: Mon, 16 Aug 2021 15:48:15 +0100 Subject: [PATCH 3/3] Lookup strings used in export UI via uiString() --- .../exportaction_admsourcescontainer.cpp | 7 +- .../reaper_adm/exportaction_dialogcontrol.cpp | 31 ++++--- .../src/reaper_adm/exportaction_pcmsink.cpp | 92 ++++++++++--------- .../src/reaper_adm/ui_text.cpp | 29 +++++- reaper-adm-extension/src/reaper_adm/ui_text.h | 28 +++++- 5 files changed, 128 insertions(+), 59 deletions(-) diff --git a/reaper-adm-extension/src/reaper_adm/exportaction_admsourcescontainer.cpp b/reaper-adm-extension/src/reaper_adm/exportaction_admsourcescontainer.cpp index 85a9b0613..004005351 100644 --- a/reaper-adm-extension/src/reaper_adm/exportaction_admsourcescontainer.cpp +++ b/reaper-adm-extension/src/reaper_adm/exportaction_admsourcescontainer.cpp @@ -3,6 +3,7 @@ #include "exportaction_admsource-admvst.h" #include "exportaction_admsource-earvst.h" +#include "ui_text.h" void AdmExportHandler::repopulate(ReaperAPI const & api) { @@ -47,12 +48,12 @@ std::vector AdmExportHandler::generateExportErrorStrings() std::vector msgs; if(!admExportSources) { - msgs.push_back(std::string("No Valid Export Sources!")); + msgs.push_back(eps::uiText(eps::TextID::EXPORT_HANDLER_ERROR_NO_VALID_SOURCES)); } if(admExportSources) { if (admExportSources->getTotalExportChannels() == 0) { - msgs.push_back("Current configuration of export sources provides 0 channels of audio."); + msgs.push_back(eps::uiText(eps::TextID::EXPORT_HANDLER_ERROR_NO_CHANNELS)); } auto sourcesMsgs = admExportSources->generateExportErrorStrings(); msgs.insert(msgs.end(), sourcesMsgs.begin(), sourcesMsgs.end()); @@ -68,7 +69,7 @@ std::vector AdmExportHandler::generateExportWarningStrings() std::vector msgs; if(earSceneMasterVstSources && earSceneMasterVstSources->validForExport() && admExportVstSources && admExportVstSources->validForExport()) { - msgs.push_back(std::string("Multiple Types of Export Source!")); + msgs.push_back(eps::uiText(eps::TextID::EXPORT_HANDLER_WARNING_MULTIPLE_SOURCE_TYPES)); } if(admExportSources) { diff --git a/reaper-adm-extension/src/reaper_adm/exportaction_dialogcontrol.cpp b/reaper-adm-extension/src/reaper_adm/exportaction_dialogcontrol.cpp index c30d8c8e7..092c5e214 100644 --- a/reaper-adm-extension/src/reaper_adm/exportaction_dialogcontrol.cpp +++ b/reaper-adm-extension/src/reaper_adm/exportaction_dialogcontrol.cpp @@ -5,6 +5,7 @@ #include "resource.h" #include "exportaction_issues.h" #include "exportaction.h" +#include "ui_text.h" // Lots of assumptions made here! May need more re-jigging if future versions differ #define EXPECTED_RENDER_DIALOG_WINDOW_TITLE "Render to File" @@ -14,9 +15,6 @@ #define REQUIRED_SOURCE_COMBO_OPTION "Master mix" #define REQUIRED_BOUNDS_COMBO_OPTION "Entire project" -#define TAKEOVER_TEXT_FOR_CHANNEL_COUNT "Auto" // What we will display for "Channels" when our PCM Sink is selected -#define FALLBACK_VALUE_FOR_CHANNEL_COUNT "Stereo" // Value once we restore state, if we didn't know what it was before - #define TIMER_ID 1 int MakeWParam(int loWord, int hiWord) @@ -153,7 +151,7 @@ void RenderDialogControl::RenderDialogState::startPreparingRenderControls(HWND h { startedPrepareDialogControls = true; // Prevents paint message relauching this EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_REFRESH), false); - SetWindowText(GetDlgItem(hwndDlg, IDC_INFOPANE), LPCSTR("\r\nValidating Project Structure...\r\n\r\nPlease Wait...")); + SetWindowText(GetDlgItem(hwndDlg, IDC_INFOPANE), eps::uiText(eps::TextID::RENDERER_VALIDATING_DIALOG).c_str()); SetTimer(hwndDlg, TIMER_ID, // timer identifier 100, // interval(ms) @@ -221,7 +219,7 @@ BOOL CALLBACK RenderDialogControl::RenderDialogState::prepareRenderControl_pass2 if(channelsLastOption.length() == 0 && currentOption.length() > 0){ channelsLastOption = currentOption; } - channelsControlSetError |= (SetWindowText(editControl, TAKEOVER_TEXT_FOR_CHANNEL_COUNT) == 0); + channelsControlSetError |= (SetWindowText(editControl, eps::uiText(eps::TextID::EXPORT_DIALOG_TAKEOVER_TEXT_FOR_CHANNEL_COUNT).c_str()) == 0); EnableWindow(editControl, false); UpdateWindow(editControl); } @@ -246,11 +244,11 @@ std::string RenderDialogControl::RenderDialogState::getAdmExportVstsInfoString() auto exportSources = admExportHandler->getAdmExportSources(); if(exportSources) { - op += "Using export source: \""; + op += eps::uiText(eps::TextID::RENDERER_EXPORT_SOURCE_PREFIX); op += admExportHandler->getAdmExportSources()->getExportSourcesName(); op += "\""; } else { - op += "No suitable export sources!"; + op += eps::uiText(eps::TextID::RENDERER_ERROR_NO_EXPORT_SOURCES); } auto errors = admExportHandler->generateExportErrorStrings(); @@ -258,7 +256,7 @@ std::string RenderDialogControl::RenderDialogState::getAdmExportVstsInfoString() auto infos = admExportHandler->generateExportInfoStrings(); if (errors.size() > 0) { - op.append("\r\n\r\nERRORS:"); + op.append(eps::uiText(eps::TextID::RENDER_LOG_ERROR_HEADER)); for(auto &msg : errors) { op.append(itemStarter); op.append(msg); @@ -266,7 +264,7 @@ std::string RenderDialogControl::RenderDialogState::getAdmExportVstsInfoString() } if (warnings.size() > 0) { - op.append("\r\n\r\nWARNINGS:"); + op.append(eps::uiText(eps::TextID::RENDER_LOG_WARNING_HEADER)); for(auto &msg : warnings) { op.append(itemStarter); op.append(msg); @@ -276,7 +274,7 @@ std::string RenderDialogControl::RenderDialogState::getAdmExportVstsInfoString() if (infos.size() > 0) { op.append("\r\n"); if(warnings.size() > 0 || errors.size() > 0) { - op.append("\r\nINFO:"); + op.append(eps::uiText(eps::TextID::RENDER_LOG_INFO_HEADER)); } for(auto &msg : infos) { op.append(itemStarter); @@ -360,7 +358,7 @@ WDL_DLGRET RenderDialogControl::RenderDialogState::wavecfgDlgProc(HWND hwndDlg, channelsControlHwnd.has_value() && !sampleRateControlSetError && !channelsControlSetError; if(!allControlsSuccessful) { - infoPaneText = "WARNING: Unable to takeover all render controls. REAPER version may be unsupported and render may fail.\r\n\r\n" + infoPaneText; + infoPaneText = eps::uiText(eps::TextID::RENDERER_ERROR_FAILED_CONTROL_OVERRIDE) + infoPaneText; } SetWindowText(GetDlgItem(hwndDlg, IDC_INFOPANE), LPCSTR(infoPaneText.c_str())); @@ -423,8 +421,15 @@ WDL_DLGRET RenderDialogControl::RenderDialogState::wavecfgDlgProc(HWND hwndDlg, if(channelsControlHwnd) { auto editControl = getComboBoxEdit(*channelsControlHwnd); if(channelsLastOption.length() > 0){ - std::string opt = channelsLastOption == TAKEOVER_TEXT_FOR_CHANNEL_COUNT ? FALLBACK_VALUE_FOR_CHANNEL_COUNT : channelsLastOption; - selectInComboBox(*channelsControlHwnd, opt); + std::string opt = + channelsLastOption == + eps::uiText( + eps::TextID:: + EXPORT_DIALOG_TAKEOVER_TEXT_FOR_CHANNEL_COUNT) + ? uiText(eps::TextID:: + EXPORT_DIALOG_FALLBACK_VALUE_FOR_CHANNEL_COUNT) + : channelsLastOption; + selectInComboBox(*channelsControlHwnd, opt); SetWindowText(editControl, opt.c_str()); } EnableWindow(editControl, true); diff --git a/reaper-adm-extension/src/reaper_adm/exportaction_pcmsink.cpp b/reaper-adm-extension/src/reaper_adm/exportaction_pcmsink.cpp index 80248589b..814f44a58 100644 --- a/reaper-adm-extension/src/reaper_adm/exportaction_pcmsink.cpp +++ b/reaper-adm-extension/src/reaper_adm/exportaction_pcmsink.cpp @@ -1,8 +1,8 @@ #include "exportaction_pcmsink.h" #include "adm/adm.hpp" -#include "adm/utilities/id_assignment.hpp" -#include "adm/write.hpp" +#include "ui_text.h" +#include #ifdef _WIN32 #include @@ -39,8 +39,11 @@ PCM_sink_adm::PCM_sink_adm(std::shared_ptr api, const char *fn, void auto admExportSources = admExportHandler->getAdmExportSources(); if(!admExportSources) { - api->ShowMessageBox("No suitable export sources within the current project.\r\nCan not continue with render.", "No Export Sources", 0); - abortRender(); + api->ShowMessageBox( + eps::uiText(eps::TextID::EXPORT_SINK_ERROR_NO_SOURCES).c_str(), + eps::uiText(eps::TextID::EXPORT_SINK_ERROR_NO_SOURCES_TITLE).c_str(), + 0); + abortRender(); return; } @@ -48,32 +51,38 @@ PCM_sink_adm::PCM_sink_adm(std::shared_ptr api, const char *fn, void totalChannels = admExportSources->getTotalExportChannels(); if (totalChannels == 0) { - api->ShowMessageBox("The current configuration of export sources will export 0 channels of audio.\r\nCan not continue with render.", "No Audio To Export", 0); - abortRender(); + api->ShowMessageBox( + eps::uiText(eps::TextID::EXPORT_SINK_ERROR_NO_SOURCES).c_str(), + eps::uiText(eps::TextID::EXPORT_SINK_ERROR_NO_CHANNELS_TITLE).c_str(), + 0); + abortRender(); return; } if(sRate != admExportSources->getSampleRate()) { - std::string msg("Error: Sink sample rate ("); - msg.append(std::to_string(sRate)); - msg.append(") does not match VST sample rate ("); - msg.append(std::to_string(admExportSources->getSampleRate())); - msg.append(")!\r\nThis is likely an internal issue.\r\nCan not continue with render."); - api->ShowMessageBox(msg.c_str(), "Sample Rate Mismatch", 0); - abortRender(); - return; + auto msg = + fmt::format(eps::uiText(eps::TextID::EXPORT_SINK_ERROR_SAMPLE_RATE), + sRate, admExportSources->getSampleRate()); + api->ShowMessageBox( + msg.c_str(), + eps::uiText(eps::TextID::EXPORT_SINK_ERROR_SAMPLE_RATE_TITLE).c_str(), + 0); + abortRender(); + return; } // Check other errors (warnings/infos are fine... we can continue with those) auto errors = admExportHandler->generateExportErrorStrings(); - if(errors.size() > 0) { - auto op = std::string("Can not render due to the following issues:\r\n"); + if(!errors.empty()) { + auto op = eps::uiText(eps::TextID::EXPORT_HANDLER_ERROR_NO_VALID_SOURCES); for(auto& error : errors) { op.append("\r\n"); op.append(error); } - api->ShowMessageBox(op.c_str() , "Render Issues", 0); + api->ShowMessageBox( + op.c_str(), + eps::uiText(eps::TextID::EXPORT_SINK_ISSUES_TITLE).c_str(), 0); abortRender(); return; } @@ -81,9 +90,11 @@ PCM_sink_adm::PCM_sink_adm(std::shared_ptr api, const char *fn, void // Check ADM auto doc = admExportSources->getAdmDocument(); if(!doc) { - api->ShowMessageBox("Error: No ADM metadata available for export.\r\nThis is likely an internal issue.\r\nCan not continue with render.", "No ADM Metadata", 0); - abortRender(); - return; + api->ShowMessageBox( + eps::uiText(eps::TextID::EXPORT_SINK_ERROR_NO_ADM).c_str(), + eps::uiText(eps::TextID::EXPORT_SINK_ERROR_NO_ADM_TITLE).c_str(), 0); + abortRender(); + return; } // Configure ADM document @@ -130,19 +141,18 @@ PCM_sink_adm::~PCM_sink_adm() } if (actualFramesWritten < expectedFramesWritten) { - // Warn user - didn't receive all the frames we expected - auto msg = std::string("Warning:\r\n"); - msg += "Received "; - msg += std::to_string(actualFramesWritten); - msg += " frames from export source \""; - msg += admExportHandler->getAdmExportSources()->getExportSourcesName(); - msg += "\".\r\n"; - msg += "Expected "; - msg += std::to_string(expectedFramesWritten); - msg += " frames."; - api->ShowMessageBox(msg.c_str(), "Render", 0); + // Warn user - didn't receive all the frames we expected + auto msg = fmt::format( + eps::uiText(eps::TextID::EXPORT_SINK_WARNING_FRAMES), + actualFramesWritten, + admExportHandler->getAdmExportSources()->getExportSourcesName(), + expectedFramesWritten); + api->ShowMessageBox( + msg.c_str(), + eps::uiText(eps::TextID::EXPORT_SINK_WARNING_FRAMES_TITLE) + .c_str(), + 0); } - writer.reset(); } @@ -169,17 +179,17 @@ INT64 PCM_sink_adm::GetFileSize() return 0; } -void PCM_sink_adm::GetOutputInfoString(char *buf, int buflen) -{ - if (writer) { - strncpy(buf, "Rendering ADM tracks...", buflen); - } - else { - strncpy(buf, "WARNING: Unable to render - invalid project structure!", buflen); - } +void PCM_sink_adm::GetOutputInfoString(char *buf, int buflen) { + if (writer) { + strncpy(buf, eps::uiText(eps::TextID::EXPORT_SINK_INFO_RENDERING).c_str(), + buflen); + } else { + strncpy(buf, + eps::uiText(eps::TextID::EXPORT_SINK_WARNING_BAD_STRUCTURE).c_str(), + buflen); + } } - void PCM_sink_adm::WriteDoubles(double **samples, int len, int nch, int offset, int spacing) { if (!writer) return; diff --git a/reaper-adm-extension/src/reaper_adm/ui_text.cpp b/reaper-adm-extension/src/reaper_adm/ui_text.cpp index 28e8dba0a..a1a66780e 100644 --- a/reaper-adm-extension/src/reaper_adm/ui_text.cpp +++ b/reaper-adm-extension/src/reaper_adm/ui_text.cpp @@ -17,7 +17,34 @@ std::string eps::uiText(eps::TextID item) { {TextID::IMPORT_MENU, "ADM File to Import"}, {TextID::IMPORT_ACTION_PREFIX, "Import ADM file using "}, {TextID::IMPORT_ERROR_TITLE, "Error: This file can not be imported."}, - {TextID::IMPORT_ERROR_DESCRIPTION, "ADM Import"} + {TextID::IMPORT_ERROR_DESCRIPTION, "ADM Import"}, + {TextID::RENDERER_VALIDATING_DIALOG, "\r\nValidating Project Structure...\r\n\r\nPlease Wait..."}, + {TextID::RENDERER_EXPORT_SOURCE_PREFIX, "Using export source: \""}, + {TextID::RENDERER_ERROR_NO_EXPORT_SOURCES, ""}, + {TextID::RENDER_LOG_ERROR_HEADER, "\r\n\r\nERRORS:"}, + {TextID::RENDER_LOG_WARNING_HEADER, "\r\n\r\nWARNINGS:"}, + {TextID::RENDER_LOG_INFO_HEADER, "\r\nINFO:"}, + {TextID::RENDERER_ERROR_FAILED_CONTROL_OVERRIDE, "WARNING: Unable to takeover all render controls. REAPER version may be unsupported and render may fail.\r\n\r\n"}, + {TextID::EXPORT_DIALOG_TAKEOVER_TEXT_FOR_CHANNEL_COUNT, "Auto"}, + {TextID::EXPORT_DIALOG_FALLBACK_VALUE_FOR_CHANNEL_COUNT, "Stereo"}, + {TextID::EXPORT_HANDLER_ERROR_NO_VALID_SOURCES, "No Valid Export Sources!"}, + {TextID::EXPORT_HANDLER_ERROR_NO_CHANNELS, "Current configuration of export sources provides 0 channels of audio."}, + {TextID::EXPORT_HANDLER_WARNING_MULTIPLE_SOURCE_TYPES, "Multiple Types of Export Source!"}, + {TextID::EXPORT_SINK_ERROR_NO_SOURCES, "No suitable export sources within the current project.\r\nCan not continue with render."}, + {TextID::EXPORT_SINK_ERROR_NO_SOURCES_TITLE, "No Export Sources"}, + {TextID::EXPORT_SINK_ERROR_NO_CHANNELS, "The current configuration of export sources will export 0 channels of audio.\r\nCan not continue with render."}, + {TextID::EXPORT_SINK_ERROR_NO_CHANNELS_TITLE, "No Audio To Export"}, + {TextID::EXPORT_SINK_ERROR_SAMPLE_RATE, "Error: Sink sample rate ({}) does not match VST sample rate ({})!\r\nThis is likely an internal issue.\r\nCan not continue with render."}, + {TextID::EXPORT_SINK_ERROR_SAMPLE_RATE_TITLE, "Sample Rate Mismatch"}, + {TextID::EXPORT_SINK_ISSUES_HEADER, "Can not render due to the following issues:\r\n"}, + {TextID::EXPORT_SINK_ISSUES_TITLE, "Render Issues"}, + {TextID::EXPORT_SINK_ERROR_NO_ADM, "Error: No ADM metadata available for export.\r\nThis is likely an internal issue.\r\nCan not continue with render."}, + {TextID::EXPORT_SINK_ERROR_NO_ADM_TITLE, "No ADM Metadata"}, + {TextID::EXPORT_SINK_WARNING_FRAMES, "Warning:\r\nReceived {} frames from export source \"{}\".\r\nExpected {} frames."}, + {TextID::EXPORT_SINK_WARNING_FRAMES_TITLE, "Render"}, + {TextID::EXPORT_SINK_INFO_RENDERING,"Rendering ADM tracks..."}, + {TextID::EXPORT_SINK_WARNING_BAD_STRUCTURE, "WARNING: Unable to render - invalid project structure!"} + }; assert(dictionary.find(item) != dictionary.end()); return(dictionary.find(item) == dictionary.end()) ? "" : dictionary[item]; diff --git a/reaper-adm-extension/src/reaper_adm/ui_text.h b/reaper-adm-extension/src/reaper_adm/ui_text.h index 09954b49a..e1dec0edf 100644 --- a/reaper-adm-extension/src/reaper_adm/ui_text.h +++ b/reaper-adm-extension/src/reaper_adm/ui_text.h @@ -18,7 +18,33 @@ enum class TextID { IMPORT_ACTION_PREFIX, IMPORT_FILE_PROMPT, IMPORT_ERROR_TITLE, - IMPORT_ERROR_DESCRIPTION + IMPORT_ERROR_DESCRIPTION, + RENDERER_VALIDATING_DIALOG, + RENDERER_EXPORT_SOURCE_PREFIX, + RENDERER_ERROR_NO_EXPORT_SOURCES, + RENDER_LOG_ERROR_HEADER, + RENDER_LOG_WARNING_HEADER, + RENDER_LOG_INFO_HEADER, + RENDERER_ERROR_FAILED_CONTROL_OVERRIDE, + EXPORT_DIALOG_TAKEOVER_TEXT_FOR_CHANNEL_COUNT, + EXPORT_DIALOG_FALLBACK_VALUE_FOR_CHANNEL_COUNT, + EXPORT_HANDLER_ERROR_NO_VALID_SOURCES, + EXPORT_HANDLER_ERROR_NO_CHANNELS, + EXPORT_HANDLER_WARNING_MULTIPLE_SOURCE_TYPES, + EXPORT_SINK_ERROR_NO_SOURCES, + EXPORT_SINK_ERROR_NO_SOURCES_TITLE, + EXPORT_SINK_ERROR_NO_CHANNELS, + EXPORT_SINK_ERROR_NO_CHANNELS_TITLE, + EXPORT_SINK_ERROR_SAMPLE_RATE, + EXPORT_SINK_ERROR_SAMPLE_RATE_TITLE, + EXPORT_SINK_ISSUES_HEADER, + EXPORT_SINK_ISSUES_TITLE, + EXPORT_SINK_ERROR_NO_ADM, + EXPORT_SINK_ERROR_NO_ADM_TITLE, + EXPORT_SINK_WARNING_FRAMES, + EXPORT_SINK_WARNING_FRAMES_TITLE, + EXPORT_SINK_INFO_RENDERING, + EXPORT_SINK_WARNING_BAD_STRUCTURE }; std::string uiText(TextID item);