001 ///////////////////////////////////////////////// 002 // This file is part of Sears project. 003 // Subtitle Editor And Re-Synch 004 // A tool to easily modify and resynch movies subtitles. 005 ///////////////////////////////////////////////// 006 //This program is free software; 007 //you can redistribute it and/or modify it under the terms 008 //of the GNU General Public License 009 //as published by the Free Software Foundation; 010 //either version 2 of the License, or (at your option) any later version. 011 ///////////////////////////////////////////////// 012 //Sears project is available under sourceforge 013 // at adress: http://sourceforge.net/projects/sears/ 014 //Copyright (C) 2005 Booba Skaya 015 //Mail: booba.skaya@gmail.com 016 //////////////////////////////////////////////// 017 018 package sears.gui.resources; 019 020 import java.awt.Toolkit; 021 import java.awt.event.InputEvent; 022 import java.awt.event.KeyEvent; 023 import java.io.File; 024 import java.net.URL; 025 import java.util.HashMap; 026 027 import javax.swing.ImageIcon; 028 import javax.swing.KeyStroke; 029 030 import sears.gui.JDialogOptions; 031 import sears.gui.MainWindow; 032 import sears.tools.JarResources; 033 import sears.tools.SearsProperties; 034 import sears.tools.Trace; 035 036 /** 037 * Class SearsResourceBundle. 038 * <br><b>Summary:</b><br> 039 * This class contains resources for Sears GUI. 040 */ 041 public class SearsResources { 042 private static Object[][] resources = { 043 //General stuff 044 { "SearsGUIIcon", "sears.png" }, 045 { "SearsGUITitle", "Sears Beta V" }, 046 { "BrowseIcon", "browse.png" }, 047 048 //Open Action 049 { "OpenIcon", "open.png"}, 050 { "OpenKey" , KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK)}, 051 { "OpenKeyMac", KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.META_MASK)}, 052 053 //Save Action 054 { "SaveIcon", "save.png"}, 055 { "SaveKey" , KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)}, 056 { "SaveKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.META_MASK)}, 057 058 //SaveAs Action 059 { "SaveAsIcon", "saveAs.png"}, 060 { "SaveAsKey" , KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_MASK)}, 061 { "SaveAsKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.META_MASK | InputEvent.SHIFT_MASK)}, 062 063 //Quit Action 064 { "QuitIcon", "quit.png"}, 065 //{ "QuitKey" , KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)}, 066 //{ "QuitKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.META_MASK)}, 067 068 //Delay Action 069 { "DelayIcon", "delay.png"}, 070 { "DelayKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F1, InputEvent.CTRL_DOWN_MASK)}, 071 { "DelayKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_1, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 072 073 //Resynch Action 074 { "ResynchIcon", "resynch.png"}, 075 { "ResynchKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F2, InputEvent.CTRL_DOWN_MASK)}, 076 { "ResynchKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_2, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 077 078 //Split Action 079 { "SplitIcon", "split.png"}, 080 { "SplitKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.CTRL_DOWN_MASK)}, 081 { "SplitKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_3, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 082 083 //Append Action 084 { "AppendIcon", "append.png"}, 085 { "AppendKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.CTRL_DOWN_MASK)}, 086 { "AppendKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_4, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 087 088 //ChainRepair Action 089 { "ChainRepairIcon", "chainRepair.png"}, 090 { "ChainRepairKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F5, InputEvent.CTRL_DOWN_MASK)}, 091 { "ChainRepairKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_5, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 092 093 //AccentRepair Action 094 { "AccentRepairIcon", "accentRepair.png"}, 095 { "AccentRepairKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F6, InputEvent.CTRL_DOWN_MASK)}, 096 { "AccentRepairKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_6, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 097 098 //HtmlRepair Action 099 { "HtmlRepairIcon", "htmlRepair.png"}, 100 { "HtmlRepairKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F7, InputEvent.CTRL_DOWN_MASK)}, 101 { "HtmlRepairKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_7, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 102 103 //OrderRepair Action 104 { "OrderRepairIcon", "orderRepair.png"}, 105 { "OrderRepairKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F8, InputEvent.CTRL_DOWN_MASK)}, 106 { "OrderRepairKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_8, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 107 108 //TimeRepair Action 109 { "TimeRepairIcon", "timeRepair.png"}, 110 { "TimeRepairKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F9, InputEvent.CTRL_DOWN_MASK)}, 111 { "TimeRepairKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_9, InputEvent.META_MASK | InputEvent.CTRL_DOWN_MASK)}, 112 113 //NormalizeDuration Action 114 { "NormalizeDurationIcon", "normalizeDuration.png"}, 115 { "NormalizeDurationKey" , null}, 116 117 //Split GUI stuff 118 { "SplitGUIBanner", "splitBanner.png"}, 119 120 //SelectVideo Action 121 { "SelectVideoIcon", "openVideo.png"}, 122 { "SelectVideoKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F10, InputEvent.CTRL_DOWN_MASK)}, 123 { "SelectVideoKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.META_DOWN_MASK | InputEvent.SHIFT_MASK)}, 124 125 //Options Action 126 { "OptionsIcon", "options.png"}, 127 { "OptionsKey" , KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_DOWN_MASK)}, 128 { "OptionsKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, InputEvent.META_MASK)}, 129 130 //Play Action 131 { "PlayIcon", "playIcon.png"}, 132 { "PlayKey" , KeyStroke.getKeyStroke(KeyEvent.VK_F11, InputEvent.CTRL_DOWN_MASK)}, 133 { "PlayKeyMac" , KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.META_DOWN_MASK | InputEvent.SHIFT_MASK)}, 134 135 //Pause Action 136 { "PauseIcon", "pauseIcon.png"}, 137 138 //Stop Action 139 { "StopIcon", "stopIcon.png"}, 140 141 //Previous Action 142 { "PreviousIcon", "rewardIcon.png"}, 143 144 //Next Action 145 { "NextIcon", "forwardIcon.png"}, 146 147 //GotoSub Action 148 { "GotoSubIcon", "gotoSubIcon.png"}, 149 150 //MagicResynchro Action 151 { "MagicResynchroIcon", "magicResynchro.png"}, 152 153 //RemoveAllAnchors Action 154 { "RemoveAllAnchorsIcon", "removeAllAnchors.png"}, 155 156 //RecentFile Action 157 { "RecentFileIcon", "openRecent.png"}, 158 159 //Anchor icon 160 { "AnchorIcon", "anchor.png"}, 161 162 //Dot icon 163 { "DotIcon", "dot.png"}, 164 165 //About Action 166 { "AboutIcon", "aboutIcon.png"}, 167 168 //Help 169 { "HelpIcon", "helpIcon.png"}, 170 // no question_mark keyEvent... 171 }; 172 173 private static HashMap<String, Object> resourcesMap; 174 175 private static JarResources jarResources; 176 177 private static String iconFolder; 178 179 180 /** 181 * Method getString. 182 * <br><b>Summary:</b><br> 183 * This method return the value that correspond to the given key. 184 * @param key The key to search. 185 * @return The <b>String</b> searched value, or "" if does not found. 186 */ 187 public static String getString(String key) { 188 //the result of the method. 189 String result = ""; 190 if (resourcesMap == null) { 191 constructMap(); 192 } 193 String value = (String) resourcesMap.get(key); 194 //return value only if non null 195 if (value != null) { 196 result = value; 197 } 198 //return the result 199 return result; 200 } 201 202 /** 203 * Method getIcon. 204 * <br><b>Summary:</b><br> 205 * This method return the icon that correspond to the given key. 206 * @param key The key to search. 207 * @return The <b>ImageIcon</b> searched icon, or blankIcon if does not found. 208 */ 209 public static ImageIcon getIcon(String key) { 210 //the result of the method. 211 ImageIcon result = null; 212 String iconFile = getString(key); 213 if (!iconFile.equals("")) { 214 //retrieve icon URL. 215 //check if a skin is precised. 216 String iconSetFile = SearsProperties.getProperty(SearsProperties.ICON_SET); 217 if(iconSetFile != null && !iconSetFile.equals("")){ 218 //We have to reach the icon in the jar file using the jarResources. 219 //create the jarResources if not already set. 220 if(jarResources == null){ 221 jarResources = new JarResources(getIconFolder()+File.separator+iconSetFile); 222 } 223 //Reach the icon in it. 224 byte[] byteImage = jarResources.getResource(iconFile); 225 if(byteImage != null){ 226 result = new ImageIcon(Toolkit.getDefaultToolkit().createImage(byteImage)); 227 }else{ 228 Trace.warning("Can't find resource "+iconFile+" in jar resources "+iconSetFile+". Using default icon."); 229 } 230 } 231 //If can not find resource, use default icon. 232 if(result == null){ 233 URL url = MainWindow.instance.getClass().getResource("/sears/gui/resources/" + iconFile); 234 if(url != null){ 235 result = new ImageIcon(url); 236 } 237 } 238 } 239 //if could not find icon, return blank icon 240 if(result == null){ 241 result = new ImageIcon(MainWindow.instance.getClass().getResource("/sears/gui/resources/blank.png")); 242 } 243 //return the result 244 return result; 245 } 246 247 /** 248 * Method getKey. 249 * <br><b>Summary:</b><br> 250 * This method return the Key accelerator that correspond to the given key. 251 * @param key The key to search. 252 * @return The <b>KeyStroke</b> searched key, or null if does not found. 253 */ 254 public static KeyStroke getKey(String key) { 255 // if we are running on Mac OS: 256 if(System.getProperty("mrj.version") != null){ 257 key = key + "Mac"; 258 } 259 //the result of the method. 260 KeyStroke result = (KeyStroke) resourcesMap.get(key); 261 //return the result 262 return result; 263 } 264 265 /** 266 * Method constructMap. 267 * <br><b>Summary:</b><br> 268 * This contruct the HashMap of resources. 269 */ 270 private static void constructMap() { 271 resourcesMap = new HashMap<String, Object>(); 272 for (int i = 0; i < resources.length; i++) { 273 resourcesMap.put((String) resources[i][0], resources[i][1]); 274 } 275 } 276 277 /** 278 * Method getIconFolder. 279 * <br><b>Summary:</b><br> 280 * This method return the Icon folder. 281 * @return (<b>String</b>) the Icon folder. 282 */ 283 public static String getIconFolder() { 284 if (iconFolder == null) { 285 // To do that retrieve the location of the JDialogOption class 286 String classResource = JDialogOptions.class.getResource( 287 "JDialogOptions.class").getFile(); 288 // Then retrieve the index of the "file:" string, which indicate we 289 // are executing from a jar file. 290 int indexOfFile = classResource.indexOf("file:"); 291 // the beginning of the jar file contain, if it exists: 292 int indexOfJar = classResource.indexOf("!"); 293 // if we are in a jar file: 294 if (indexOfFile != -1 && indexOfJar != -1) { 295 // we get the parent file of the jar file: 296 File parent = new File(classResource.substring(0, indexOfJar)).getParentFile(); 297 // and with the parent of the parent, we get back the icon directory path: 298 iconFolder = new File(parent.getParent()) + System.getProperty("file.separator") + "icons"; 299 //remove begining "file:" pattern 300 iconFolder = iconFolder.substring(5); 301 } else { 302 // we are not in a jar file, let's assume we are in eclipse. 303 // And eclipse project does export the icons folder. 304 // search for the last sears pattern, which is the root for the 305 // sears class. 306 int indexOfSearsPackage = classResource.lastIndexOf("sears"); 307 if (indexOfSearsPackage != -1) { 308 // we have retrieved the sears folder, go up, and find the 309 // icon folder. 310 iconFolder = classResource 311 .substring(0, indexOfSearsPackage); 312 iconFolder += "icons"; 313 } 314 } 315 } 316 return iconFolder; 317 } 318 }