OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/common/time_format.h" | 5 #include "chrome/common/time_format.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 enum FormatType { | 106 enum FormatType { |
107 FORMAT_SHORT, | 107 FORMAT_SHORT, |
108 FORMAT_REMAINING, | 108 FORMAT_REMAINING, |
109 FORMAT_ELAPSED, | 109 FORMAT_ELAPSED, |
110 }; | 110 }; |
111 | 111 |
112 } // namespace | 112 } // namespace |
113 | 113 |
114 class TimeFormatter { | 114 class TimeFormatter { |
115 public: | 115 public: |
116 const std::vector<PluralFormat*>& formatter(FormatType format_type) { | 116 const std::vector<icu::PluralFormat*>& formatter(FormatType format_type) { |
117 switch (format_type) { | 117 switch (format_type) { |
118 case FORMAT_SHORT: | 118 case FORMAT_SHORT: |
119 return short_formatter_; | 119 return short_formatter_; |
120 case FORMAT_REMAINING: | 120 case FORMAT_REMAINING: |
121 return time_left_formatter_; | 121 return time_left_formatter_; |
122 case FORMAT_ELAPSED: | 122 case FORMAT_ELAPSED: |
123 return time_elapsed_formatter_; | 123 return time_elapsed_formatter_; |
124 default: | 124 default: |
125 NOTREACHED(); | 125 NOTREACHED(); |
126 return short_formatter_; | 126 return short_formatter_; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 STLDeleteContainerPointers(short_formatter_.begin(), | 164 STLDeleteContainerPointers(short_formatter_.begin(), |
165 short_formatter_.end()); | 165 short_formatter_.end()); |
166 STLDeleteContainerPointers(time_left_formatter_.begin(), | 166 STLDeleteContainerPointers(time_left_formatter_.begin(), |
167 time_left_formatter_.end()); | 167 time_left_formatter_.end()); |
168 STLDeleteContainerPointers(time_elapsed_formatter_.begin(), | 168 STLDeleteContainerPointers(time_elapsed_formatter_.begin(), |
169 time_elapsed_formatter_.end()); | 169 time_elapsed_formatter_.end()); |
170 } | 170 } |
171 friend class Singleton<TimeFormatter>; | 171 friend class Singleton<TimeFormatter>; |
172 friend struct DefaultSingletonTraits<TimeFormatter>; | 172 friend struct DefaultSingletonTraits<TimeFormatter>; |
173 | 173 |
174 std::vector<PluralFormat*> short_formatter_; | 174 std::vector<icu::PluralFormat*> short_formatter_; |
175 std::vector<PluralFormat*> time_left_formatter_; | 175 std::vector<icu::PluralFormat*> time_left_formatter_; |
176 std::vector<PluralFormat*> time_elapsed_formatter_; | 176 std::vector<icu::PluralFormat*> time_elapsed_formatter_; |
177 static void BuildFormats(FormatType format_type, | 177 static void BuildFormats(FormatType format_type, |
178 std::vector<PluralFormat*>* time_formats); | 178 std::vector<icu::PluralFormat*>* time_formats); |
179 static PluralFormat* createFallbackFormat(const PluralRules& rules, | 179 static icu::PluralFormat* createFallbackFormat( |
180 int index, | 180 const icu::PluralRules& rules, int index, FormatType format_type); |
181 FormatType format_type); | |
182 | 181 |
183 DISALLOW_EVIL_CONSTRUCTORS(TimeFormatter); | 182 DISALLOW_EVIL_CONSTRUCTORS(TimeFormatter); |
184 }; | 183 }; |
185 | 184 |
186 void TimeFormatter::BuildFormats(FormatType format_type, | 185 void TimeFormatter::BuildFormats( |
187 std::vector<PluralFormat*>* time_formats) { | 186 FormatType format_type, std::vector<icu::PluralFormat*>* time_formats) { |
188 const static UnicodeString kKeywords[] = { | 187 static const icu::UnicodeString kKeywords[] = { |
189 UNICODE_STRING_SIMPLE("other"), UNICODE_STRING_SIMPLE("one"), | 188 UNICODE_STRING_SIMPLE("other"), UNICODE_STRING_SIMPLE("one"), |
190 UNICODE_STRING_SIMPLE("zero"), UNICODE_STRING_SIMPLE("two"), | 189 UNICODE_STRING_SIMPLE("zero"), UNICODE_STRING_SIMPLE("two"), |
191 UNICODE_STRING_SIMPLE("few"), UNICODE_STRING_SIMPLE("many") | 190 UNICODE_STRING_SIMPLE("few"), UNICODE_STRING_SIMPLE("many") |
192 }; | 191 }; |
193 UErrorCode err = U_ZERO_ERROR; | 192 UErrorCode err = U_ZERO_ERROR; |
194 scoped_ptr<PluralRules> rules( | 193 scoped_ptr<icu::PluralRules> rules( |
195 PluralRules::forLocale(Locale::getDefault(), err)); | 194 icu::PluralRules::forLocale(icu::Locale::getDefault(), err)); |
196 if (U_FAILURE(err)) { | 195 if (U_FAILURE(err)) { |
197 err = U_ZERO_ERROR; | 196 err = U_ZERO_ERROR; |
198 UnicodeString fallback_rules("one: n is 1", -1, US_INV); | 197 icu::UnicodeString fallback_rules("one: n is 1", -1, US_INV); |
199 rules.reset(PluralRules::createRules(fallback_rules, err)); | 198 rules.reset(icu::PluralRules::createRules(fallback_rules, err)); |
200 DCHECK(U_SUCCESS(err)); | 199 DCHECK(U_SUCCESS(err)); |
201 } | 200 } |
202 | 201 |
203 const MessageIDs& message_ids = GetMessageIDs(format_type); | 202 const MessageIDs& message_ids = GetMessageIDs(format_type); |
204 | 203 |
205 for (int i = 0; i < 4; ++i) { | 204 for (int i = 0; i < 4; ++i) { |
206 UnicodeString pattern; | 205 icu::UnicodeString pattern; |
207 for (size_t j = 0; j < arraysize(kKeywords); ++j) { | 206 for (size_t j = 0; j < arraysize(kKeywords); ++j) { |
208 int msg_id = message_ids.ids[i][j]; | 207 int msg_id = message_ids.ids[i][j]; |
209 std::string sub_pattern = WideToUTF8(l10n_util::GetString(msg_id)); | 208 std::string sub_pattern = WideToUTF8(l10n_util::GetString(msg_id)); |
210 // NA means this keyword is not used in the current locale. | 209 // NA means this keyword is not used in the current locale. |
211 // Even if a translator translated for this keyword, we do not | 210 // Even if a translator translated for this keyword, we do not |
212 // use it unless it's 'other' (j=0) or it's defined in the rules | 211 // use it unless it's 'other' (j=0) or it's defined in the rules |
213 // for the current locale. Special-casing of 'other' will be removed | 212 // for the current locale. Special-casing of 'other' will be removed |
214 // once ICU's isKeyword is fixed to return true for isKeyword('other'). | 213 // once ICU's isKeyword is fixed to return true for isKeyword('other'). |
215 if (sub_pattern.compare("NA") != 0 && | 214 if (sub_pattern.compare("NA") != 0 && |
216 (j == 0 || rules->isKeyword(kKeywords[j]))) { | 215 (j == 0 || rules->isKeyword(kKeywords[j]))) { |
217 pattern += kKeywords[j]; | 216 pattern += kKeywords[j]; |
218 pattern += UNICODE_STRING_SIMPLE("{"); | 217 pattern += UNICODE_STRING_SIMPLE("{"); |
219 pattern += UnicodeString(sub_pattern.c_str(), "UTF-8"); | 218 pattern += icu::UnicodeString(sub_pattern.c_str(), "UTF-8"); |
220 pattern += UNICODE_STRING_SIMPLE("}"); | 219 pattern += UNICODE_STRING_SIMPLE("}"); |
221 } | 220 } |
222 } | 221 } |
223 PluralFormat* format = new PluralFormat(*rules, pattern, err); | 222 icu::PluralFormat* format = new icu::PluralFormat(*rules, pattern, err); |
224 if (U_SUCCESS(err)) { | 223 if (U_SUCCESS(err)) { |
225 time_formats->push_back(format); | 224 time_formats->push_back(format); |
226 } else { | 225 } else { |
227 delete format; | 226 delete format; |
228 time_formats->push_back(createFallbackFormat(*rules, i, format_type)); | 227 time_formats->push_back(createFallbackFormat(*rules, i, format_type)); |
229 // Reset it so that next ICU call can proceed. | 228 // Reset it so that next ICU call can proceed. |
230 err = U_ZERO_ERROR; | 229 err = U_ZERO_ERROR; |
231 } | 230 } |
232 } | 231 } |
233 } | 232 } |
234 | 233 |
235 // Create a hard-coded fallback plural format. This will never be called | 234 // Create a hard-coded fallback plural format. This will never be called |
236 // unless translators make a mistake. | 235 // unless translators make a mistake. |
237 PluralFormat* TimeFormatter::createFallbackFormat(const PluralRules& rules, | 236 icu::PluralFormat* TimeFormatter::createFallbackFormat( |
238 int index, | 237 const icu::PluralRules& rules, int index, FormatType format_type) { |
239 FormatType format_type) { | 238 static const icu::UnicodeString kUnits[4][2] = { |
240 const static UnicodeString kUnits[4][2] = { | |
241 { UNICODE_STRING_SIMPLE("sec"), UNICODE_STRING_SIMPLE("secs") }, | 239 { UNICODE_STRING_SIMPLE("sec"), UNICODE_STRING_SIMPLE("secs") }, |
242 { UNICODE_STRING_SIMPLE("min"), UNICODE_STRING_SIMPLE("mins") }, | 240 { UNICODE_STRING_SIMPLE("min"), UNICODE_STRING_SIMPLE("mins") }, |
243 { UNICODE_STRING_SIMPLE("hour"), UNICODE_STRING_SIMPLE("hours") }, | 241 { UNICODE_STRING_SIMPLE("hour"), UNICODE_STRING_SIMPLE("hours") }, |
244 { UNICODE_STRING_SIMPLE("day"), UNICODE_STRING_SIMPLE("days") } | 242 { UNICODE_STRING_SIMPLE("day"), UNICODE_STRING_SIMPLE("days") } |
245 }; | 243 }; |
246 UnicodeString suffix(GetFallbackFormatSuffix(format_type), -1, US_INV); | 244 icu::UnicodeString suffix(GetFallbackFormatSuffix(format_type), -1, US_INV); |
247 UnicodeString pattern; | 245 icu::UnicodeString pattern; |
248 if (rules.isKeyword(UNICODE_STRING_SIMPLE("one"))) { | 246 if (rules.isKeyword(UNICODE_STRING_SIMPLE("one"))) { |
249 pattern += UNICODE_STRING_SIMPLE("one{# ") + kUnits[index][0] + suffix; | 247 pattern += UNICODE_STRING_SIMPLE("one{# ") + kUnits[index][0] + suffix; |
250 } | 248 } |
251 pattern += UNICODE_STRING_SIMPLE(" other{# ") + kUnits[index][1] + suffix; | 249 pattern += UNICODE_STRING_SIMPLE(" other{# ") + kUnits[index][1] + suffix; |
252 UErrorCode err = U_ZERO_ERROR; | 250 UErrorCode err = U_ZERO_ERROR; |
253 PluralFormat* format = new PluralFormat(rules, pattern, err); | 251 icu::PluralFormat* format = new icu::PluralFormat(rules, pattern, err); |
254 DCHECK(U_SUCCESS(err)); | 252 DCHECK(U_SUCCESS(err)); |
255 return format; | 253 return format; |
256 } | 254 } |
257 | 255 |
258 Singleton<TimeFormatter> time_formatter; | 256 Singleton<TimeFormatter> time_formatter; |
259 | 257 |
260 static std::wstring FormatTimeImpl(const TimeDelta& delta, | 258 static std::wstring FormatTimeImpl(const TimeDelta& delta, |
261 FormatType format_type) { | 259 FormatType format_type) { |
262 if (delta.ToInternalValue() < 0) { | 260 if (delta.ToInternalValue() < 0) { |
263 NOTREACHED() << "Negative duration"; | 261 NOTREACHED() << "Negative duration"; |
264 return std::wstring(); | 262 return std::wstring(); |
265 } | 263 } |
266 | 264 |
267 int number; | 265 int number; |
268 | 266 |
269 const std::vector<PluralFormat*>& formatters = | 267 const std::vector<icu::PluralFormat*>& formatters = |
270 time_formatter->formatter(format_type); | 268 time_formatter->formatter(format_type); |
271 | 269 |
272 UErrorCode error = U_ZERO_ERROR; | 270 UErrorCode error = U_ZERO_ERROR; |
273 UnicodeString time_string; | 271 icu::UnicodeString time_string; |
274 // Less than a minute gets "X seconds left" | 272 // Less than a minute gets "X seconds left" |
275 if (delta.ToInternalValue() < Time::kMicrosecondsPerMinute) { | 273 if (delta.ToInternalValue() < Time::kMicrosecondsPerMinute) { |
276 number = static_cast<int>(delta.ToInternalValue() / | 274 number = static_cast<int>(delta.ToInternalValue() / |
277 Time::kMicrosecondsPerSecond); | 275 Time::kMicrosecondsPerSecond); |
278 time_string = formatters[0]->format(number, error); | 276 time_string = formatters[0]->format(number, error); |
279 | 277 |
280 // Less than 1 hour gets "X minutes left". | 278 // Less than 1 hour gets "X minutes left". |
281 } else if (delta.ToInternalValue() < Time::kMicrosecondsPerHour) { | 279 } else if (delta.ToInternalValue() < Time::kMicrosecondsPerHour) { |
282 number = static_cast<int>(delta.ToInternalValue() / | 280 number = static_cast<int>(delta.ToInternalValue() / |
283 Time::kMicrosecondsPerMinute); | 281 Time::kMicrosecondsPerMinute); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 | 329 |
332 // Filter out "today" and "yesterday" | 330 // Filter out "today" and "yesterday" |
333 if (time >= midnight_today) | 331 if (time >= midnight_today) |
334 return l10n_util::GetString(IDS_PAST_TIME_TODAY); | 332 return l10n_util::GetString(IDS_PAST_TIME_TODAY); |
335 else if (time >= midnight_today - | 333 else if (time >= midnight_today - |
336 TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay)) | 334 TimeDelta::FromMicroseconds(Time::kMicrosecondsPerDay)) |
337 return l10n_util::GetString(IDS_PAST_TIME_YESTERDAY); | 335 return l10n_util::GetString(IDS_PAST_TIME_YESTERDAY); |
338 | 336 |
339 return std::wstring(); | 337 return std::wstring(); |
340 } | 338 } |
OLD | NEW |