localizations.dart 15.2 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

8
import 'debug.dart';
9

10 11 12
// Examples can assume:
// late BuildContext context;

13 14 15 16 17
/// Determines the order of the columns inside [CupertinoDatePicker] in
/// time and date time mode.
enum DatePickerDateTimeOrder {
  /// Order of the columns, from left to right: date, hour, minute, am/pm.
  ///
18
  /// Example: Fri Aug 31 | 02 | 08 | PM.
19 20 21
  date_time_dayPeriod,
  /// Order of the columns, from left to right: date, am/pm, hour, minute.
  ///
22
  /// Example: Fri Aug 31 | PM | 02 | 08.
23 24 25
  date_dayPeriod_time,
  /// Order of the columns, from left to right: hour, minute, am/pm, date.
  ///
26
  /// Example: 02 | 08 | PM | Fri Aug 31.
27 28 29
  time_dayPeriod_date,
  /// Order of the columns, from left to right: am/pm, hour, minute, date.
  ///
30
  /// Example: PM | 02 | 08 | Fri Aug 31.
31 32 33 34 35 36 37
  dayPeriod_time_date,
}

/// Determines the order of the columns inside [CupertinoDatePicker] in date mode.
enum DatePickerDateOrder {
  /// Order of the columns, from left to right: day, month, year.
  ///
38
  /// Example: 12 | March | 1996.
39 40 41
  dmy,
  /// Order of the columns, from left to right: month, day, year.
  ///
42
  /// Example: March | 12 | 1996.
43 44 45
  mdy,
  /// Order of the columns, from left to right: year, month, day.
  ///
46
  /// Example: 1996 | March | 12.
47 48 49
  ymd,
  /// Order of the columns, from left to right: year, day, month.
  ///
50
  /// Example: 1996 | 12 | March.
51 52
  ydm,
}
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

/// Defines the localized resource values used by the Cupertino widgets.
///
/// See also:
///
///  * [DefaultCupertinoLocalizations], the default, English-only, implementation
///    of this interface.
// TODO(xster): Supply non-english strings.
abstract class CupertinoLocalizations {
  /// Year that is shown in [CupertinoDatePicker] spinner corresponding to the
  /// given year index.
  ///
  /// Examples: datePickerYear(1) in:
  ///
  ///  - US English: 2018
  ///  - Korean: 2018년
69
  // The global version uses date symbols data from the intl package.
70 71 72 73 74 75 76 77 78
  String datePickerYear(int yearIndex);

  /// Month that is shown in [CupertinoDatePicker] spinner corresponding to
  /// the given month index.
  ///
  /// Examples: datePickerMonth(1) in:
  ///
  ///  - US English: January
  ///  - Korean: 1월
79
  // The global version uses date symbols data from the intl package.
80 81 82 83 84
  String datePickerMonth(int monthIndex);

  /// Day of month that is shown in [CupertinoDatePicker] spinner corresponding
  /// to the given day index.
  ///
85 86
  /// If weekDay is provided then it will also show weekday name alongside the numerical day.
  ///
87 88 89 90
  /// Examples: datePickerDayOfMonth(1) in:
  ///
  ///  - US English: 1
  ///  - Korean: 1일
91 92 93
  /// Examples: datePickerDayOfMonth(1, 1) in:
  ///
  ///  - US English: Mon 1
94
  // The global version uses date symbols data from the intl package.
95
  String datePickerDayOfMonth(int dayIndex, [int? weekDay]);
96 97 98 99 100 101 102 103

  /// The medium-width date format that is shown in [CupertinoDatePicker]
  /// spinner. Abbreviates month and days of week.
  ///
  /// Examples:
  ///
  /// - US English: Wed Sep 27
  /// - Russian: ср сент. 27
104
  // The global version is based on intl package's DateFormat.MMMEd.
105 106 107 108 109 110 111
  String datePickerMediumDate(DateTime date);

