The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "../basics/juce_StandardHeader.h"
  19. BEGIN_JUCE_NAMESPACE
  20. #include "juce_LocalisedStrings.h"
  21. //==============================================================================
  22. LocalisedStrings::LocalisedStrings (const String& fileContents) throw()
  23. {
  24. loadFromText (fileContents);
  25. }
  26. LocalisedStrings::LocalisedStrings (const File& fileToLoad) throw()
  27. {
  28. loadFromText (fileToLoad.loadFileAsString());
  29. }
  30. LocalisedStrings::~LocalisedStrings() throw()
  31. {
  32. }
  33. //==============================================================================
  34. const String LocalisedStrings::translate (const String& text) const throw()
  35. {
  36. return translations.getValue (text, text);
  37. }
  38. static int findCloseQuote (const String& text, int startPos) throw()
  39. {
  40. tchar lastChar = 0;
  41. for (;;)
  42. {
  43. const tchar c = text [startPos];
  44. if (c == 0 || (c == T('"') && lastChar != T('\\')))
  45. break;
  46. lastChar = c;
  47. ++startPos;
  48. }
  49. return startPos;
  50. }
  51. static const String unescapeString (const String& s) throw()
  52. {
  53. return s.replace (T("\\\""), T("\""))
  54. .replace (T("\\\'"), T("\'"))
  55. .replace (T("\\t"), T("\t"))
  56. .replace (T("\\r"), T("\r"))
  57. .replace (T("\\n"), T("\n"));
  58. }
  59. void LocalisedStrings::loadFromText (const String& fileContents) throw()
  60. {
  61. StringArray lines;
  62. lines.addLines (fileContents);
  63. for (int i = 0; i < lines.size(); ++i)
  64. {
  65. String line (lines[i].trim());
  66. if (line.startsWithChar (T('"')))
  67. {
  68. int closeQuote = findCloseQuote (line, 1);
  69. const String originalText (unescapeString (line.substring (1, closeQuote)));
  70. if (originalText.isNotEmpty())
  71. {
  72. const int openingQuote = findCloseQuote (line, closeQuote + 1);
  73. closeQuote = findCloseQuote (line, openingQuote + 1);
  74. const String newText (unescapeString (line.substring (openingQuote + 1, closeQuote)));
  75. if (newText.isNotEmpty())
  76. translations.set (originalText, newText);
  77. }
  78. }
  79. else if (line.startsWithIgnoreCase (T("language:")))
  80. {
  81. languageName = line.substring (9).trim();
  82. }
  83. else if (line.startsWithIgnoreCase (T("countries:")))
  84. {
  85. countryCodes.addTokens (line.substring (10).trim(), true);
  86. countryCodes.trim();
  87. countryCodes.removeEmptyStrings();
  88. }
  89. }
  90. }
  91. void LocalisedStrings::setIgnoresCase (const bool shouldIgnoreCase) throw()
  92. {
  93. translations.setIgnoresCase (shouldIgnoreCase);
  94. }
  95. //==============================================================================
  96. static CriticalSection currentMappingsLock;
  97. static LocalisedStrings* currentMappings = 0;
  98. void LocalisedStrings::setCurrentMappings (LocalisedStrings* newTranslations) throw()
  99. {
  100. const ScopedLock sl (currentMappingsLock);
  101. delete currentMappings;
  102. currentMappings = newTranslations;
  103. }
  104. LocalisedStrings* LocalisedStrings::getCurrentMappings() throw()
  105. {
  106. return currentMappings;
  107. }
  108. const String LocalisedStrings::translateWithCurrentMappings (const String& text) throw()
  109. {
  110. const ScopedLock sl (currentMappingsLock);
  111. if (currentMappings != 0)
  112. return currentMappings->translate (text);
  113. return text;
  114. }
  115. const String LocalisedStrings::translateWithCurrentMappings (const char* text) throw()
  116. {
  117. return translateWithCurrentMappings (String (text));
  118. }
  119. END_JUCE_NAMESPACE