Example #1
0
    def _setLocale(self, primaryLocale, ignoreError=False):
        if wxIsAvailable():
            # Strip the country code for wxLocales
            # since any invalid values raise an
            # uncapturable error in the wx Widgets layer.
            # With the exception of Chinese, all
            # wx localizations use the lang
            # code exclusively.
            # XXX [grant] Also, pt_BR is common. This just seems
            # bogus.
            try:
                setWxLocale(stripCountryCode(primaryLocale), self)
            except I18nException:
                if not ignoreError:
                    raise

        setPyICULocale(primaryLocale)
        setEnvironmentLocale(primaryLocale)

        from application import Utility

        if Utility.getPlatformID() == "osx-ppc" and \
           Utility.getOSName() in ('10.3-Panther', '10.4-Tiger'):
            # On OS X PPC the LC_NUMERIC values will
            # localize unless the Python locale is
            # set to 'C'. Localized numeric values ie.
            # 1234,23 for a float in the 'FR' locale
            # create data exchange issues and needs to
            # be avoided at all costs.
            setPythonLocale('C')
        else:
            setPythonLocale(primaryLocale)
Example #2
0
    def _setLocale(self, primaryLocale, ignoreError=False):
        if wxIsAvailable():
            # Strip the country code for wxLocales
            # since any invalid values raise an
            # uncapturable error in the wx Widgets layer.
            # With the exception of Chinese, all
            # wx localizations use the lang
            # code exclusively.
            # XXX [grant] Also, pt_BR is common. This just seems
            # bogus.
            try:
                setWxLocale(stripCountryCode(primaryLocale), self)
            except I18nException:
                if not ignoreError:
                    raise

        setPyICULocale(primaryLocale)
        setEnvironmentLocale(primaryLocale)

        from application import Utility

        if Utility.getPlatformID() == "osx-ppc" and \
           Utility.getOSName() in ('10.3-Panther', '10.4-Tiger'):
            # On OS X PPC the LC_NUMERIC values will
            # localize unless the Python locale is
            # set to 'C'. Localized numeric values ie.
            # 1234,23 for a float in the 'FR' locale
            # create data exchange issues and needs to
            # be avoided at all costs.
            setPythonLocale('C')
        else:
            setPythonLocale(primaryLocale)
Example #3
0
    def setWxLocale(locale, i18nMan):
        """
          Sets the c{wx.Locale} to the value passed in
          c{str} locale argument.

          If the locale passed is not a valid wx locale and
          and that locale consists of a lang and country code,
          the country code is stripped and the lang code
          is set as the c{wx.Locale}.

          This logic is employed in the cases such as "es_UY"
          where wxPython does not have a translation for
          'es_UY' but does have one for 'es'.

          If the locale is still not valid after attempting to
          use just the lang code a c{I18nException} is raised.

          @param locale: a c{str} locale
          @type locale: ASCII c{str}
        """

        # Need to unload wx.Locale object otherwise it will
        # hold a dangling reference and not use the new Locale
        global _WX_LOCALE
        _WX_LOCALE = None

        # findWxLocale can return None when the locale
        # is not supported on the host OS
        lc = findWxLocale(locale, i18nMan)

        if lc is not None and not lc.IsOk() and hasCountryCode(locale):
            # Need to unload wx.Locale object otherwise it will
            # hold a dangling reference and not use the
            # Stripped Locale

            lc = None

            # Strip the country code and just use the language
            # For example wx does not have a translation for
            # 'es_UY' but does have one for 'es'

            lc = findWxLocale(stripCountryCode(locale), i18nMan)

        if lc is None or not lc.IsOk():
            raise I18nException, "Invalid wxPython Locale: '%s'" % locale

        # Keep a Global reference to the Wx Locale
        # To ensure it does not get unloaded during the
        # application life cycle. There can be only one
        # wx locale per Python instance
        _WX_LOCALE = lc
