Home | History | Annotate | Download | only in configuration
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.eclipse.org/org/documents/epl-v10.php
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.ide.eclipse.adt.internal.editors.layout.configuration;
     17 
     18 import com.android.annotations.NonNull;
     19 import com.android.annotations.Nullable;
     20 import com.android.ide.common.resources.LocaleManager;
     21 import com.android.ide.common.resources.configuration.FolderConfiguration;
     22 import com.android.ide.common.resources.configuration.LocaleQualifier;
     23 import com.android.ide.eclipse.adt.internal.editors.IconFactory;
     24 import com.google.common.collect.Maps;
     25 
     26 import org.eclipse.swt.graphics.Image;
     27 import org.eclipse.wb.internal.core.DesignerPlugin;
     28 
     29 import java.util.Locale;
     30 import java.util.Map;
     31 
     32 /**
     33  * The {@linkplain FlagManager} provides access to flags for regions known
     34  * to {@link LocaleManager}. It also contains some locale related display
     35  * functions.
     36  * <p>
     37  * All the flag images came from the WindowBuilder subversion repository
     38  * http://dev.eclipse.org/svnroot/tools/org.eclipse.windowbuilder/trunk (and in
     39  * particular, a snapshot of revision 424). However, it appears that the icons
     40  * are from http://www.famfamfam.com/lab/icons/flags/ which states that "these
     41  * flag icons are available for free use for any purpose with no requirement for
     42  * attribution." Adding the URL here such that we can check back occasionally
     43  * and see if there are corrections or updates. Also note that the flag names
     44  * are in ISO 3166-1 alpha-2 country codes.
     45  */
     46 public class FlagManager {
     47     private static final FlagManager sInstance = new FlagManager();
     48 
     49     /**
     50      * Returns the {@linkplain FlagManager} singleton
     51      *
     52      * @return the {@linkplain FlagManager} singleton, never null
     53      */
     54     @NonNull
     55     public static FlagManager get() {
     56         return sInstance;
     57     }
     58 
     59     /** Use the {@link #get()} factory method */
     60     private FlagManager() {
     61     }
     62 
     63     /** Map from region to flag icon */
     64     private final Map<String, Image> mImageMap = Maps.newHashMap();
     65 
     66     /**
     67      * Returns the empty flag icon used to indicate an unknown country
     68      *
     69      * @return the globe icon used to indicate an unknown country
     70      */
     71     public static Image getEmptyIcon() {
     72       return DesignerPlugin.getImage("nls/flags/flag_empty.png"); //$NON-NLS-1$
     73     }
     74 
     75     /**
     76      * Returns the globe icon used to indicate "any" language
     77      *
     78      * @return the globe icon used to indicate "any" language
     79      */
     80     public static Image getGlobeIcon() {
     81         return IconFactory.getInstance().getIcon("globe"); //$NON-NLS-1$
     82     }
     83 
     84     /**
     85      * Returns the flag for the given language and region.
     86      *
     87      * @param language the language, or null (if null, region must not be null),
     88      *            the 2 letter language code (ISO 639-1), in lower case
     89      * @param region the region, or null (if null, language must not be null),
     90      *            the 2 letter region code (ISO 3166-1 alpha-2), in upper case
     91      * @return a suitable flag icon, or null
     92      */
     93     @Nullable
     94     public Image getFlag(@Nullable String language, @Nullable String region) {
     95         assert region != null || language != null;
     96         if (region == null || region.isEmpty()) {
     97             // Look up the region for a given language
     98             assert language != null;
     99 
    100             // Special cases where we have a dedicated flag available:
    101             if (language.equals("ca")) {        //$NON-NLS-1$
    102               return getIcon("catalonia");      //$NON-NLS-1$
    103             }
    104             else if (language.equals("gd")) { //$NON-NLS-1$
    105               return getIcon("scotland");     //$NON-NLS-1$
    106             }
    107             else if (language.equals("cy")) { //$NON-NLS-1$
    108               return getIcon("wales");        //$NON-NLS-1$
    109             }
    110 
    111             // Prefer the local registration of the current locale; even if
    112             // for example the default locale for English is the US, if the current
    113             // default locale is English, then use its associated country, which could
    114             // for example be Australia.
    115             Locale locale = Locale.getDefault();
    116             if (language.equals(locale.getLanguage())) {
    117                 Image flag = getFlag(locale.getCountry());
    118                 if (flag != null) {
    119                     return flag;
    120                 }
    121             }
    122 
    123             region = LocaleManager.getLanguageRegion(language);
    124         }
    125 
    126         if (region == null || region.isEmpty()) {
    127             // No country specified, and the language is for a country we
    128             // don't have a flag for
    129             return null;
    130         }
    131 
    132         return getIcon(region);
    133     }
    134 
    135     /**
    136      * Returns the flag for the given language and region.
    137      *
    138      * @param language the language qualifier, or null (if null, region must not be null),
    139      * @param region the region, or null (if null, language must not be null),
    140      * @return a suitable flag icon, or null
    141      */
    142     public Image getFlag(@Nullable LocaleQualifier locale) {
    143         if (locale == null) {
    144             return null;
    145           }
    146           String languageCode = locale.getLanguage();
    147           String regionCode = locale.getRegion();
    148           if (LocaleQualifier.FAKE_VALUE.equals(languageCode)) {
    149             languageCode = null;
    150           }
    151           return getFlag(languageCode, regionCode);
    152     }
    153 
    154     /**
    155      * Returns a flag for a given resource folder name (such as
    156      * {@code values-en-rUS}), or null
    157      *
    158      * @param folder the folder name
    159      * @return a corresponding flag icon, or null if none was found
    160      */
    161     @Nullable
    162     public Image getFlagForFolderName(@NonNull String folder) {
    163         FolderConfiguration configuration = FolderConfiguration.getConfigForFolder(folder);
    164         if (configuration != null) {
    165           return get().getFlag(configuration);
    166         }
    167 
    168         return null;
    169     }
    170 
    171     /**
    172      * Returns the flag for the given folder
    173      *
    174      * @param configuration the folder configuration
    175      * @return a suitable flag icon, or null
    176      */
    177     @Nullable
    178     public Image getFlag(@NonNull FolderConfiguration configuration) {
    179         return getFlag(configuration.getLocaleQualifier());
    180     }
    181 
    182 
    183 
    184     /**
    185      * Returns the flag for the given region.
    186      *
    187      * @param region the 2 letter region code (ISO 3166-1 alpha-2), in upper case
    188      * @return a suitable flag icon, or null
    189      */
    190     @Nullable
    191     public Image getFlag(@NonNull String region) {
    192         assert region.length() == 2
    193                 && Character.isUpperCase(region.charAt(0))
    194                 && Character.isUpperCase(region.charAt(1)) : region;
    195 
    196         return getIcon(region);
    197     }
    198 
    199     private Image getIcon(@NonNull String base) {
    200         Image flagImage = mImageMap.get(base);
    201           if (flagImage == null) {
    202               // TODO: Special case locale currently running on system such
    203               // that the current country matches the current locale
    204               if (mImageMap.containsKey(base)) {
    205                   // Already checked: there's just no image there
    206                   return null;
    207               }
    208               String flagFileName = base.toLowerCase(Locale.US) + ".png"; //$NON-NLS-1$
    209               flagImage = DesignerPlugin.getImage("nls/flags/" + flagFileName); //$NON-NLS-1$
    210               mImageMap.put(base, flagImage);
    211           }
    212 
    213         return flagImage;
    214     }
    215 }
    216