  /// Hour that is shown in [CupertinoDatePicker] spinner corresponding
  /// to the given hour value.
  ///
  /// Examples: datePickerHour(1) in:
  ///
112
  ///  - US English: 1
113
  ///  - Arabic: ٠١
114
  // The global version uses date symbols data from the intl package.
115 116
  String datePickerHour(int hour);

117
  /// Semantics label for the given hour value in [CupertinoDatePicker].
118
  // The global version uses the translated string from the arb file.
119
  String? datePickerHourSemanticsLabel(int hour);
120

121 122 123 124 125 126 127
  /// Minute that is shown in [CupertinoDatePicker] spinner corresponding
  /// to the given minute value.
  ///
  /// Examples: datePickerMinute(1) in:
  ///
  ///  - US English: 01
  ///  - Arabic: ٠١
128
  // The global version uses date symbols data from the intl package.
129 130
  String datePickerMinute(int minute);

131
  /// Semantics label for the given minute value in [CupertinoDatePicker].
132
  // The global version uses the translated string from the arb file.
133
  String? datePickerMinuteSemanticsLabel(int minute);
134

135
  /// The order of the date elements that will be shown in [CupertinoDatePicker].
136
  // The global version uses the translated string from the arb file.
137 138 139
  DatePickerDateOrder get datePickerDateOrder;

  /// The order of the time elements that will be shown in [CupertinoDatePicker].
140
  // The global version uses the translated string from the arb file.
141
  DatePickerDateTimeOrder get datePickerDateTimeOrder;
142 143

  /// The abbreviation for ante meridiem (before noon) shown in the time picker.
144
  // The global version uses the translated string from the arb file.
145 146 147
  String get anteMeridiemAbbreviation;

  /// The abbreviation for post meridiem (after noon) shown in the time picker.
148
  // The global version uses the translated string from the arb file.
149 150
  String get postMeridiemAbbreviation;

151 152 153 154
  /// Label shown in date pickers when the date is today.
  // The global version uses the translated string from the arb file.
  String get todayLabel;

155
  /// The term used by the system to announce dialog alerts.
156
  // The global version uses the translated string from the arb file.
157 158
  String get alertDialogLabel;

159 160 161 162 163 164
  /// The accessibility label used on a tab in a [CupertinoTabBar].
  ///
  /// This message describes the index of the selected tab and how many tabs
  /// there are, e.g. 'tab, 1 of 2' in United States English.
  ///
  /// `tabIndex` and `tabCount` must be greater than or equal to one.
165
  String tabSemanticsLabel({required int tabIndex, required int tabCount});
166

167
  /// Hour that is shown in [CupertinoTimerPicker] corresponding to
168 169 170 171 172 173
  /// the given hour value.
  ///
  /// Examples: timerPickerHour(1) in:
  ///
  ///  - US English: 1
  ///  - Arabic: ١
174
  // The global version uses date symbols data from the intl package.
175 176
  String timerPickerHour(int hour);

177
  /// Minute that is shown in [CupertinoTimerPicker] corresponding to
178 179 180 181 182 183
  /// the given minute value.
  ///
  /// Examples: timerPickerMinute(1) in:
  ///
  ///  - US English: 1
  ///  - Arabic: ١
184
  // The global version uses date symbols data from the intl package.
185 186
  String timerPickerMinute(int minute);

187
  /// Second that is shown in [CupertinoTimerPicker] corresponding to
188 189 190 191 192 193
  /// the given second value.
  ///
  /// Examples: timerPickerSecond(1) in:
  ///
  ///  - US English: 1
  ///  - Arabic: ١
194
  // The global version uses date symbols data from the intl package.
195 196 197
  String timerPickerSecond(int second);

