KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > options > keymap > EditorBridge


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.options.keymap;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.lang.ref.WeakReference JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.MissingResourceException JavaDoc;
33 import java.util.Set JavaDoc;
34 import javax.swing.Action JavaDoc;
35 import javax.swing.KeyStroke JavaDoc;
36 import javax.swing.text.EditorKit JavaDoc;
37 import javax.swing.text.TextAction JavaDoc;
38 import org.netbeans.api.editor.mimelookup.MimeLookup;
39 import org.netbeans.api.editor.mimelookup.MimePath;
40 import org.netbeans.api.editor.settings.MultiKeyBinding;
41 import org.netbeans.editor.BaseAction;
42 import org.netbeans.editor.BaseKit;
43 import org.netbeans.modules.editor.NbEditorKit;
44 import org.netbeans.modules.editor.settings.storage.api.EditorSettings;
45 import org.netbeans.modules.editor.settings.storage.api.KeyBindingSettingsFactory;
46 import org.openide.ErrorManager;
47 import org.openide.filesystems.FileObject;
48 import org.openide.filesystems.FileSystem;
49 import org.openide.filesystems.Repository;
50 import org.openide.util.Lookup;
51 import org.openide.util.NbBundle;
52 import org.openide.util.Utilities;
53
54
55 /**
56  * @author Jan Jancura
57  */