Example #4
0
    def setWxLocale(locale, i18nMan):
        """
          Sets the c{wx.Locale} to the value passed in
          c{str} locale argument.

          If the locale passed is not a valid wx locale and
          and that locale consists of a lang and country code,
          the country code is stripped and the lang code
          is set as the c{wx.Locale}.

          This logic is employed in the cases such as "es_UY"
          where wxPython does not have a translation for
          'es_UY' but does have one for 'es'.

          If the locale is still not valid after attempting to
          use just the lang code a c{I18nException} is raised.

          @param locale: a c{str} locale
          @type locale: ASCII c{str}
        """

        # Need to unload wx.Locale object otherwise it will
        # hold a dangling reference and not use the new Locale
        global _WX_LOCALE
        _WX_LOCALE = None

        # findWxLocale can return None when the locale
        # is not supported on the host OS
        lc = findWxLocale(locale, i18nMan)

        if lc is not None and not lc.IsOk() and hasCountryCode(locale):
            # Need to unload wx.Locale object otherwise it will
            # hold a dangling reference and not use the
            # Stripped Locale

            lc = None

            # Strip the country code and just use the language
            # For example wx does not have a translation for
            # 'es_UY' but does have one for 'es'

            lc = findWxLocale(stripCountryCode(locale), i18nMan)

        if lc is None or not lc.IsOk():
            raise I18nException, "Invalid wxPython Locale: '%s'" % locale

        # Keep a Global reference to the Wx Locale
        # To ensure it does not get unloaded during the
        # application life cycle. There can be only one
        # wx locale per Python instance
        _WX_LOCALE = lc
Example #5
0
    def setLocaleSet(self, localeSet=None, fallback=True):
        """
        Resets the c{I18nManager locale set c{List}.

        Resetting the locale set includes unloading all gettext
        .mo translations, loading the the gettext .mo translations
        for the current locale set, and setting the gettext locale
        fallback order if the fallback parameter is set to True.

        Note the initial locale set for the c{I18nManager}
        must be set in the C{I18nManager.initialize}
        method.

        Note, setting the c{I18nManager} locale set
        also adds the language code as a fallback for language /
        county code locale definitions when fallback is set to True.
        If the locale set contains 'fr_CA' this method will also add
        to the locale set 'fr' as a fallback for 'fr_CA'.

        If no localeSet is passed the discoverLocaleSet
        method will be called to retrieve the
        locale set of the Operating System.

        A locale of 'test' can be passed to this method.

        In testing mode all values returned by
        the c{I18nManager.getText} and c{i18nManager.wxTranslate}
        methods insert a (\u00FC): at the start of the string.

        This method sets the following:
           1. The PyICU Locale
           2. The wxPython Locale
           3. The Python Locale
           4. The Operating System Enviroment Locale

        The setLocaleSet method can raise the following exceptions:
            1. c{UnicodeEncodeError}
            2. c{NameError}
            3. c{I18nException}

        @param localeSet: A c{unicode} or c{str}  or c{List}
                          containing locale country and language
                          codes. The value(s) must be able to
                          be converted to ASCII. If None
                          is passed the setLocaleSet method
                          will call the discoverLocaleSet
                          method to retrieve the Operating
                          System locale set.

        @type localeSet: None or ASCII c{str} or c{unicode} or
                         c{List} containing ASCII
                         c{str} or c{unicode} values

         @param fallback: Indicates whether locale set fallback should
                          take place. If set to True, the
                          c{I18nManager} will search all locales
                          in the locale set till a resource or
                          gettext mo translation file is found. If
                          set to False the c{I18nManager} will
                          only try to locate a resource or
                          gettext mo translation file for the
                          current locale which is the first locale
                          in the locale set.


          @type fallback: c{boolean}
        """
        self._testing = False

        discover = localeSet is None

        if discover:
            try:
                localeSet = self.discoverLocaleSet()
            except:
                # Just in case an error is raised in the
                # discovering of the localeSet, capture
                # it here and keep the localeSet variable
                # as None. This will result in the
                # locale being set to "en_US" later in the
                # code. In the discovery case Chandler
                # should do everything possible to
                # still load the application even
                # if an error was raised.
                pass
        else:
            assert (type(localeSet) == ListType
                    or type(localeSet) == UnicodeType
                    or type(localeSet) == StringType)

            if 'test' in localeSet:
                localeSet = ['en_US']
                self._testing = True

        # If the localeSet is Unicode or a String
        # then wrap the value in a list
        if type(localeSet) != ListType:
            if localeSet is None or len(localeSet.strip()) == 0:
                # The locale is empty so do not include it
                # in the localeSet list. This will default
                # the locale to 'en' later in the code.
                localeSet = []
            else:
                localeSet = [localeSet]

        # Check if the "en" locale or one of
        # its country sub-sets such as "en_US" or
        # "en_GB" is in the localeSet. If there
        # is not a match then add "en" as the last
        # locale in the the localeSet for fallback
        # purposes. This ensures that the English
        # localization of Chandler which contains
        # string changes added after a localization
        # code freeze are leveraged in the Chandler
        # UI.
        #The locale set appending of "en"
        # must be done before the call to the
        # parent classes setLocaleSet method
        # as that method loads and initalizes the
        # the gettext .mo files for each locale in
        # the locale set.

        if not any(loc.lower().startswith("en") for loc in localeSet):
            localeSet.append("en_US")

        #XXX This can raise an Exception if an invalid locale is
        # passed. Could make a more user friendly error message
        # here by capturing and re-raising the exception.
        # A bogus locale would be related to a user manually
        # entering the locale on the command line.
        super(I18nManager, self).setLocaleSet(localeSet, fallback)

        # If there is not an .mo translation file loaded for any
        # of the locales in the locale set then default to
        # United States English to prevent wxPython and PyICU
        # from localizing while Chandler is displaying English text.
        primaryLocale = "en_US"

        if fallback:
            # Find the first locale in the locale set that either:
            #
            #   1. Has a translation egg installed.
            #
            #   2. Has a translation egg installed for its language code only.
            #      This preserves any country specific date / time formatting.
            #      For example, if the locale is fr_CA and there is no fr_CA egg
            #      but there is an fr egg then set the locale to fr_CA.

            for lc in self._localeSet:
                if (self.hasTranslation(self._DEFAULT_PROJECT,
                                        self._DEFAULT_CATALOG, lc)
                        or (hasCountryCode(lc) and self.hasTranslation(
                            self._DEFAULT_PROJECT, self._DEFAULT_CATALOG,
                            stripCountryCode(lc)))):
                    primaryLocale = lc

                    if primaryLocale == "en_US":
                        # This is a bit of a hack but
                        # not sure of a cleaner way to
                        # implement this logic.
                        # If the primaryLocale is "en_US"
                        # then it means that all of the
                        # locales in the locale set that
                        # preceeded "en" do not have a
                        # translation.
                        self._localeSet = ['en_US', 'en']
                    break
            else:
                lc = self._localeSet[0]

                if (lc.startswith("en") or self.hasTranslation(
                        self._DEFAULT_PROJECT, self._DEFAULT_CATALOG, lc)):
                    primaryLocale = lc

        try:
            self._setLocale(primaryLocale)
        except I18nException:
            if discover:
                self._setLocale("en_US", ignoreError=True)
            else:
                # If the locale was passed in (ie. not
                # discovered from the OS) then raise
                # the error. The most common case is
                # someone typing an invalid locale
                # on the command line. In this case
                # we do want to raise the error and
                # not just default to "en_US".
                raise

        # Reset the resource lookup cache
        self._lookupCache = None
        self._lookupCache = {}
