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 get()55 public static FlagManager get() { 56 return sInstance; 57 } 58 59 /** Use the {@link #get()} factory method */ FlagManager()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 */ getEmptyIcon()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 */ getGlobeIcon()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 getFlag(@ullable String language, @Nullable String region)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 */ getFlag(@ullable LocaleQualifier locale)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 getFlagForFolderName(@onNull String folder)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 getFlag(@onNull FolderConfiguration configuration)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 getFlag(@onNull String region)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 getIcon(@onNull String base)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