diff --git a/extras/Introjucer/Source/Application/jucer_OpenDocumentManager.cpp b/extras/Introjucer/Source/Application/jucer_OpenDocumentManager.cpp index 71384e0a76..1856e9d1e0 100644 --- a/extras/Introjucer/Source/Application/jucer_OpenDocumentManager.cpp +++ b/extras/Introjucer/Source/Application/jucer_OpenDocumentManager.cpp @@ -173,9 +173,9 @@ FileBasedDocument::SaveResult OpenDocumentManager::saveIfNeededAndUserAgrees (Op TRANS("Closing document..."), TRANS("Do you want to save the changes to \"") + doc->getName() + "\"?", - TRANS("save"), - TRANS("discard changes"), - TRANS("cancel")); + TRANS("Save"), + TRANS("Discard changes"), + TRANS("Cancel")); if (r == 1) // save changes return doc->save() ? FileBasedDocument::savedOk diff --git a/extras/Introjucer/Source/Project/jucer_Module.cpp b/extras/Introjucer/Source/Project/jucer_Module.cpp index 77937a35fc..c64e89612c 100644 --- a/extras/Introjucer/Source/Project/jucer_Module.cpp +++ b/extras/Introjucer/Source/Project/jucer_Module.cpp @@ -714,16 +714,19 @@ static void addFileWithGroups (Project::Item& group, const RelativePath& file, c } } +void LibraryModule::findBrowseableFiles (const File& localModuleFolder, Array& filesFound) const +{ + const var filesArray (moduleInfo ["browse"]); + const Array* const files = filesArray.getArray(); + + for (int i = 0; i < files->size(); ++i) + findWildcardMatches (localModuleFolder, files->getReference(i), filesFound); +} + void LibraryModule::addBrowsableCode (ProjectExporter& exporter, const Array& compiled, const File& localModuleFolder) const { if (sourceFiles.size() == 0) - { - const var filesArray (moduleInfo ["browse"]); - const Array* const files = filesArray.getArray(); - - for (int i = 0; i < files->size(); ++i) - findWildcardMatches (localModuleFolder, files->getReference(i), sourceFiles); - } + findBrowseableFiles (localModuleFolder, sourceFiles); Project::Item sourceGroup (Project::Item::createGroup (exporter.getProject(), getID(), "__mainsourcegroup" + getID())); diff --git a/extras/Introjucer/Source/Project/jucer_Module.h b/extras/Introjucer/Source/Project/jucer_Module.h index a529a071cc..8911f37cb8 100644 --- a/extras/Introjucer/Source/Project/jucer_Module.h +++ b/extras/Introjucer/Source/Project/jucer_Module.h @@ -51,6 +51,7 @@ public: void createPropertyEditors (ProjectExporter&, PropertyListBuilder&) const; void getConfigFlags (Project&, OwnedArray& flags) const; void getLocalCompiledFiles (const File& localModuleFolder, Array& files) const; + void findBrowseableFiles (const File& localModuleFolder, Array& files) const; File getLocalFolderFor (Project&) const; static String getInfoFileName() { return "juce_module_info"; } diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 560754e11b..72a7f2e91f 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -355,7 +355,7 @@ private: bool doNextScan() { - progressMessage = TRANS("Testing:\n\n") + scanner->getNextPluginFileThatWillBeScanned(); + progressMessage = TRANS("Testing") + ":\n\n" + scanner->getNextPluginFileThatWillBeScanned(); if (scanner->scanNextFile (true)) { @@ -419,6 +419,7 @@ void PluginListComponent::scanFinished (const StringArray& failedFiles) if (shortNames.size() > 0) AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon, TRANS("Scan complete"), - TRANS("Note that the following files appeared to be plugin files, but failed to load correctly:\n\n") + TRANS("Note that the following files appeared to be plugin files, but failed to load correctly") + + ":\n\n" + shortNames.joinIntoString (", ")); } diff --git a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp index 99d59ee56d..f58f9887e1 100644 --- a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp @@ -70,7 +70,6 @@ class AudioDeviceSelectorComponent::MidiInputSelectorComponentListBox : public private ListBoxModel { public: - //============================================================================== MidiInputSelectorComponentListBox (AudioDeviceManager& deviceManager_, const String& noItemsMessage_, const int minNumber_, @@ -193,6 +192,7 @@ struct AudioDeviceSetupDetails bool useStereoPairs; }; +static String getNoDeviceString() { return "<< " + TRANS("none") + " >>"); } //============================================================================== class AudioDeviceSettingsPanel : public Component, @@ -515,7 +515,7 @@ private: for (int i = 0; i < devs.size(); ++i) combo.addItem (devs[i], i + 1); - combo.addItem (TRANS("<< none >>"), -1); + combo.addItem (getNoDeviceString(), -1); combo.setSelectedId (-1, true); } @@ -959,7 +959,7 @@ AudioDeviceSelectorComponent::AudioDeviceSelectorComponent (AudioDeviceManager& { addAndMakeVisible (midiInputsList = new MidiInputSelectorComponentListBox (deviceManager, - TRANS("(No MIDI inputs available)"), + "(" + TRANS("No MIDI inputs available") + ")", 0, 0)); midiInputsLabel = new Label (String::empty, TRANS ("Active MIDI inputs:")); @@ -1102,7 +1102,7 @@ void AudioDeviceSelectorComponent::updateAllControls() const StringArray midiOuts (MidiOutput::getDevices()); - midiOutputSelector->addItem (TRANS("<< none >>"), -1); + midiOutputSelector->addItem (getNoDeviceString(), -1); midiOutputSelector->addSeparator(); for (int i = 0; i < midiOuts.size(); ++i) diff --git a/modules/juce_core/text/juce_LocalisedStrings.h b/modules/juce_core/text/juce_LocalisedStrings.h index 5a4dfa9dce..58f620476c 100644 --- a/modules/juce_core/text/juce_LocalisedStrings.h +++ b/modules/juce_core/text/juce_LocalisedStrings.h @@ -109,7 +109,7 @@ public: /** Returns the currently selected set of mappings. This is the object that was last passed to setCurrentMappings(). It may - be 0 if none has been created. + be nullptr if none has been created. */ static LocalisedStrings* getCurrentMappings(); @@ -195,6 +195,15 @@ private: #define TRANS(stringLiteral) juce::translate (stringLiteral) #endif +/** A dummy version of the TRANS macro, used to indicate a string literal that should be + added to the translation file by source-code scanner tools. + + Wrapping a string literal in this macro has no effect, but by using it around strings + that your app needs to translate at a later stage, it lets automatic code-scanning tools + find this string and add it to the list of strings that need translation. +*/ +#define NEEDS_TRANS(stringLiteral) (stringLiteral) + /** Uses the LocalisedStrings class to translate the given string literal. @see LocalisedStrings */ diff --git a/modules/juce_core/time/juce_RelativeTime.cpp b/modules/juce_core/time/juce_RelativeTime.cpp index cb98655fe5..4f6db36bc5 100644 --- a/modules/juce_core/time/juce_RelativeTime.cpp +++ b/modules/juce_core/time/juce_RelativeTime.cpp @@ -61,6 +61,13 @@ bool operator>= (const RelativeTime& t1, const RelativeTime& t2) noexcept bool operator<= (const RelativeTime& t1, const RelativeTime& t2) noexcept { return t1.inSeconds() <= t2.inSeconds(); } //============================================================================== +static void translateTimeField (String& result, int n, const char* singular, const char* plural) +{ + result << TRANS (n == 1 ? singular : plural) + .replace (n == 1 ? "1" : "2", String (n)) + << ' '; +} + String RelativeTime::getDescription (const String& returnValueForZeroTime) const { if (seconds < 0.001 && seconds > -0.001) @@ -76,16 +83,14 @@ String RelativeTime::getDescription (const String& returnValueForZeroTime) const int n = std::abs ((int) inWeeks()); if (n > 0) { - result << n << TRANS (n == 1 ? " week " - : " weeks "); + translateTimeField (result, n, NEEDS_TRANS("1 week"), NEEDS_TRANS("2 weeks")); ++fieldsShown; } n = std::abs ((int) inDays()) % 7; if (n > 0) { - result << n << TRANS (n == 1 ? " day " - : " days "); + translateTimeField (result, n, NEEDS_TRANS("1 day"), NEEDS_TRANS("2 days")); ++fieldsShown; } @@ -94,8 +99,7 @@ String RelativeTime::getDescription (const String& returnValueForZeroTime) const n = std::abs ((int) inHours()) % 24; if (n > 0) { - result << n << TRANS (n == 1 ? " hr " - : " hrs "); + translateTimeField (result, n, NEEDS_TRANS("1 hr"), NEEDS_TRANS("2 hrs")); ++fieldsShown; } @@ -104,8 +108,7 @@ String RelativeTime::getDescription (const String& returnValueForZeroTime) const n = std::abs ((int) inMinutes()) % 60; if (n > 0) { - result << n << TRANS (n == 1 ? " min " - : " mins "); + translateTimeField (result, n, NEEDS_TRANS("1 min"), NEEDS_TRANS("2 mins")); ++fieldsShown; } @@ -114,8 +117,7 @@ String RelativeTime::getDescription (const String& returnValueForZeroTime) const n = std::abs ((int) inSeconds()) % 60; if (n > 0) { - result << n << TRANS (n == 1 ? " sec " - : " secs "); + translateTimeField (result, n, NEEDS_TRANS("1 sec"), NEEDS_TRANS("2 secs")); ++fieldsShown; } @@ -123,7 +125,7 @@ String RelativeTime::getDescription (const String& returnValueForZeroTime) const { n = std::abs ((int) inMilliseconds()) % 1000; if (n > 0) - result << n << TRANS (" ms"); + result << n << ' ' << TRANS ("ms"); } } } diff --git a/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp index 0b38a6b97b..8a1578b168 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp @@ -102,7 +102,7 @@ FileBrowserComponent::FileBrowserComponent (int flags_, addAndMakeVisible (goUpButton = getLookAndFeel().createFileBrowserGoUpButton()); goUpButton->addListener (this); - goUpButton->setTooltip (TRANS ("go up to parent directory")); + goUpButton->setTooltip (TRANS ("Go up to parent directory")); if (previewComp != nullptr) addAndMakeVisible (previewComp); @@ -523,7 +523,7 @@ void FileBrowserComponent::getRoots (StringArray& rootNames, StringArray& rootPa } else if (drive.isOnCDRomDrive()) { - name << TRANS(" [CD/DVD drive]"); + name << " [" << TRANS("CD/DVD drive") << ']'; } rootNames.add (name); diff --git a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp index 7175145a82..874e34dd43 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp @@ -209,12 +209,13 @@ void FileChooserDialogBox::okButtonPressed() && content->chooserComponent.getSelectedFile(0).exists()) { AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, - TRANS("File already exists"), - TRANS("There's already a file called:") - + "\n\n" + content->chooserComponent.getSelectedFile(0).getFullPathName() - + "\n\n" + TRANS("Are you sure you want to overwrite it?"), - TRANS("overwrite"), - TRANS("cancel"), + TRANS("File already exists"), + TRANS("There's already a file called: FLMN") + .replace ("FLNM", content->chooserComponent.getSelectedFile(0).getFullPathName()) + + "\n\n" + + TRANS("Are you sure you want to overwrite it?"), + TRANS("Overwrite"), + TRANS("Cancel"), this, ModalCallbackFunction::forComponent (okToOverwriteFileCallback, this)); } diff --git a/modules/juce_gui_basics/widgets/juce_Toolbar.cpp b/modules/juce_gui_basics/widgets/juce_Toolbar.cpp index 2b445f437e..5fd3422db8 100644 --- a/modules/juce_gui_basics/widgets/juce_Toolbar.cpp +++ b/modules/juce_gui_basics/widgets/juce_Toolbar.cpp @@ -708,8 +708,9 @@ private: : factory (factory_), toolbar (toolbar_), palette (factory_, toolbar_), - instructions (String::empty, TRANS ("You can drag the items above and drop them onto a toolbar to add them.\n\n" - "Items on the toolbar can also be dragged around to change their order, or dragged off the edge to delete them.")), + instructions (String::empty, TRANS ("You can drag the items above and drop them onto a toolbar to add them.") + + "\n\n" + + TRANS ("Items on the toolbar can also be dragged around to change their order, or dragged off the edge to delete them.")), defaultButton (TRANS ("Restore to default set of items")) { addAndMakeVisible (&palette); diff --git a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp index dd0dc72507..7c625ed2a8 100644 --- a/modules/juce_gui_basics/windows/juce_AlertWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_AlertWindow.cpp @@ -632,7 +632,7 @@ void AlertWindow::showMessageBox (AlertIconType iconType, else { AlertWindowInfo info (title, message, associatedComponent, iconType, 1, nullptr, true); - info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; + info.button1 = buttonText.isEmpty() ? TRANS("OK") : buttonText; info.invoke(); } @@ -653,7 +653,7 @@ void AlertWindow::showMessageBoxAsync (AlertIconType iconType, else { AlertWindowInfo info (title, message, associatedComponent, iconType, 1, callback, false); - info.button1 = buttonText.isEmpty() ? TRANS("ok") : buttonText; + info.button1 = buttonText.isEmpty() ? TRANS("OK") : buttonText; info.invoke(); } @@ -671,8 +671,8 @@ bool AlertWindow::showOkCancelBox (AlertIconType iconType, return NativeMessageBox::showOkCancelBox (iconType, title, message, associatedComponent, callback); AlertWindowInfo info (title, message, associatedComponent, iconType, 2, callback, callback == nullptr); - info.button1 = button1Text.isEmpty() ? TRANS("ok") : button1Text; - info.button2 = button2Text.isEmpty() ? TRANS("cancel") : button2Text; + info.button1 = button1Text.isEmpty() ? TRANS("OK") : button1Text; + info.button2 = button2Text.isEmpty() ? TRANS("Cancel") : button2Text; return info.invoke() != 0; } @@ -690,9 +690,9 @@ int AlertWindow::showYesNoCancelBox (AlertIconType iconType, return NativeMessageBox::showYesNoCancelBox (iconType, title, message, associatedComponent, callback); AlertWindowInfo info (title, message, associatedComponent, iconType, 3, callback, callback == nullptr); - info.button1 = button1Text.isEmpty() ? TRANS("yes") : button1Text; - info.button2 = button2Text.isEmpty() ? TRANS("no") : button2Text; - info.button3 = button3Text.isEmpty() ? TRANS("cancel") : button3Text; + info.button1 = button1Text.isEmpty() ? TRANS("Yes") : button1Text; + info.button2 = button2Text.isEmpty() ? TRANS("No") : button2Text; + info.button3 = button3Text.isEmpty() ? TRANS("Cancel") : button3Text; return info.invoke(); } diff --git a/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp b/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp index 8c8d565cc3..ae56fba91e 100644 --- a/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp +++ b/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp @@ -98,8 +98,8 @@ bool FileBasedDocument::loadFrom (const File& newFile, { AlertWindow::showMessageBox (AlertWindow::WarningIcon, TRANS("Failed to open file..."), - TRANS("There was an error while trying to load the file:\n\n") - + newFile.getFullPathName() + TRANS("There was an error while trying to load the file: FLNM") + .replace ("FLNM", "\n" + newFile.getFullPathName()) + "\n\n" + result.getErrorMessage()); } @@ -119,6 +119,18 @@ bool FileBasedDocument::loadFromUserSpecifiedFile (const bool showMessageOnFailu return false; } +static bool askToOverwriteFile (const File& newFile) +{ + return AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, + TRANS("File already exists"), + TRANS("There's already a file called: FLMN") + .replace ("FLNM", newFile.getFullPathName()) + + "\n\n" + + TRANS("Are you sure you want to overwrite it?"), + TRANS("Overwrite"), + TRANS("Cancel")); +} + //============================================================================== FileBasedDocument::SaveResult FileBasedDocument::save (const bool askUserForFileIfNotSpecified, const bool showMessageOnFailure) @@ -144,19 +156,10 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile, return failedToWriteToFile; } - if (warnAboutOverwritingExistingFiles && newFile.exists()) - { - if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, - TRANS("File already exists"), - TRANS("There's already a file called:\n\n") - + newFile.getFullPathName() - + TRANS("\n\nAre you sure you want to overwrite it?"), - TRANS("overwrite"), - TRANS("cancel"))) - { - return userCancelledSave; - } - } + if (warnAboutOverwritingExistingFiles + && newFile.exists() + && ! askToOverwriteFile (newFile)) + return userCancelledSave; MouseCursor::showWaitCursor(); @@ -180,10 +183,9 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile, { AlertWindow::showMessageBox (AlertWindow::WarningIcon, TRANS("Error writing to file..."), - TRANS("An error occurred while trying to save \"") - + getDocumentTitle() - + TRANS("\" to the file:\n\n") - + newFile.getFullPathName() + TRANS("An error occurred while trying to save \"DCNM\" to the file: FLNM") + .replace ("DCNM", getDocumentTitle()) + .replace ("FLNM", "\n" + newFile.getFullPathName()) + "\n\n" + result.getErrorMessage()); } @@ -198,11 +200,11 @@ FileBasedDocument::SaveResult FileBasedDocument::saveIfNeededAndUserAgrees() const int r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon, TRANS("Closing document..."), - TRANS("Do you want to save the changes to \"") - + getDocumentTitle() + "\"?", - TRANS("save"), - TRANS("discard changes"), - TRANS("cancel")); + TRANS("Do you want to save the changes to \"DCNM\"?") + .replace ("DCNM", getDocumentTitle()), + TRANS("Save"), + TRANS("Discard changes"), + TRANS("Cancel")); if (r == 1) // save changes return save (true, true); @@ -248,19 +250,8 @@ FileBasedDocument::SaveResult FileBasedDocument::saveAsInteractive (const bool w { chosen = chosen.withFileExtension (fileExtension); - if (chosen.exists()) - { - if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, - TRANS("File already exists"), - TRANS("There's already a file called:") - + "\n\n" + chosen.getFullPathName() - + "\n\n" + TRANS("Are you sure you want to overwrite it?"), - TRANS("overwrite"), - TRANS("cancel"))) - { - return userCancelledSave; - } - } + if (chosen.exists() && ! askToOverwriteFile (chosen)) + return userCancelledSave; } setLastDocumentOpened (chosen); diff --git a/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp b/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp index 8245ee1a0d..84316b1271 100644 --- a/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp +++ b/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp @@ -96,7 +96,7 @@ public: AlertWindow::NoIcon), owner (kec) { - addButton (TRANS("Ok"), 1); + addButton (TRANS("OK"), 1); addButton (TRANS("Cancel"), 0); // (avoid return + escape keys getting processed by the buttons..) @@ -110,13 +110,15 @@ public: bool keyPressed (const KeyPress& key) { lastPress = key; - String message (TRANS("Key: ") + owner.getDescriptionForKeyPress (key)); + String message (TRANS("Key") + ": " + owner.getDescriptionForKeyPress (key)); const CommandID previousCommand = owner.getMappings().findCommandForKeyPress (key); if (previousCommand != 0) - message << "\n\n" << TRANS("(Currently assigned to \"") - << owner.getCommandManager().getNameOfCommand (previousCommand) << "\")"; + message << "\n\n(" + << TRANS("Currently assigned to \"CMDN\"") + .replace ("CMDN", owner.getCommandManager().getNameOfCommand (previousCommand)) + << ')'; setMessage (message); return true; @@ -160,9 +162,10 @@ public: { AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, TRANS("Change key-mapping"), - TRANS("This key is already assigned to the command \"") - + owner.getCommandManager().getNameOfCommand (previousCommand) - + TRANS("\"\n\nDo you want to re-assign it to this new command instead?"), + TRANS("This key is already assigned to the command \"CMDN\"") + .replace ("CMDN", owner.getCommandManager().getNameOfCommand (previousCommand)) + + "\n\n" + + TRANS("Do you want to re-assign it to this new command instead?"), TRANS("Re-assign"), TRANS("Cancel"), this,