Example #6
0
    def setLocaleSet(self, localeSet=None, fallback=True):
        """
        Resets the c{I18nManager locale set c{List}.

        Resetting the locale set includes unloading all gettext
        .mo translations, loading the the gettext .mo translations
        for the current locale set, and setting the gettext locale
        fallback order if the fallback parameter is set to True.

        Note the initial locale set for the c{I18nManager}
        must be set in the C{I18nManager.initialize}
        method.

        Note, setting the c{I18nManager} locale set
        also adds the language code as a fallback for language /
        county code locale definitions when fallback is set to True.
        If the locale set contains 'fr_CA' this method will also add
        to the locale set 'fr' as a fallback for 'fr_CA'.

        If no localeSet is passed the discoverLocaleSet
        method will be called to retrieve the
        locale set of the Operating System.

        A locale of 'test' can be passed to this method.

        In testing mode all values returned by
        the c{I18nManager.getText} and c{i18nManager.wxTranslate}
        methods insert a (\u00FC): at the start of the string.

        This method sets the following:
           1. The PyICU Locale
           2. The wxPython Locale
           3. The Python Locale
           4. The Operating System Enviroment Locale

        The setLocaleSet method can raise the following exceptions:
            1. c{UnicodeEncodeError}
            2. c{NameError}
            3. c{I18nException}

        @param localeSet: A c{unicode} or c{str}  or c{List}
                          containing locale country and language
                          codes. The value(s) must be able to
                          be converted to ASCII. If None
                          is passed the setLocaleSet method
                          will call the discoverLocaleSet
                          method to retrieve the Operating
                          System locale set.

        @type localeSet: None or ASCII c{str} or c{unicode} or
                         c{List} containing ASCII
                         c{str} or c{unicode} values

         @param fallback: Indicates whether locale set fallback should
                          take place. If set to True, the
                          c{I18nManager} will search all locales
                          in the locale set till a resource or
                          gettext mo translation file is found. If
                          set to False the c{I18nManager} will
                          only try to locate a resource or
                          gettext mo translation file for the
                          current locale which is the first locale
                          in the locale set.


          @type fallback: c{boolean}
        """
        self._testing = False

        discover = localeSet is None

        if discover:
            try:
                localeSet = self.discoverLocaleSet()
            except:
                # Just in case an error is raised in the
                # discovering of the localeSet, capture
                # it here and keep the localeSet variable
                # as None. This will result in the
                # locale being set to "en_US" later in the
                # code. In the discovery case Chandler
                # should do everything possible to
                # still load the application even
                # if an error was raised.
                pass
        else:
            assert(type(localeSet) == ListType or
                   type(localeSet) == UnicodeType or
                   type(localeSet) == StringType)

            if 'test' in localeSet:
                localeSet = ['en_US']
                self._testing = True

        # If the localeSet is Unicode or a String
        # then wrap the value in a list
        if type(localeSet) != ListType:
            if localeSet is None or len(localeSet.strip()) == 0:
                # The locale is empty so do not include it
                # in the localeSet list. This will default
                # the locale to 'en' later in the code.
                localeSet = []
            else:
                localeSet = [localeSet]

        # Check if the "en" locale or one of
        # its country sub-sets such as "en_US" or
        # "en_GB" is in the localeSet. If there
        # is not a match then add "en" as the last
        # locale in the the localeSet for fallback
        # purposes. This ensures that the English
        # localization of Chandler which contains
        # string changes added after a localization
        # code freeze are leveraged in the Chandler
        # UI.
        #The locale set appending of "en"
        # must be done before the call to the
        # parent classes setLocaleSet method
        # as that method loads and initalizes the
        # the gettext .mo files for each locale in
        # the locale set.

        if not any(loc.lower().startswith("en") for loc in localeSet):
            localeSet.append("en_US")

        #XXX This can raise an Exception if an invalid locale is
        # passed. Could make a more user friendly error message
        # here by capturing and re-raising the exception.
        # A bogus locale would be related to a user manually
        # entering the locale on the command line.
        super(I18nManager, self).setLocaleSet(localeSet, fallback)

        # If there is not an .mo translation file loaded for any
        # of the locales in the locale set then default to
        # United States English to prevent wxPython and PyICU
        # from localizing while Chandler is displaying English text.
        primaryLocale = "en_US"

        if fallback:
            # Find the first locale in the locale set that either:
            #
            #   1. Has a translation egg installed.
            #
            #   2. Has a translation egg installed for its language code only.
            #      This preserves any country specific date / time formatting.
            #      For example, if the locale is fr_CA and there is no fr_CA egg 
            #      but there is an fr egg then set the locale to fr_CA.

            for lc in self._localeSet:
                if (self.hasTranslation(self._DEFAULT_PROJECT,
                                        self._DEFAULT_CATALOG, lc) or
                    (hasCountryCode(lc) and
                     self.hasTranslation(self._DEFAULT_PROJECT,
                                         self._DEFAULT_CATALOG,
                                         stripCountryCode(lc)))):
                    primaryLocale = lc

                    if primaryLocale == "en_US":
                        # This is a bit of a hack but
                        # not sure of a cleaner way to
                        # implement this logic.
                        # If the primaryLocale is "en_US"
                        # then it means that all of the
                        # locales in the locale set that
                        # preceeded "en" do not have a
                        # translation.
                        self._localeSet = ['en_US', 'en']
                    break
            else:
                lc = self._localeSet[0]

                if (lc.startswith("en") or
                    self.hasTranslation(self._DEFAULT_PROJECT, 
                                        self._DEFAULT_CATALOG, lc)):
                    primaryLocale = lc

        try:
            self._setLocale(primaryLocale)
        except I18nException:
            if discover:
                self._setLocale("en_US", ignoreError=True)
            else:
                # If the locale was passed in (ie. not
                # discovered from the OS) then raise
                # the error. The most common case is
                # someone typing an invalid locale
                # on the command line. In this case
                # we do want to raise the error and
                # not just default to "en_US".
                raise

        # Reset the resource lookup cache
        self._lookupCache = None
        self._lookupCache = {}
