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    }