diff --git a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj index 29ad1533de..9a9c68a1d5 100644 --- a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj +++ b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj @@ -441,6 +441,7 @@ 54569C1C994F3A0255785EAA = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_android_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; 54747E887C1021F05F172B89 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; }; 54DAB21828DE5EEDABE2F5D4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = transupp.h; path = "../../../../modules/juce_graphics/image_formats/jpglib/transupp.h"; sourceTree = "SOURCE_ROOT"; }; + 546593F6EA70EABF708772FE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TranslationToolComponent.h"; path = "../../Source/Utility/jucer_TranslationToolComponent.h"; sourceTree = "SOURCE_ROOT"; }; 553725A0E3A391651ED1731E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FileHelpers.h"; path = "../../Source/Utility/jucer_FileHelpers.h"; sourceTree = "SOURCE_ROOT"; }; 55F7CE15FA02A9F599A83A58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; 563091B0916AD9AAA36C7DC5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_OpenDocumentManager.h"; path = "../../Source/Application/jucer_OpenDocumentManager.h"; sourceTree = "SOURCE_ROOT"; }; @@ -657,6 +658,7 @@ 8DDA82E1200B61D3B6C526E8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_graphics.h"; path = "../../../../modules/juce_graphics/juce_graphics.h"; sourceTree = "SOURCE_ROOT"; }; 8DEFBFC3BEDCCF29BA577EE9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MountedVolumeListChangeDetector.h"; path = "../../../../modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h"; sourceTree = "SOURCE_ROOT"; }; 8E00CF4CE2305C5CE5B60E37 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TopLevelWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.h"; sourceTree = "SOURCE_ROOT"; }; + 8C67B567CF362A163D24B3B1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TranslationHelpers.h"; path = "../../Source/Utility/jucer_TranslationHelpers.h"; sourceTree = "SOURCE_ROOT"; }; 8F30A53C7FE4BC65171FB3E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerDocument.h"; path = "../../Source/ComponentEditor/jucer_JucerDocument.h"; sourceTree = "SOURCE_ROOT"; }; 8F7BE18698ADCEF51CDE4A5C = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; 8F8BF1A7130D858E0A239F9E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ConfigTree_Base.h"; path = "../../Source/Project/jucer_ConfigTree_Base.h"; sourceTree = "SOURCE_ROOT"; }; @@ -960,7 +962,6 @@ D2F80DA0946A5EE01FC016CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; }; D374DC78AAC02504576AA9B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GroupComponentHandler.h"; path = "../../Source/ComponentEditor/components/jucer_GroupComponentHandler.h"; sourceTree = "SOURCE_ROOT"; }; D376B9B54EC944E766AFEC45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; }; - D3E139185095C486DD3D61F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TranslationTool.h"; path = "../../Source/Utility/jucer_TranslationTool.h"; sourceTree = "SOURCE_ROOT"; }; D4444EC6342A2A7BC4F7BC46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentTextProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_ComponentTextProperty.h"; sourceTree = "SOURCE_ROOT"; }; D4643408B22E79278A36EF58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = crc32.h; path = "../../../../modules/juce_core/zip/zlib/crc32.h"; sourceTree = "SOURCE_ROOT"; }; D4697A0232AECE5DAC5E332E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; @@ -1347,7 +1348,8 @@ 631983AA62673015F8D7453B, 9BC8AE609A07657CEF587548, B0D2198D1261755918CD454D, - D3E139185095C486DD3D61F2, + 8C67B567CF362A163D24B3B1, + 546593F6EA70EABF708772FE, 7F29F77B1C00A9704E6D0859, 8090981F07A76E465DAAADF4, ); name = Utility; sourceTree = ""; }; C5A691BE7288ADA68DC8D39A = {isa = PBXGroup; children = ( diff --git a/extras/Projucer/Builds/VisualStudio2013/Projucer.sln b/extras/Projucer/Builds/VisualStudio2013/Projucer.sln index 2470ce91a6..a9e08d0c45 100644 --- a/extras/Projucer/Builds/VisualStudio2013/Projucer.sln +++ b/extras/Projucer/Builds/VisualStudio2013/Projucer.sln @@ -236,7 +236,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utility", "Utility", "{5B44 ..\..\Source\Utility\jucer_StoredSettings.cpp = ..\..\Source\Utility\jucer_StoredSettings.cpp ..\..\Source\Utility\jucer_StoredSettings.h = ..\..\Source\Utility\jucer_StoredSettings.h ..\..\Source\Utility\jucer_SVGPathDataComponent.h = ..\..\Source\Utility\jucer_SVGPathDataComponent.h - ..\..\Source\Utility\jucer_TranslationTool.h = ..\..\Source\Utility\jucer_TranslationTool.h + ..\..\Source\Utility\jucer_TranslationHelpers.h = ..\..\Source\Utility\jucer_TranslationHelpers.h + ..\..\Source\Utility\jucer_TranslationToolComponent.h = ..\..\Source\Utility\jucer_TranslationToolComponent.h ..\..\Source\Utility\jucer_UTF8Component.h = ..\..\Source\Utility\jucer_UTF8Component.h ..\..\Source\Utility\jucer_ValueSourceHelpers.h = ..\..\Source\Utility\jucer_ValueSourceHelpers.h EndProjectSection diff --git a/extras/Projucer/Builds/VisualStudio2015/Projucer.sln b/extras/Projucer/Builds/VisualStudio2015/Projucer.sln index daeaaf5953..055a7c2092 100644 --- a/extras/Projucer/Builds/VisualStudio2015/Projucer.sln +++ b/extras/Projucer/Builds/VisualStudio2015/Projucer.sln @@ -236,7 +236,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utility", "Utility", "{5B44 ..\..\Source\Utility\jucer_StoredSettings.cpp = ..\..\Source\Utility\jucer_StoredSettings.cpp ..\..\Source\Utility\jucer_StoredSettings.h = ..\..\Source\Utility\jucer_StoredSettings.h ..\..\Source\Utility\jucer_SVGPathDataComponent.h = ..\..\Source\Utility\jucer_SVGPathDataComponent.h - ..\..\Source\Utility\jucer_TranslationTool.h = ..\..\Source\Utility\jucer_TranslationTool.h + ..\..\Source\Utility\jucer_TranslationHelpers.h = ..\..\Source\Utility\jucer_TranslationHelpers.h + ..\..\Source\Utility\jucer_TranslationToolComponent.h = ..\..\Source\Utility\jucer_TranslationToolComponent.h ..\..\Source\Utility\jucer_UTF8Component.h = ..\..\Source\Utility\jucer_UTF8Component.h ..\..\Source\Utility\jucer_ValueSourceHelpers.h = ..\..\Source\Utility\jucer_ValueSourceHelpers.h EndProjectSection diff --git a/extras/Projucer/Projucer.jucer b/extras/Projucer/Projucer.jucer index 5c2b27625d..dd4d5e9cc8 100644 --- a/extras/Projucer/Projucer.jucer +++ b/extras/Projucer/Projucer.jucer @@ -473,8 +473,10 @@ file="Source/Utility/jucer_StoredSettings.h"/> - + + r (getLocalBounds().withTrimmedBottom (m)); - instructionsLabel.setBounds (r.removeFromTop (textH * 2).reduced (m)); - r.removeFromTop (m); - Rectangle r2 (r.removeFromTop (textH - (2 * m))); - scanButton.setBounds (r2.removeFromLeft (r.getWidth() / 2).reduced (m, 0)); - loadButton.setBounds (r2.reduced (m, 0)); - - label1.setBounds (r.removeFromTop (textH).reduced (m)); - editorPre.setBounds (r.removeFromTop (editorH).reduced (m, 0)); - - label2.setBounds (r.removeFromTop (textH).reduced (m)); - editorPost.setBounds (r.removeFromTop (editorH).reduced (m, 0)); - - r2 = r.removeFromTop (textH); - generateButton.setBounds (r2.removeFromRight (152).reduced (m)); - label3.setBounds (r2.reduced (m)); - editorResult.setBounds (r.removeFromTop (editorH).reduced (m, 0)); - - label4.setBounds (r.removeFromTop (textH).reduced (m)); - editorOriginal.setBounds (r.reduced (m, 0)); - } - -private: - CodeDocument documentOriginal, documentPre, documentPost, documentResult; - CodeEditorComponent editorOriginal, editorPre, editorPost, editorResult; - juce::Label label1, label2, label3, label4; - juce::TextButton generateButton; - juce::Label instructionsLabel; - juce::TextButton scanButton; - juce::TextButton loadButton; - - ProjucerLookAndFeel lf; - - void buttonClicked (Button* b) override - { - if (b == &generateButton) generate(); - else if (b == &loadButton) loadFile(); - else if (b == &scanButton) scanProject(); - } - - void generate() - { - StringArray preStrings (TranslationHelpers::breakApart (documentPre.getAllContent())); - StringArray postStrings (TranslationHelpers::breakApart (documentPost.getAllContent())); - - if (postStrings.size() != preStrings.size()) - { - AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, - TRANS("Error"), - TRANS("The pre- and post-translation text doesn't match!\n\n" - "Perhaps it got mangled by the translator?")); - return; - } - - const LocalisedStrings originalTranslation (documentOriginal.getAllContent(), false); - documentResult.replaceAllContent (TranslationHelpers::createFinishedTranslationFile (preStrings, postStrings, originalTranslation)); - } - - void loadFile() - { - FileChooser fc ("Choose a translation file to load", - File(), "*"); - - if (fc.browseForFileToOpen()) - { - const LocalisedStrings loadedStrings (fc.getResult(), false); - documentOriginal.replaceAllContent (fc.getResult().loadFileAsString().trim()); - setPreTranslationText (TranslationHelpers::getPreTranslationText (loadedStrings)); - } - } - - void scanProject() - { - if (Project* project = ProjucerApplication::getApp().mainWindowList.getFrontmostProject()) - setPreTranslationText (TranslationHelpers::getPreTranslationText (*project)); - else - AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Translation Tool", - "This will only work when you have a project open!"); - } - - void setPreTranslationText (const String& text) - { - documentPre.replaceAllContent (text); - editorPre.grabKeyboardFocus(); - editorPre.selectAll(); - } -}; diff --git a/extras/Projucer/Source/Utility/jucer_TranslationToolComponent.h b/extras/Projucer/Source/Utility/jucer_TranslationToolComponent.h new file mode 100644 index 0000000000..2c2922e41c --- /dev/null +++ b/extras/Projucer/Source/Utility/jucer_TranslationToolComponent.h @@ -0,0 +1,205 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2015 - ROLI Ltd. + + Permission is granted to use this software under the terms of either: + a) the GPL v2 (or any later version) + b) the Affero GPL v3 + + Details of these licenses can be found at: www.gnu.org/licenses + + JUCE 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. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.juce.com for more information. + + ============================================================================== +*/ + +#ifndef JUCER_TRANSLATIONTOOLCOMPONENT_H_INCLUDED +#define JUCER_TRANSLATIONTOOLCOMPONENT_H_INCLUDED + +#include "jucer_TranslationHelpers.h" + +//============================================================================== +class TranslationToolComponent : public Component, + public ButtonListener +{ +public: + TranslationToolComponent() + : editorOriginal (documentOriginal, nullptr), + editorPre (documentPre, nullptr), + editorPost (documentPost, nullptr), + editorResult (documentResult, nullptr) + { + setLookAndFeel (&lf); + + instructionsLabel.setText ( + "This utility converts translation files to/from a format that can be passed to automatic translation tools." + "\n\n" + "First, choose whether to scan the current project for all TRANS() macros, or " + "pick an existing translation file to load:", dontSendNotification); + addAndMakeVisible (instructionsLabel); + + label1.setText ("..then copy-and-paste this annotated text into Google Translate or some other translator:", dontSendNotification); + addAndMakeVisible (label1); + + label2.setText ("...then, take the translated result and paste it into the box below:", dontSendNotification); + addAndMakeVisible (label2); + + label3.setText ("Finally, click the 'Generate' button, and a translation file will be created below. " + "Remember to update its language code at the top!", dontSendNotification); + addAndMakeVisible (label3); + + label4.setText ("If you load an existing file the already translated strings will be removed. Ensure this box is empty to create a fresh translation", dontSendNotification); + addAndMakeVisible (label4); + + addAndMakeVisible (editorOriginal); + addAndMakeVisible (editorPre); + addAndMakeVisible (editorPost); + addAndMakeVisible (editorResult); + + generateButton.setButtonText (TRANS("Generate")); + addAndMakeVisible (generateButton); + scanProjectButton.setButtonText ("Scan Project for TRANS macros"); + addAndMakeVisible (scanProjectButton); + scanFolderButton.setButtonText ("Scan Folder for TRANS macros"); + addAndMakeVisible (scanFolderButton); + loadTranslationButton.setButtonText ("Load existing translation File..."); + addAndMakeVisible (loadTranslationButton); + generateButton.addListener (this); + + scanProjectButton.addListener (this); + scanFolderButton.addListener (this); + loadTranslationButton.addListener (this); + } + + void paint (Graphics& g) override + { + ProjucerLookAndFeel::fillWithBackgroundTexture (*this, g); + } + + void resized() override + { + const int m = 6; + const int textH = 44; + const int extraH = (7 * textH); + const int editorH = (getHeight() - extraH) / 4; + const int numButtons = 3; + + Rectangle r (getLocalBounds().withTrimmedBottom (m)); + const int buttonWidth = r.getWidth() / numButtons; + + instructionsLabel.setBounds (r.removeFromTop (textH * 2).reduced (m)); + r.removeFromTop (m); + Rectangle r2 (r.removeFromTop (textH - (2 * m))); + scanProjectButton .setBounds (r2.removeFromLeft (buttonWidth).reduced (m, 0)); + scanFolderButton .setBounds (r2.removeFromLeft (buttonWidth).reduced (m, 0)); + loadTranslationButton.setBounds (r2.reduced (m, 0)); + + label1 .setBounds (r.removeFromTop (textH) .reduced (m)); + editorPre.setBounds (r.removeFromTop (editorH).reduced (m, 0)); + + label2 .setBounds (r.removeFromTop (textH) .reduced (m)); + editorPost.setBounds (r.removeFromTop (editorH).reduced (m, 0)); + + r2 = r.removeFromTop (textH); + generateButton.setBounds (r2.removeFromRight (152).reduced (m)); + label3 .setBounds (r2.reduced (m)); + editorResult .setBounds (r.removeFromTop (editorH).reduced (m, 0)); + + label4 .setBounds (r.removeFromTop (textH).reduced (m)); + editorOriginal.setBounds (r.reduced (m, 0)); + } + +private: + CodeDocument documentOriginal, documentPre, documentPost, documentResult; + CodeEditorComponent editorOriginal, editorPre, editorPost, editorResult; + juce::Label label1, label2, label3, label4; + juce::TextButton generateButton; + juce::Label instructionsLabel; + juce::TextButton scanProjectButton; + juce::TextButton scanFolderButton; + juce::TextButton loadTranslationButton; + + ProjucerLookAndFeel lf; + + void buttonClicked (Button* b) override + { + if (b == &generateButton) generate(); + else if (b == &scanProjectButton) scanProject(); + else if (b == &scanFolderButton) scanFolder(); + else if (b == &loadTranslationButton) loadFile(); + else + jassertfalse; + } + + void generate() + { + StringArray preStrings (TranslationHelpers::breakApart (documentPre.getAllContent())); + StringArray postStrings (TranslationHelpers::breakApart (documentPost.getAllContent())); + + if (postStrings.size() != preStrings.size()) + { + AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, + TRANS("Error"), + TRANS("The pre- and post-translation text doesn't match!\n\n" + "Perhaps it got mangled by the translator?")); + return; + } + + const LocalisedStrings originalTranslation (documentOriginal.getAllContent(), false); + documentResult.replaceAllContent (TranslationHelpers::createFinishedTranslationFile (preStrings, postStrings, originalTranslation)); + } + + void scanProject() + { + if (Project* project = ProjucerApplication::getApp().mainWindowList.getFrontmostProject()) + setPreTranslationText (TranslationHelpers::getPreTranslationText (*project)); + else + AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Translation Tool", + "This will only work when you have a project open!"); + } + + void scanFolder() + { + FileChooser fc ("Choose the root folder to search for the TRANS macros", + File(), "*"); + + if (fc.browseForDirectory()) + { + StringArray strings; + TranslationHelpers::scanFolderForTranslations (strings, fc.getResult()); + setPreTranslationText (TranslationHelpers::mungeStrings(strings)); + } + } + + void loadFile() + { + FileChooser fc ("Choose a translation file to load", + File(), "*"); + + if (fc.browseForFileToOpen()) + { + const LocalisedStrings loadedStrings (fc.getResult(), false); + documentOriginal.replaceAllContent (fc.getResult().loadFileAsString().trim()); + setPreTranslationText (TranslationHelpers::getPreTranslationText (loadedStrings)); + } + } + + void setPreTranslationText (const String& text) + { + documentPre.replaceAllContent (text); + editorPre.grabKeyboardFocus(); + editorPre.selectAll(); + } +}; + + +#endif // JUCER_TRANSLATIONTOOLCOMPONENT_H_INCLUDED