Example #7
0
    def __init__(self):
        super(LocalePickerDialog, self).__init__(wx.GetApp().mainFrame, -1, u"", style=wx.DEFAULT_DIALOG_STYLE)
        self._locales = {}

        localeCodes = getAvailableChandlerLocales()
        icuLocales = Locale.getAvailableLocales()
        icuLocaleCodes = icuLocales.keys()
        langCodeAdded = {}
        linux = sys.platform.startswith("linux")

        for localeCode in localeCodes:
            langCode = stripCountryCode(localeCode)

            if linux and not hasWxLocale(langCode):
                # Not all WxPython translations are
                # installed by default on English
                # versions of Linux. Thus even
                # though there is a translation
                # egg available for Chandler, wx
                # will raise an error on Chandler
                # start up
                continue

            if hasCountryCode(localeCode) and not langCode in localeCodes:
                # There is no translation egg available for
                # the langCode (fallback). In this case, country variations
                # can not be made available to the user. This will
                # be rare if ever happen that say a "fr_CA" egg is
                # registered with Chandler but not an "fr" egg.
                self._locales[Locale(localeCode).getDisplayName()] = localeCode
                continue

            if not langCodeAdded.has_key(langCode):
                added = False

                for icuLocale in icuLocaleCodes:
                    if icuLocale.startswith(langCode):
                        self._locales[icuLocales[icuLocale].getDisplayName()] = icuLocale
                        added = True
                if added:
                    langCodeAdded[langCode] = True

        currentLocale = getLocale()
        currentLocaleName = Locale(currentLocale).getDisplayName()

        if currentLocale not in localeCodes:
            # Add the current locale to the locale selection list.
            # This case occurs when a user manual specifies a locale
            # on the command line or via prefs that does not have
            # a translation egg installed.
            self._locales[currentLocaleName] = currentLocale

        choices = self._locales.keys()
        choices.sort()

        # Now continue with the normal construction of the dialog
        # contents
        sizer = wx.BoxSizer(wx.VERTICAL)
        label = wx.StaticText(self, -1, _(u"Please select a language:"), size=(DIALOG_WIDTH, -1))
        label.Wrap(DIALOG_WIDTH)

        sizer.Add(label, 0, wx.ALIGN_CENTER | wx.ALL, 10)

        self._localeChoices = wx.Choice(self, -1, choices=choices, size=(DIALOG_WIDTH - 70, -1))

        sizer.Add(self._localeChoices, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 10)

        pos = self._localeChoices.FindString(currentLocaleName)

        if pos != wx.NOT_FOUND:
            self._localeChoices.SetSelection(pos)

        sizer.AddSpacer(10, 0)

        bsizer = wx.BoxSizer(wx.HORIZONTAL)

        # Load the wx.ICON_EXCLAMATION icon
        bmp = wx.ArtProvider.GetBitmap(wx.ART_WARNING, wx.ART_MESSAGE_BOX, (32, 32))
        icon = wx.StaticBitmap(self, -1, bmp)
        bsizer.Add(icon, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)

        note = wx.StaticText(self, -1, _(u"Switching languages will cause Chandler to automatically restart."))

        note.Wrap(DIALOG_WIDTH)

        bsizer.Add(note, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        sizer.Add(bsizer)

        sizer.AddSpacer(5, 0)

        box = wx.BoxSizer(wx.HORIZONTAL)
        btn = wx.Button(self, wx.ID_OK)
        btn.SetDefault()
        box.Add(btn, 0, wx.ALIGN_RIGHT | wx.ALL, 5)

        btn = wx.Button(self, wx.ID_CANCEL)
        box.Add(btn, 0, wx.ALIGN_RIGHT | wx.ALL, 5)

        sizer.Add(box, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        sizer.Fit(self)