OpenShot Library | libopenshot-audio  0.2.0
juce_LocalisedStrings.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 LocalisedStrings::LocalisedStrings (const String& fileContents, bool ignoreCase)
27 {
28  loadFromText (fileContents, ignoreCase);
29 }
30 
31 LocalisedStrings::LocalisedStrings (const File& fileToLoad, bool ignoreCase)
32 {
33  loadFromText (fileToLoad.loadFileAsString(), ignoreCase);
34 }
35 
37  : languageName (other.languageName), countryCodes (other.countryCodes),
38  translations (other.translations), fallback (createCopyIfNotNull (other.fallback.get()))
39 {
40 }
41 
42 LocalisedStrings& LocalisedStrings::operator= (const LocalisedStrings& other)
43 {
44  languageName = other.languageName;
45  countryCodes = other.countryCodes;
46  translations = other.translations;
47  fallback.reset (createCopyIfNotNull (other.fallback.get()));
48  return *this;
49 }
50 
52 {
53 }
54 
55 //==============================================================================
57 {
58  if (fallback != nullptr && ! translations.containsKey (text))
59  return fallback->translate (text);
60 
61  return translations.getValue (text, text);
62 }
63 
64 String LocalisedStrings::translate (const String& text, const String& resultIfNotFound) const
65 {
66  if (fallback != nullptr && ! translations.containsKey (text))
67  return fallback->translate (text, resultIfNotFound);
68 
69  return translations.getValue (text, resultIfNotFound);
70 }
71 
72 namespace
73 {
74  #if JUCE_CHECK_MEMORY_LEAKS
75  // By using this object to force a LocalisedStrings object to be created
76  // before the currentMappings object, we can force the static order-of-destruction to
77  // delete the currentMappings object first, which avoids a bogus leak warning.
78  // (Oddly, just creating a LocalisedStrings on the stack doesn't work in gcc, it
79  // has to be created with 'new' for this to work..)
80  struct LeakAvoidanceTrick
81  {
82  LeakAvoidanceTrick()
83  {
84  const std::unique_ptr<LocalisedStrings> dummy (new LocalisedStrings (String(), false));
85  }
86  };
87 
88  LeakAvoidanceTrick leakAvoidanceTrick;
89  #endif
90 
91  SpinLock currentMappingsLock;
92  std::unique_ptr<LocalisedStrings> currentMappings;
93 
94  static int findCloseQuote (const String& text, int startPos)
95  {
96  juce_wchar lastChar = 0;
97  auto t = text.getCharPointer() + startPos;
98 
99  for (;;)
100  {
101  auto c = t.getAndAdvance();
102 
103  if (c == 0 || (c == '"' && lastChar != '\\'))
104  break;
105 
106  lastChar = c;
107  ++startPos;
108  }
109 
110  return startPos;
111  }
112 
113  static String unescapeString (const String& s)
114  {
115  return s.replace ("\\\"", "\"")
116  .replace ("\\\'", "\'")
117  .replace ("\\t", "\t")
118  .replace ("\\r", "\r")
119  .replace ("\\n", "\n");
120  }
121 }
122 
123 void LocalisedStrings::loadFromText (const String& fileContents, bool ignoreCase)
124 {
125  translations.setIgnoresCase (ignoreCase);
126 
127  StringArray lines;
128  lines.addLines (fileContents);
129 
130  for (auto& l : lines)
131  {
132  auto line = l.trim();
133 
134  if (line.startsWithChar ('"'))
135  {
136  auto closeQuote = findCloseQuote (line, 1);
137  auto originalText = unescapeString (line.substring (1, closeQuote));
138 
139  if (originalText.isNotEmpty())
140  {
141  auto openingQuote = findCloseQuote (line, closeQuote + 1);
142  closeQuote = findCloseQuote (line, openingQuote + 1);
143  auto newText = unescapeString (line.substring (openingQuote + 1, closeQuote));
144 
145  if (newText.isNotEmpty())
146  translations.set (originalText, newText);
147  }
148  }
149  else if (line.startsWithIgnoreCase ("language:"))
150  {
151  languageName = line.substring (9).trim();
152  }
153  else if (line.startsWithIgnoreCase ("countries:"))
154  {
155  countryCodes.addTokens (line.substring (10).trim(), true);
156  countryCodes.trim();
157  countryCodes.removeEmptyStrings();
158  }
159  }
160 
161  translations.minimiseStorageOverheads();
162 }
163 
165 {
166  jassert (languageName == other.languageName);
167  jassert (countryCodes == other.countryCodes);
168 
169  translations.addArray (other.translations);
170 }
171 
173 {
174  fallback.reset (f);
175 }
176 
177 //==============================================================================
179 {
180  const SpinLock::ScopedLockType sl (currentMappingsLock);
181  currentMappings.reset (newTranslations);
182 }
183 
185 {
186  return currentMappings.get();
187 }
188 
189 String LocalisedStrings::translateWithCurrentMappings (const String& text) { return juce::translate (text); }
190 String LocalisedStrings::translateWithCurrentMappings (const char* text) { return juce::translate (text); }
191 
192 JUCE_API String translate (const String& text) { return juce::translate (text, text); }
193 JUCE_API String translate (const char* text) { return juce::translate (String (text)); }
194 JUCE_API String translate (CharPointer_UTF8 text) { return juce::translate (String (text)); }
195 
196 JUCE_API String translate (const String& text, const String& resultIfNotFound)
197 {
198  const SpinLock::ScopedLockType sl (currentMappingsLock);
199 
200  if (auto* mappings = LocalisedStrings::getCurrentMappings())
201  return mappings->translate (text, resultIfNotFound);
202 
203  return resultIfNotFound;
204 }
205 
206 } // namespace juce
juce::File::loadFileAsString
String loadFileAsString() const
Reads a file into memory as a string.
Definition: juce_File.cpp:530
juce::LocalisedStrings::addStrings
void addStrings(const LocalisedStrings &)
Adds and merges another set of translations into this set.
Definition: juce_LocalisedStrings.cpp:164
juce::StringPairArray::addArray
void addArray(const StringPairArray &other)
Adds the items from another array to this one.
Definition: juce_StringPairArray.cpp:120
juce::LocalisedStrings::translateWithCurrentMappings
static String translateWithCurrentMappings(const String &text)
Tries to translate a string using the currently selected set of mappings.
Definition: juce_LocalisedStrings.cpp:189
juce::StringPairArray::setIgnoresCase
void setIgnoresCase(bool shouldIgnoreCase)
Indicates whether to use a case-insensitive search when looking up a key string.
Definition: juce_StringPairArray.cpp:143
juce::StringArray::trim
void trim()
Deletes any whitespace characters from the starts and ends of all the strings.
Definition: juce_StringArray.cpp:265
juce::StringArray::removeEmptyStrings
void removeEmptyStrings(bool removeWhitespaceStrings=true)
Removes empty strings from the array.
Definition: juce_StringArray.cpp:249
juce::LocalisedStrings::setCurrentMappings
static void setCurrentMappings(LocalisedStrings *newTranslations)
Selects the current set of mappings to be used by the system.
Definition: juce_LocalisedStrings.cpp:178
juce::LocalisedStrings::LocalisedStrings
LocalisedStrings(const String &fileContents, bool ignoreCaseOfKeys)
Creates a set of translations from the text of a translation file.
Definition: juce_LocalisedStrings.cpp:26
JUCE_API
#define JUCE_API
This macro is added to all JUCE public class declarations.
Definition: juce_StandardHeader.h:143
juce::LocalisedStrings::~LocalisedStrings
~LocalisedStrings()
Destructor.
Definition: juce_LocalisedStrings.cpp:51
juce::File
Represents a local file or directory.
Definition: juce_File.h:44
juce::StringPairArray::containsKey
bool containsKey(StringRef key) const noexcept
Returns true if the given key exists.
Definition: juce_StringPairArray.cpp:100
juce::StringPairArray::set
void set(const String &key, const String &value)
Adds or amends a key/value pair.
Definition: juce_StringPairArray.cpp:105
juce::GenericScopedLock
Automatically locks and unlocks a mutex object.
Definition: juce_ScopedLock.h:58
juce::StringPairArray::minimiseStorageOverheads
void minimiseStorageOverheads()
Reduces the amount of storage being used by the array.
Definition: juce_StringPairArray.cpp:163
juce::SpinLock::ScopedLockType
GenericScopedLock< SpinLock > ScopedLockType
Provides the type of scoped lock to use for locking a SpinLock.
Definition: juce_SpinLock.h:77
juce::StringArray::addTokens
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Breaks up a string into tokens and adds them to this array.
Definition: juce_StringArray.cpp:328
juce::LocalisedStrings::getCurrentMappings
static LocalisedStrings * getCurrentMappings()
Returns the currently selected set of mappings.
Definition: juce_LocalisedStrings.cpp:184
juce::String
The JUCE String class!
Definition: juce_String.h:42
juce::String::substring
String substring(int startIndex, int endIndex) const
Returns a subsection of the string.
Definition: juce_String.cpp:1504
juce::LocalisedStrings::translate
String translate(const String &text) const
Attempts to look up a string and return its localised version.
Definition: juce_LocalisedStrings.cpp:56
juce::LocalisedStrings::setFallback
void setFallback(LocalisedStrings *fallbackStrings)
Gives this object a set of strings to use as a fallback if a string isn't found.
Definition: juce_LocalisedStrings.cpp:172
juce::StringPairArray::getValue
String getValue(StringRef, const String &defaultReturnValue) const
Finds the value corresponding to a key string.
Definition: juce_StringPairArray.cpp:90
juce::String::trim
String trim() const
Returns a copy of this string with any whitespace characters removed from the start and end.
Definition: juce_String.cpp:1662
juce::LocalisedStrings
Used to convert strings to localised foreign-language versions.
Definition: juce_LocalisedStrings.h:75