  /// Label that appears next to the hour picker in
198
  /// [CupertinoTimerPicker] when selected hour value is `hour`.
199
  /// This function will deal with pluralization based on the `hour` parameter.
200
  // The global version uses the translated string from the arb file.
201
  String? timerPickerHourLabel(int hour);
202

203 204 205 206
  /// All possible hour labels that appears next to the hour picker in
  /// [CupertinoTimerPicker]
  List<String> get timerPickerHourLabels;

207
  /// Label that appears next to the minute picker in
208
  /// [CupertinoTimerPicker] when selected minute value is `minute`.
209
  /// This function will deal with pluralization based on the `minute` parameter.
210
  // The global version uses the translated string from the arb file.
211
  String? timerPickerMinuteLabel(int minute);
212

213 214 215 216
  /// All possible minute labels that appears next to the minute picker in
  /// [CupertinoTimerPicker]
  List<String> get timerPickerMinuteLabels;

217
  /// Label that appears next to the minute picker in
218
  /// [CupertinoTimerPicker] when selected minute value is `second`.
219
  /// This function will deal with pluralization based on the `second` parameter.
220
  // The global version uses the translated string from the arb file.
221
  String? timerPickerSecondLabel(int second);
222

223 224 225 226
  /// All possible second labels that appears next to the second picker in
  /// [CupertinoTimerPicker]
  List<String> get timerPickerSecondLabels;

227
  /// The term used for cutting.
228
  // The global version uses the translated string from the arb file.
229 230
  String get cutButtonLabel;

231
  /// The term used for copying.
232
  // The global version uses the translated string from the arb file.
233 234
  String get copyButtonLabel;

235
  /// The term used for pasting.
236
  // The global version uses the translated string from the arb file.
237 238
  String get pasteButtonLabel;

239 240 241 242 243
  /// Label that appears in the Cupertino toolbar when the spell checker
  /// couldn't find any replacements for the current word.
  // The global version uses the translated string from the arb file.
  String get noSpellCheckReplacementsLabel;

244
  /// The term used for selecting everything.
245
  // The global version uses the translated string from the arb file.
246 247
  String get selectAllButtonLabel;

248 249 250 251
  /// The term used for looking up a selection.
  // The global version uses the translated string from the arb file.
  String get lookUpButtonLabel;

252 253
  /// The default placeholder used in [CupertinoSearchTextField].
  // The global version uses the translated string from the arb file.
254
  String get searchTextFieldPlaceholderLabel;
255

256 257 258 259 260 261 262
  /// Label read out by accessibility tools (VoiceOver) for a modal
  /// barrier to indicate that a tap dismisses the barrier.
  ///
  /// A modal barrier can for example be found behind an alert or popup to block
  /// user interaction with elements behind it.
  String get modalBarrierDismissLabel;

263 264 265 266
  /// Label read out by accessibility tools (VoiceOver) for a context menu to
  /// indicate that a tap outside dismisses the context menu.
  String get menuDismissLabel;

267 268 269
  /// The `CupertinoLocalizations` from the closest [Localizations] instance
  /// that encloses the given context.
  ///
270 271 272
  /// If no [CupertinoLocalizations] are available in the given `context`, this
  /// method throws an exception.
  ///
273
  /// This method is just a convenient shorthand for:
274
  /// `Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations)!`.
275 276 277 278 279 280 281
  ///
  /// References to the localized resources defined by this class are typically
  /// written in terms of this method. For example:
  ///
  /// ```dart
  /// CupertinoLocalizations.of(context).anteMeridiemAbbreviation;
  /// ```
282
  static CupertinoLocalizations of(BuildContext context) {
283
    assert(debugCheckHasCupertinoLocalizations(context));
284
    return Localizations.of<CupertinoLocalizations>(context, CupertinoLocalizations)!;
285 286 287 288 289 290 291 292 293 294 295 296 297 298
  }
}

class _CupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
  const _CupertinoLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => locale.languageCode == 'en';

  @override
  Future<CupertinoLocalizations> load(Locale locale) => DefaultCupertinoLocalizations.load(locale);

  @override
  bool shouldReload(_CupertinoLocalizationsDelegate old) => false;
299 300 301

  @override
  String toString() => 'DefaultCupertinoLocalizations.delegate(en_US)';
302 303
}

304
/// US English strings for the Cupertino widgets.
305 306 307 308 309 310 311 312
class DefaultCupertinoLocalizations implements CupertinoLocalizations {
  /// Constructs an object that defines the cupertino widgets' localized strings
  /// for US English (only).
  ///
  /// [LocalizationsDelegate] implementations typically call the static [load]
  /// function, rather than constructing this class directly.
  const DefaultCupertinoLocalizations();

313 314
  /// Short version of days of week.
  static const List<String> shortWeekdays = <String>[
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
    'Mon',
    'Tue',
    'Wed',
    'Thu',
    'Fri',
    'Sat',
    'Sun',
  ];

  static const List<String> _shortMonths = <String>[
    'Jan',
    'Feb',
    'Mar',
    'Apr',
    'May',
    'Jun',
    'Jul',
    'Aug',
    'Sep',
    'Oct',
    'Nov',
    'Dec',
  ];

  static const List<String> _months = <String>[
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December',
  ];

354 355


356 357 358 359 360 361 362
  @override
  String datePickerYear(int yearIndex) => yearIndex.toString();

