DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (c969a93b0ca7)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_intl_IntlOSPreferences_h__
#define mozilla_intl_IntlOSPreferences_h__

#include "mozilla/StaticPtr.h"
#include "nsDataHashtable.h"
#include "nsString.h"
#include "nsTArray.h"
#include "unicode/uloc.h"

#include "mozIOSPreferences.h"

namespace mozilla {
namespace intl {

/**
 * OSPreferences API provides a set of methods for retrieving information from
 * the host environment on topics such as:
 *   - Internationalization
 *   - Localization
 *   - Regional preferences
 *
 * The API is meant to remain as simple as possible, relaying information from
 * the host environment to the user without too much logic.
 *
 * Saying that, there are two exceptions to that paradigm.
 *
 * First one is normalization. We do intend to translate host environment
 * concepts to unified Intl/L10n vocabulary used by Mozilla.
 * That means that we will format locale IDs, timezone names, currencies etc.
 * into a chosen format.
 *
 * Second is caching. This API does cache values and where possible will
 * hook into the environment for some event-driven cache invalidation.
 *
 * This means that on platforms that do not support a mechanism to
 * notify apps about changes, new OS-level settings may not be reflected
 * in the app until it is relaunched.
 */
class OSPreferences : public mozIOSPreferences {
 public:
  NS_DECL_ISUPPORTS
  NS_DECL_MOZIOSPREFERENCES

  enum class DateTimeFormatStyle {
    Invalid = -1,
    None,
    Short,   // e.g. time: HH:mm, date: Y/m/d
    Medium,  // likely same as Short
    Long,    // e.g. time: including seconds, date: including weekday
    Full     // e.g. time: with timezone, date: with long weekday, month
  };

  /**
   * Constructor, to do any necessary initialization such as registering for
   * notifications from the system when prefs are modified.
   */
  OSPreferences();

  /**
   * Create (if necessary) and return a raw pointer to the singleton instance.
   * Use this accessor in C++ code that just wants to call a method on the
   * instance, but does not need to hold a reference, as in
   *    nsAutoCString str;
   *    OSPreferences::GetInstance()->GetSystemLocale(str);
   */
  static OSPreferences* GetInstance();

  /**
   * Return an addRef'd pointer to the singleton instance. This is used by the
   * XPCOM constructor that exists to support usage from JS.
   */
  static already_AddRefed<OSPreferences> GetInstanceAddRefed() {
    return RefPtr<OSPreferences>(GetInstance()).forget();
  }

  static bool GetDateTimeConnectorPattern(const nsACString& aLocale,
                                          nsAString& aRetVal);

  /**
   * Triggers a refresh of retrieving data from host environment.
   *
   * If the result differs from the previous list, it will additionally
   * trigger global events for changed values:
   *
   *  * SystemLocales: "intl:system-locales-changed"
   *
   * This method should not be called from anywhere except of per-platform
   * hooks into OS events.
   */
  void Refresh();

 protected:
  nsTArray<nsCString> mSystemLocales;
  nsTArray<nsCString> mRegionalPrefsLocales;

  const size_t kMaxCachedPatterns = 15;
  nsDataHashtable<nsCStringHashKey, nsString> mPatternCache;

 private:
  virtual ~OSPreferences();

  static StaticRefPtr<OSPreferences> sInstance;

  static bool CanonicalizeLanguageTag(nsCString& aLoc);

  /**
   * Helper methods to get formats from ICU; these will return false
   * in case of error, in which case the caller cannot rely on aRetVal.
   */
  bool GetDateTimePatternForStyle(DateTimeFormatStyle aDateStyle,
                                  DateTimeFormatStyle aTimeStyle,
                                  const nsACString& aLocale,
                                  nsAString& aRetVal);

  bool GetDateTimeSkeletonForStyle(DateTimeFormatStyle aDateStyle,
                                   DateTimeFormatStyle aTimeStyle,
                                   const nsACString& aLocale,
                                   nsAString& aRetVal);

  bool GetPatternForSkeleton(const nsAString& aSkeleton,
                             const nsACString& aLocale, nsAString& aRetVal);

  /**
   * This is a host environment specific method that will be implemented
   * separately for each platform.
   *
   * It is only called when the cache is empty or invalidated.
   *
   * The return value indicates whether the function successfully
   * resolved at least one locale.
   */
  bool ReadSystemLocales(nsTArray<nsCString>& aRetVal);

  bool ReadRegionalPrefsLocales(nsTArray<nsCString>& aRetVal);

  /**
   * This is a host environment specific method that will be implemented
   * separately for each platform.
   *
   * It is `best-effort` kind of API that attempts to construct the best
   * possible date/time pattern for the given styles and locales.
   *
   * In case we fail to, or don't know how to retrieve the pattern in a
   * given environment this function will return false.
   * Callers should always be prepared to handle that scenario.
   *
   * The heuristic may depend on the OS API and HIG guidelines.
   */
  bool ReadDateTimePattern(DateTimeFormatStyle aDateFormatStyle,
                           DateTimeFormatStyle aTimeFormatStyle,
                           const nsACString& aLocale, nsAString& aRetVal);
};

}  // namespace intl
}  // namespace mozilla

#endif /* mozilla_intl_IntlOSPreferences_h__ */