Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: ui/base/l10n/formatter.cc

Issue 1140153005: ICU msg format support with more than one arguments (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Mark's review comments Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/base/BUILD.gn ('k') | ui/base/l10n/l10n_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/l10n/formatter.h" 5 #include "ui/base/l10n/formatter.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
10 #include "third_party/icu/source/common/unicode/unistr.h" 11 #include "third_party/icu/source/common/unicode/unistr.h"
11 #include "third_party/icu/source/i18n/unicode/msgfmt.h" 12 #include "third_party/icu/source/i18n/unicode/msgfmt.h"
12 #include "ui/base/l10n/l10n_util.h" 13 #include "ui/base/l10n/l10n_util.h"
13 #include "ui/base/l10n/l10n_util_plurals.h"
14 #include "ui/strings/grit/ui_strings.h" 14 #include "ui/strings/grit/ui_strings.h"
15 15
16 namespace ui { 16 namespace ui {
17 17
18 UI_BASE_EXPORT bool formatter_force_fallback = false; 18 UI_BASE_EXPORT bool formatter_force_fallback = false;
19 19
20 struct Pluralities { 20 struct Pluralities {
21 int id; 21 int id;
22 const char* const fallback_one; 22 const char* const fallback_one;
23 const char* const fallback_other; 23 const char* const fallback_other;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 IDS_TIME_DAYS_1ST, 132 IDS_TIME_DAYS_1ST,
133 "one{# day and }", 133 "one{# day and }",
134 " other{# days and }" 134 " other{# days and }"
135 }; 135 };
136 static const Pluralities IDS_DURATION_HOUR_2ND = { 136 static const Pluralities IDS_DURATION_HOUR_2ND = {
137 IDS_TIME_HOURS_2ND, 137 IDS_TIME_HOURS_2ND,
138 "one{# hour}", 138 "one{# hour}",
139 " other{# hours}" 139 " other{# hours}"
140 }; 140 };
141 141
142 namespace {
143
144 scoped_ptr<icu::PluralRules> BuildPluralRules() {
145 UErrorCode err = U_ZERO_ERROR;
146 scoped_ptr<icu::PluralRules> rules(
147 icu::PluralRules::forLocale(icu::Locale::getDefault(), err));
148 if (U_FAILURE(err)) {
149 err = U_ZERO_ERROR;
150 icu::UnicodeString fallback_rules("one: n is 1", -1, US_INV);
151 rules.reset(icu::PluralRules::createRules(fallback_rules, err));
152 DCHECK(U_SUCCESS(err));
153 }
154 return rules.Pass();
155 }
156
157 void FormatNumberInPlural(const icu::MessageFormat& format, int number,
158 icu::UnicodeString* result, UErrorCode* err) {
159 if (U_FAILURE(*err)) return;
160 icu::Formattable formattable(number);
161 icu::FieldPosition ignore(icu::FieldPosition::DONT_CARE);
162 format.format(&formattable, 1, *result, ignore, *err);
163 DCHECK(U_SUCCESS(*err));
164 return;
165 }
166
167 } // namespace
168
142 Formatter::Formatter(const Pluralities& sec_pluralities, 169 Formatter::Formatter(const Pluralities& sec_pluralities,
143 const Pluralities& min_pluralities, 170 const Pluralities& min_pluralities,
144 const Pluralities& hour_pluralities, 171 const Pluralities& hour_pluralities,
145 const Pluralities& day_pluralities) { 172 const Pluralities& day_pluralities) {
146 simple_format_[UNIT_SEC] = InitFormat(sec_pluralities); 173 simple_format_[UNIT_SEC] = InitFormat(sec_pluralities);
147 simple_format_[UNIT_MIN] = InitFormat(min_pluralities); 174 simple_format_[UNIT_MIN] = InitFormat(min_pluralities);
148 simple_format_[UNIT_HOUR] = InitFormat(hour_pluralities); 175 simple_format_[UNIT_HOUR] = InitFormat(hour_pluralities);
149 simple_format_[UNIT_DAY] = InitFormat(day_pluralities); 176 simple_format_[UNIT_DAY] = InitFormat(day_pluralities);
150 } 177 }
151 178
(...skipping 18 matching lines...) Expand all
170 detailed_format_[TWO_UNITS_DAY_HOUR][0] = InitFormat(day_hour_pluralities1); 197 detailed_format_[TWO_UNITS_DAY_HOUR][0] = InitFormat(day_hour_pluralities1);
171 detailed_format_[TWO_UNITS_DAY_HOUR][1] = InitFormat(day_hour_pluralities2); 198 detailed_format_[TWO_UNITS_DAY_HOUR][1] = InitFormat(day_hour_pluralities2);
172 } 199 }
173 200
174 void Formatter::Format(Unit unit, 201 void Formatter::Format(Unit unit,
175 int value, 202 int value,
176 icu::UnicodeString* formatted_string) const { 203 icu::UnicodeString* formatted_string) const {
177 DCHECK(simple_format_[unit]); 204 DCHECK(simple_format_[unit]);
178 DCHECK(formatted_string->isEmpty() == TRUE); 205 DCHECK(formatted_string->isEmpty() == TRUE);
179 UErrorCode error = U_ZERO_ERROR; 206 UErrorCode error = U_ZERO_ERROR;
180 l10n_util::FormatNumberInPlural(*simple_format_[unit], 207 FormatNumberInPlural(*simple_format_[unit],
181 value, formatted_string, &error); 208 value, formatted_string, &error);
182 DCHECK(U_SUCCESS(error)) << "Error in icu::PluralFormat::format()."; 209 DCHECK(U_SUCCESS(error)) << "Error in icu::PluralFormat::format().";
183 return; 210 return;
184 } 211 }
185 212
186 void Formatter::Format(TwoUnits units, 213 void Formatter::Format(TwoUnits units,
187 int value_1, 214 int value_1,
188 int value_2, 215 int value_2,
189 icu::UnicodeString* formatted_string) const { 216 icu::UnicodeString* formatted_string) const {
190 DCHECK(detailed_format_[units][0]) 217 DCHECK(detailed_format_[units][0])
191 << "Detailed() not implemented for your (format, length) combination!"; 218 << "Detailed() not implemented for your (format, length) combination!";
192 DCHECK(detailed_format_[units][1]) 219 DCHECK(detailed_format_[units][1])
193 << "Detailed() not implemented for your (format, length) combination!"; 220 << "Detailed() not implemented for your (format, length) combination!";
194 DCHECK(formatted_string->isEmpty() == TRUE); 221 DCHECK(formatted_string->isEmpty() == TRUE);
195 UErrorCode error = U_ZERO_ERROR; 222 UErrorCode error = U_ZERO_ERROR;
196 l10n_util::FormatNumberInPlural(*detailed_format_[units][0], value_1, 223 FormatNumberInPlural(*detailed_format_[units][0], value_1,
197 formatted_string, &error); 224 formatted_string, &error);
198 DCHECK(U_SUCCESS(error)); 225 DCHECK(U_SUCCESS(error));
199 l10n_util::FormatNumberInPlural(*detailed_format_[units][1], value_2, 226 FormatNumberInPlural(*detailed_format_[units][1], value_2,
200 formatted_string, &error); 227 formatted_string, &error);
201 DCHECK(U_SUCCESS(error)); 228 DCHECK(U_SUCCESS(error));
202 return; 229 return;
203 } 230 }
204 231
205 scoped_ptr<icu::MessageFormat> Formatter::CreateFallbackFormat( 232 scoped_ptr<icu::MessageFormat> Formatter::CreateFallbackFormat(
206 const icu::PluralRules& rules, 233 const icu::PluralRules& rules,
207 const Pluralities& pluralities) const { 234 const Pluralities& pluralities) const {
208 icu::UnicodeString pattern("{NUMBER, plural, "); 235 icu::UnicodeString pattern("{NUMBER, plural, ");
209 if (rules.isKeyword(UNICODE_STRING_SIMPLE("one"))) 236 if (rules.isKeyword(UNICODE_STRING_SIMPLE("one")))
210 pattern += icu::UnicodeString(pluralities.fallback_one); 237 pattern += icu::UnicodeString(pluralities.fallback_one);
(...skipping 12 matching lines...) Expand all
223 if (!formatter_force_fallback) { 250 if (!formatter_force_fallback) {
224 base::string16 pattern = l10n_util::GetStringUTF16(pluralities.id); 251 base::string16 pattern = l10n_util::GetStringUTF16(pluralities.id);
225 UErrorCode error = U_ZERO_ERROR; 252 UErrorCode error = U_ZERO_ERROR;
226 scoped_ptr<icu::MessageFormat> format(new icu::MessageFormat( 253 scoped_ptr<icu::MessageFormat> format(new icu::MessageFormat(
227 icu::UnicodeString(FALSE, pattern.data(), pattern.length()), error)); 254 icu::UnicodeString(FALSE, pattern.data(), pattern.length()), error));
228 DCHECK(U_SUCCESS(error)); 255 DCHECK(U_SUCCESS(error));
229 if (format.get()) 256 if (format.get())
230 return format.Pass(); 257 return format.Pass();
231 } 258 }
232 259
233 scoped_ptr<icu::PluralRules> rules(l10n_util::BuildPluralRules()); 260 scoped_ptr<icu::PluralRules> rules(BuildPluralRules());
234 return CreateFallbackFormat(*rules, pluralities); 261 return CreateFallbackFormat(*rules, pluralities);
235 } 262 }
236 263
237 const Formatter* FormatterContainer::Get(TimeFormat::Format format, 264 const Formatter* FormatterContainer::Get(TimeFormat::Format format,
238 TimeFormat::Length length) const { 265 TimeFormat::Length length) const {
239 DCHECK(formatter_[format][length]) 266 DCHECK(formatter_[format][length])
240 << "Combination of FORMAT_ELAPSED and LENGTH_LONG is not implemented!"; 267 << "Combination of FORMAT_ELAPSED and LENGTH_LONG is not implemented!";
241 return formatter_[format][length].get(); 268 return formatter_[format][length].get();
242 } 269 }
243 270
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 312
286 void FormatterContainer::Shutdown() { 313 void FormatterContainer::Shutdown() {
287 for (int format = 0; format < TimeFormat::FORMAT_COUNT; ++format) { 314 for (int format = 0; format < TimeFormat::FORMAT_COUNT; ++format) {
288 for (int length = 0; length < TimeFormat::LENGTH_COUNT; ++length) { 315 for (int length = 0; length < TimeFormat::LENGTH_COUNT; ++length) {
289 formatter_[format][length].reset(); 316 formatter_[format][length].reset();
290 } 317 }
291 } 318 }
292 } 319 }
293 320
294 } // namespace ui 321 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/BUILD.gn ('k') | ui/base/l10n/l10n_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698