  @override
  String datePickerMonth(int monthIndex) => _months[monthIndex - 1];

  @override
363 364 365 366 367 368 369
  String datePickerDayOfMonth(int dayIndex, [int? weekDay]) {
    if (weekDay != null) {
      return ' ${shortWeekdays[weekDay - DateTime.monday]} $dayIndex ';
    }

    return dayIndex.toString();
  }
370 371

  @override
372
  String datePickerHour(int hour) => hour.toString();
373

374
  @override
375
  String datePickerHourSemanticsLabel(int hour) => "$hour o'clock";
376

377 378 379
  @override
  String datePickerMinute(int minute) => minute.toString().padLeft(2, '0');

380 381
  @override
  String datePickerMinuteSemanticsLabel(int minute) {
382
    if (minute == 1) {
383
      return '1 minute';
384
    }
385
    return '$minute minutes';
386 387
  }

388 389
  @override
  String datePickerMediumDate(DateTime date) {
390
    return '${shortWeekdays[date.weekday - DateTime.monday]} '
391
      '${_shortMonths[date.month - DateTime.january]} '
392
      '${date.day.toString().padRight(2)}';
393 394 395
  }

  @override
396 397 398 399
  DatePickerDateOrder get datePickerDateOrder => DatePickerDateOrder.mdy;

  @override
  DatePickerDateTimeOrder get datePickerDateTimeOrder => DatePickerDateTimeOrder.date_time_dayPeriod;
400 401 402 403 404 405 406

  @override
  String get anteMeridiemAbbreviation => 'AM';

  @override
  String get postMeridiemAbbreviation => 'PM';

407 408 409
  @override
  String get todayLabel => 'Today';

410 411 412
  @override
  String get alertDialogLabel => 'Alert';

413
  @override
414
  String tabSemanticsLabel({required int tabIndex, required int tabCount}) {
415 416
    assert(tabIndex >= 1);
    assert(tabCount >= 1);
417
    return 'Tab $tabIndex of $tabCount';
418 419
  }

420 421 422 423 424 425 426 427 428 429 430 431
  @override
  String timerPickerHour(int hour) => hour.toString();

  @override
  String timerPickerMinute(int minute) => minute.toString();

  @override
  String timerPickerSecond(int second) => second.toString();

  @override
  String timerPickerHourLabel(int hour) => hour == 1 ? 'hour' : 'hours';

432 433 434
  @override
  List<String> get timerPickerHourLabels => const <String>['hour', 'hours'];

435
  @override
436
  String timerPickerMinuteLabel(int minute) => 'min.';
437

438 439 440
  @override
  List<String> get timerPickerMinuteLabels => const <String>['min.'];

441
  @override
442
  String timerPickerSecondLabel(int second) => 'sec.';
443

444 445 446
  @override
  List<String> get timerPickerSecondLabels => const <String>['sec.'];

447 448 449 450 451 452 453 454 455
  @override
  String get cutButtonLabel => 'Cut';

  @override
  String get copyButtonLabel => 'Copy';

  @override
  String get pasteButtonLabel => 'Paste';

456 457 458
  @override
  String get noSpellCheckReplacementsLabel => 'No Replacements Found';

459 460 461
  @override
  String get selectAllButtonLabel => 'Select All';

462 463 464
  @override
  String get lookUpButtonLabel => 'Look Up';

465
  @override
466
  String get searchTextFieldPlaceholderLabel => 'Search';
467

468 469 470
  @override
  String get modalBarrierDismissLabel => 'Dismiss';

471 472 473
  @override
  String get menuDismissLabel => 'Dismiss menu';

474 475 476 477 478 479 480
  /// Creates an object that provides US English resource values for the
  /// cupertino library widgets.
  ///
  /// The [locale] parameter is ignored.
  ///
  /// This method is typically used to create a [LocalizationsDelegate].
  static Future<CupertinoLocalizations> load(Locale locale) {
481
    return SynchronousFuture<CupertinoLocalizations>(const DefaultCupertinoLocalizations());
482 483 484 485 486 487
  }

  /// A [LocalizationsDelegate] that uses [DefaultCupertinoLocalizations.load]
  /// to create an instance of this class.
  static const LocalizationsDelegate<CupertinoLocalizations> delegate = _CupertinoLocalizationsDelegate();
}