58 public final class EditorBridge {
59     
60     private Map JavaDoc actions;
61     
62     Map JavaDoc getActions () {
63         if (actions == null) {
64             Map JavaDoc categories = readCategories ();
65             actions = new HashMap JavaDoc ();
66             Iterator JavaDoc it = getEditorActionsMap ().values ().iterator ();
67             while (it.hasNext ()) {
68                 ActionImpl action = (ActionImpl) it.next ();
69                 String JavaDoc category = (String JavaDoc) categories.get (action.getId ());
70                 if (category == null)
71                     category = NbBundle.getMessage
72                         (EditorBridge.class, "CTL_Other"); // NOI18N
73
Set JavaDoc a = (Set JavaDoc) actions.get (category);
74                 if (a == null) {
75                     a = new HashSet JavaDoc ();
76                     actions.put (category, a);
77                 }
78                 a.add (action);
79             }
80             actions.remove ("Hidden"); // NOI18N
81
}
82         return actions;
83     }
84     
85     void refreshActions () {
86         editorActionsMap = null;
87         actions = null;
88         actionNameToMimeTypes = new HashMap JavaDoc ();
89     }
90
91     String JavaDoc getCurrentProfile () {
92         return getEditorSettings ().getCurrentKeyMapProfile ();
93     }
94     
95     void setCurrentProfile (String JavaDoc profile) {
96         getEditorSettings ().setCurrentKeyMapProfile (profile);
97     }
98     
99     boolean isCustomProfile (String JavaDoc profile) {
100         return getEditorSettings ().isCustomKeymapProfile (profile);
101     }
102     
103     Map JavaDoc readKeymap (String JavaDoc profile) {
104         Map JavaDoc result = new HashMap JavaDoc ();
105         readKeymap (profile, "text/base", false, result);
106         Iterator JavaDoc it = getEditorSettings ().getMimeTypes ().iterator ();
107         while (it.hasNext ())
108             readKeymap (profile, (String JavaDoc) it.next (), false, result);
109         return Collections.unmodifiableMap (result);
110     }
111     
112     Map JavaDoc readKeymapDefaults (String JavaDoc profile) {
113         Map JavaDoc result = new HashMap JavaDoc ();
114         readKeymap (profile, "text/base", true, result);
115         Iterator JavaDoc it = getEditorSettings ().getMimeTypes ().iterator ();
116         while (it.hasNext ())
117             readKeymap (profile, (String JavaDoc) it.next (), true, result);
118         return Collections.unmodifiableMap (result);
119     }
120
121     void deleteProfile (String JavaDoc profile) {
122         KeyBindingSettingsFactory kbs = getKeyBindingSettings ("text/base");
123         kbs.setKeyBindings (profile, null);
124     }
125     
126     /**
127      * Saves actionToShortcuts Map (GlobalAction > Set (String (shortcut)).
128      * Ignores all non EditorAction actions.
129      */

130     void saveKeymap (String JavaDoc profile, Map JavaDoc actionToShortcuts) {
131         
132         // 1)
133
// convert actionToShortcuts: Map (ActionImpl > Set (String (shortcut AS-M)))
134
// to mimeTypeToKeyBinding: Map (String (mimetype) > List (MultiKeyBinding)).
135
Map JavaDoc mimeTypeToKeyBinding = new HashMap JavaDoc (); // editor shortcuts
136
Iterator JavaDoc it = actionToShortcuts.keySet ().iterator ();
137         while (it.hasNext ()) {
138             ActionImpl action = (ActionImpl) it.next ();
139             Set JavaDoc shortcuts = (Set JavaDoc) actionToShortcuts.get (action);
140
141             if (action instanceof CompoundAction)
142                 action = ((CompoundAction) action).getEditorAction ();
143             if (!(action instanceof EditorAction)) continue;
144             EditorAction editorAction = (EditorAction) action;
145             Set JavaDoc mimeTypes = getMimeTypes (editorAction);
146
147             Iterator JavaDoc it2 = shortcuts.iterator ();
148             while (it2.hasNext ()) {
149                 String JavaDoc shortcut = (String JavaDoc) it2.next ();
150                 MultiKeyBinding mkb = new MultiKeyBinding (
151                     Utils.stringToKeyStrokes2 (shortcut),
152                     editorAction.getId ()
153                 );
154                 Iterator JavaDoc it3 = mimeTypes.iterator ();
155                 while (it3.hasNext ()) {
156                     String JavaDoc mimeType = (String JavaDoc) it3.next ();
157                     List JavaDoc l = (List JavaDoc) mimeTypeToKeyBinding.get (mimeType);
158                     if (l == null) {
159                         l = new ArrayList JavaDoc ();
160                         mimeTypeToKeyBinding.put (mimeType, l);
161                     }
162                     l.add (mkb);
163                 }
164             }
165         }
166         
167         // 2) save all shortcuts
168
it = keyBindingSettings.keySet ().iterator ();
169         while (it.hasNext ()) {
170             String JavaDoc mimeType = (String JavaDoc) it.next ();
171             KeyBindingSettingsFactory kbs = (KeyBindingSettingsFactory) keyBindingSettings.
172                 get (mimeType);
173             //log ("changeKeymap.editorShortcuts " + mimeType, (List) mimeTypeToKeyBinding.get (mimeType));
174
kbs.setKeyBindings (profile, (List JavaDoc) mimeTypeToKeyBinding.get (mimeType));
175         }
176     }
177     
178     
179     // private methods .........................................................
180

181     /** Map (String (mimeType) > Set (String (action name))). */
182     private Map JavaDoc editorActionsMap;
183     /** Map (ActionImpl > Set (String (mimeType))). */
184     private Map JavaDoc actionNameToMimeTypes = new HashMap JavaDoc ();
185     
186     /**
187      * Returns map of all editor actions.
188      * Map (String (mimeType) > Set (String (action name)))
189      */

190     private Map JavaDoc getEditorActionsMap () {
191         if (editorActionsMap == null) {
192             editorActionsMap = new HashMap JavaDoc ();
193             Iterator JavaDoc it = getEditorSettings ().getMimeTypes ().iterator ();
194             while (it.hasNext ())
195                 initActionMap ((String JavaDoc) it.next ());
196             initActionMap ("text/base");
197         }
198         return editorActionsMap;
199     }
200     
201     private Set JavaDoc getMimeTypes (EditorAction a) {
202         getEditorActionsMap (); // initialization
203
return (Set JavaDoc) actionNameToMimeTypes.get (a.getId ());
204     }
205     
206     /**
207      * Loads editor actions for given mimeType to editorActionsMap.
208      */

209     private void initActionMap (String JavaDoc mimeType) {
210         
211         // 1) get EditorKit
212
EditorKit JavaDoc editorKit = null;
213         if (mimeType.equals ("text/base")) {
214             editorKit = BaseKit.getKit (NbEditorKit.class);
215         } else {
216             Lookup mimeLookup = MimeLookup.getLookup (MimePath.parse(mimeType));
217             editorKit = (EditorKit JavaDoc) mimeLookup.lookup (EditorKit JavaDoc.class);
218         }
219         if (editorKit == null) {
220             if (System.getProperty ("org.netbeans.optionsDialog") != null)
221                 System.out.println
222                     ("KeymapModel EditorKit not found for: " + mimeType);
223             return;
224         }
225         
226         // 2) copy actions from EditorKit to actionMap
227
Action JavaDoc[] as = editorKit.getActions ();
228         int i, k = as.length;
229         for (i = 0; i < k; i++) {
230             Object JavaDoc isHidden = as [i].getValue (BaseAction.NO_KEYBINDING);
231             if (isHidden instanceof Boolean JavaDoc &&
232                 ((Boolean JavaDoc) isHidden).booleanValue ()
233             )
234                 continue; // ignore hidden actions
235

236             EditorAction action = new EditorAction ((TextAction JavaDoc) as [i]);
237             String JavaDoc id = action.getId ();
238             editorActionsMap.put (id, action);
239             if (mimeType.equals ("text/base")) {
240                 actionNameToMimeTypes.put (id, Collections.singleton ("text/base"));
241                 continue;
242             }
243             Set JavaDoc s = (Set JavaDoc) actionNameToMimeTypes.get (id);
244             if (s == null) {
245                 s = new HashSet JavaDoc ();
246                 actionNameToMimeTypes.put (id, s);
247             }
248             s.add (mimeType);
249         }
250     }
251     
252     private EditorSettings editorSettings;
253     
254     private EditorSettings getEditorSettings () {
255         if (editorSettings == null)
256             editorSettings = EditorSettings.getDefault ();
257         return editorSettings;
258     }
259     
260     private Map JavaDoc keyBindingSettings = new HashMap JavaDoc ();
261     private KeyBindingSettingsFactory getKeyBindingSettings (String JavaDoc mimeType) {
262         if (keyBindingSettings.containsKey (mimeType))
263             return (KeyBindingSettingsFactory) keyBindingSettings.get (mimeType);
264         KeyBindingSettingsFactory kbs = EditorSettings.getDefault ().
265             getKeyBindingSettings (new String JavaDoc[] {mimeType});
266         keyBindingSettings.put (mimeType, kbs);
267         getListener ().add (kbs);
268         return kbs;
269     }
270     
271     private Listener JavaDoc listener;
272     private Listener JavaDoc getListener () {
273         if (listener == null)
274             listener = new Listener JavaDoc (this);
275         return listener;
276     }
277     
278     private static class Listener implements PropertyChangeListener JavaDoc {
279         
280         private WeakReference JavaDoc model;
281         private Set JavaDoc settings = new HashSet JavaDoc ();
282         
283         Listener (EditorBridge model) {
284             this.model = new WeakReference JavaDoc (model);
285         }
286         
287         void add (KeyBindingSettingsFactory settings) {
288             this.settings.add (settings);
289             settings.addPropertyChangeListener (this);
290         }
291         
292         private EditorBridge getModel () {
293             EditorBridge m = (EditorBridge) model.get ();
294             if (m != null) return m;
295             Iterator JavaDoc it = settings.iterator ();
296             while (it.hasNext ())
297                 ((KeyBindingSettingsFactory) it.next ()).
298                     removePropertyChangeListener (this);
299             settings = new HashSet JavaDoc ();
300             return null;
301         }
302         
303         public void propertyChange (PropertyChangeEvent JavaDoc evt) {
304             EditorBridge model = getModel ();
305             if (model == null) return;
306             //model.keyMaps = new HashMap ();
307
}
308     }
309     
310     /**
311      * Reads keymap for given mimetype and profile to given map
312      * Map (ActionImpl > Set (String (shortcut)))
313      */

314     private void readKeymap (
315         String JavaDoc profile,
316         String JavaDoc mimeType,
317         boolean defaults,
318         Map JavaDoc map
319     ) {
320         // 1) get list of MultiKeyBindings
321
KeyBindingSettingsFactory kbs = getKeyBindingSettings (mimeType);
322         if (kbs == null) return;
323         List JavaDoc keyBindings = defaults ?
324             kbs.getKeyBindingDefaults (profile) :
325             kbs.getKeyBindings (profile);
326         if (keyBindings == null) return;
327
328         // 2) create Map (String (action name) > Set (String (shortcut)))
329
Map JavaDoc actionNameToShortcuts = convertKeymap (keyBindings);
330
331         // 3) create Map (EditorAction > Set (String (shortcut)))
332
Iterator JavaDoc it = actionNameToShortcuts.keySet ().iterator ();
333         while (it.hasNext ()) {
334             String JavaDoc actionName = (String JavaDoc) it.next ();
335             Set JavaDoc keyStrokes = (Set JavaDoc) actionNameToShortcuts.get
336                 (actionName);
337             ActionImpl action = (ActionImpl) getEditorActionsMap ().get (actionName);
338             if (action == null) {
339                 if (System.getProperty ("org.netbeans.optionsDialog") != null)
340                     System.out.println ("action not found " + actionName);
341                 continue;
342             }
343             Set JavaDoc s = (Set JavaDoc) map.get (action);
344             if (s == null)
345                 map.put (action, keyStrokes);
346             else
347                 s.addAll (keyStrokes);
348         }
349     }
350     
351     /**
352      * create Map (String (action name) > Set (String (shortcut AS-M)))
353      *
354      * @param keyBindings list of MultiKeyBindings
355      */

356     private static Map JavaDoc convertKeymap (List JavaDoc keyBindings) {
357         Map JavaDoc actionNameToShortcuts = new HashMap JavaDoc ();
358         int i, k = keyBindings.size ();
359         for (i = 0; i < k; i++) {
360             MultiKeyBinding mkb = (MultiKeyBinding) keyBindings.get (i);
361             String JavaDoc keyStroke = "";
362             Iterator JavaDoc it = mkb.getKeyStrokeList ().iterator ();
363             if (it.hasNext ()) {
364                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc
365                     (Utilities.keyToString ((KeyStroke JavaDoc) it.next ()));
366                 while (it.hasNext ())
367                     sb.append (' ').append
368                         (Utilities.keyToString ((KeyStroke JavaDoc) it.next ()));
369                 keyStroke = sb.toString ();
370             }
371
372             Set JavaDoc keyStrokes = (Set JavaDoc) actionNameToShortcuts.get
373                 (mkb.getActionName ());
374             if (keyStrokes == null) {
375                 keyStrokes = new HashSet JavaDoc ();
376                 actionNameToShortcuts.put (mkb.getActionName (), keyStrokes);
377             }
378             keyStrokes.add (keyStroke);
379             //S ystem.out.println(" " + mkb.actionName + " : " + keyStroke);
380
}
381         return actionNameToShortcuts;
382     }
383
384     private static Map JavaDoc readCategories () {
385         Map JavaDoc result = new HashMap JavaDoc ();
386         FileSystem fs = Repository.getDefault ().getDefaultFileSystem ();
387         FileObject fo = fs.findResource ("OptionsDialog/Actions");
388         if (fo == null) return result;
389         FileObject[] categories = fo.getChildren ();
390         int i, k = categories.length;
391         for (i = 0; i < k; i++) {
392             String JavaDoc categoryName = categories [i].getName ();
393             String JavaDoc bundleName = (String JavaDoc) categories [i].getAttribute
394                 ("SystemFileSystem.localizingBundle");
395             if (bundleName != null)
396                 try {
397                     categoryName = NbBundle.getBundle (bundleName).getString (
398                         categories [i].getPath ()
399                     );
400                 } catch (MissingResourceException JavaDoc ex) {
401                     ErrorManager.getDefault ().notify (ex);
402                 }
403             FileObject[] actions = categories [i].getChildren ();
404             int j, jj = actions.length;
405             for (j = 0; j < jj; j++) {
406                 if (actions [j].getExt ().length () > 0) continue;
407                 String JavaDoc actionName = actions [j].getName ();
408                 result.put (actionName, categoryName);
409             }
410         }
411         return result;
412     }
413     
414     public static class EditorAction implements ActionImpl {
415         private TextAction JavaDoc action;
416         private String JavaDoc name;
417         private String JavaDoc id;
418         private String JavaDoc delegaitngActionId;
419         
420         public EditorAction (TextAction JavaDoc a) {
421             action = a;
422         }
423         
424         public String JavaDoc getDisplayName () {
425             if (name == null) {
426                 name = (String JavaDoc) action.getValue (Action.SHORT_DESCRIPTION);
427                 name = name.replaceAll ("&", "").trim ();
428             }
429             return name;
430         }
431         
432         public String JavaDoc getId () {
433             if (id == null)
434                 id = (String JavaDoc) action.getValue (Action.NAME);
435             return id;
436         }
437         
438         public String JavaDoc getDelegatingActionId () {
439             if (delegaitngActionId == null)
440                 delegaitngActionId = (String JavaDoc) action.getValue
441                     (NbEditorKit.SYSTEM_ACTION_CLASS_NAME_PROPERTY);
442             return delegaitngActionId;
443         }
444         
445         public boolean equals (Object JavaDoc o) {
446             if (!(o instanceof EditorAction)) return false;
447             return ((EditorAction) o).getId ().equals (getId ());
448         }
449         
450         public int hashCode () {
451             return getId ().hashCode ();
452         }
453         
454         public String JavaDoc toString () {
455             return super.toString () + ":" + getId ();
456         }
457     }
458 }
459
Popular Tags