| @@ -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 | |||
| @@ -714,16 +714,19 @@ static void addFileWithGroups (Project::Item& group, const RelativePath& file, c | |||
| } | |||
| } | |||
| void LibraryModule::findBrowseableFiles (const File& localModuleFolder, Array<File>& filesFound) const | |||
| { | |||
| const var filesArray (moduleInfo ["browse"]); | |||
| const Array<var>* 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<File>& compiled, const File& localModuleFolder) const | |||
| { | |||
| if (sourceFiles.size() == 0) | |||
| { | |||
| const var filesArray (moduleInfo ["browse"]); | |||
| const Array<var>* 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())); | |||
| @@ -51,6 +51,7 @@ public: | |||
| void createPropertyEditors (ProjectExporter&, PropertyListBuilder&) const; | |||
| void getConfigFlags (Project&, OwnedArray<Project::ConfigFlag>& flags) const; | |||
| void getLocalCompiledFiles (const File& localModuleFolder, Array<File>& files) const; | |||
| void findBrowseableFiles (const File& localModuleFolder, Array<File>& files) const; | |||
| File getLocalFolderFor (Project&) const; | |||
| static String getInfoFileName() { return "juce_module_info"; } | |||
| @@ -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 (", ")); | |||
| } | |||
| @@ -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) | |||
| @@ -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 | |||
| */ | |||
| @@ -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"); | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| @@ -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)); | |||
| } | |||
| @@ -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); | |||
| @@ -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(); | |||
| } | |||
| @@ -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); | |||
| @@ -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, | |||