1 19 20 package org.netbeans.modules.options.keymap; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.lang.ref.WeakReference ; 25 import java.util.ArrayList ; 26 import java.util.Collections ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.MissingResourceException ; 33 import java.util.Set ; 34 import javax.swing.Action ; 35 import javax.swing.KeyStroke ; 36 import javax.swing.text.EditorKit ; 37 import javax.swing.text.TextAction ; 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 58 public final class EditorBridge { 59 60 private Map actions; 61 62 Map getActions () { 63 if (actions == null) { 64 Map categories = readCategories (); 65 actions = new HashMap (); 66 Iterator it = getEditorActionsMap ().values ().iterator (); 67 while (it.hasNext ()) { 68 ActionImpl action = (ActionImpl) it.next (); 69 String category = (String ) categories.get (action.getId ()); 70 if (category == null) 71 category = NbBundle.getMessage 72 (EditorBridge.class, "CTL_Other"); Set a = (Set ) actions.get (category); 74 if (a == null) { 75 a = new HashSet (); 76 actions.put (category, a); 77 } 78 a.add (action); 79 } 80 actions.remove ("Hidden"); } 82 return actions; 83 } 84 85 void refreshActions () { 86 editorActionsMap = null; 87 actions = null; 88 actionNameToMimeTypes = new HashMap (); 89 } 90 91 String getCurrentProfile () { 92 return getEditorSettings ().getCurrentKeyMapProfile (); 93 } 94 95 void setCurrentProfile (String profile) { 96 getEditorSettings ().setCurrentKeyMapProfile (profile); 97 } 98 99 boolean isCustomProfile (String profile) { 100 return getEditorSettings ().isCustomKeymapProfile (profile); 101 } 102 103 Map readKeymap (String profile) { 104 Map result = new HashMap (); 105 readKeymap (profile, "text/base", false, result); 106 Iterator it = getEditorSettings ().getMimeTypes ().iterator (); 107 while (it.hasNext ()) 108 readKeymap (profile, (String ) it.next (), false, result); 109 return Collections.unmodifiableMap (result); 110 } 111 112 Map readKeymapDefaults (String profile) { 113 Map result = new HashMap (); 114 readKeymap (profile, "text/base", true, result); 115 Iterator it = getEditorSettings ().getMimeTypes ().iterator (); 116 while (it.hasNext ()) 117 readKeymap (profile, (String ) it.next (), true, result); 118 return Collections.unmodifiableMap (result); 119 } 120 121 void deleteProfile (String profile) { 122 KeyBindingSettingsFactory kbs = getKeyBindingSettings ("text/base"); 123 kbs.setKeyBindings (profile, null); 124 } 125 126 130 void saveKeymap (String profile, Map actionToShortcuts) { 131 132 Map mimeTypeToKeyBinding = new HashMap (); Iterator it = actionToShortcuts.keySet ().iterator (); 137 while (it.hasNext ()) { 138 ActionImpl action = (ActionImpl) it.next (); 139 Set shortcuts = (Set ) 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 mimeTypes = getMimeTypes (editorAction); 146 147 Iterator it2 = shortcuts.iterator (); 148 while (it2.hasNext ()) { 149 String shortcut = (String ) it2.next (); 150 MultiKeyBinding mkb = new MultiKeyBinding ( 151 Utils.stringToKeyStrokes2 (shortcut), 152 editorAction.getId () 153 ); 154 Iterator it3 = mimeTypes.iterator (); 155 while (it3.hasNext ()) { 156 String mimeType = (String ) it3.next (); 157 List l = (List ) mimeTypeToKeyBinding.get (mimeType); 158 if (l == null) { 159 l = new ArrayList (); 160 mimeTypeToKeyBinding.put (mimeType, l); 161 } 162 l.add (mkb); 163 } 164 } 165 } 166 167 it = keyBindingSettings.keySet ().iterator (); 169 while (it.hasNext ()) { 170 String mimeType = (String ) it.next (); 171 KeyBindingSettingsFactory kbs = (KeyBindingSettingsFactory) keyBindingSettings. 172 get (mimeType); 173 kbs.setKeyBindings (profile, (List ) mimeTypeToKeyBinding.get (mimeType)); 175 } 176 } 177 178 179 181 182 private Map editorActionsMap; 183 184 private Map actionNameToMimeTypes = new HashMap (); 185 186 190 private Map getEditorActionsMap () { 191 if (editorActionsMap == null) { 192 editorActionsMap = new HashMap (); 193 Iterator it = getEditorSettings ().getMimeTypes ().iterator (); 194 while (it.hasNext ()) 195 initActionMap ((String ) it.next ()); 196 initActionMap ("text/base"); 197 } 198 return editorActionsMap; 199 } 200 201 private Set getMimeTypes (EditorAction a) { 202 getEditorActionsMap (); return (Set ) actionNameToMimeTypes.get (a.getId ()); 204 } 205 206 209 private void initActionMap (String mimeType) { 210 211 EditorKit 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 ) mimeLookup.lookup (EditorKit .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 Action [] as = editorKit.getActions (); 228 int i, k = as.length; 229 for (i = 0; i < k; i++) { 230 Object isHidden = as [i].getValue (BaseAction.NO_KEYBINDING); 231 if (isHidden instanceof Boolean && 232 ((Boolean ) isHidden).booleanValue () 233 ) 234 continue; 236 EditorAction action = new EditorAction ((TextAction ) as [i]); 237 String 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 s = (Set ) actionNameToMimeTypes.get (id); 244 if (s == null) { 245 s = new HashSet (); 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 keyBindingSettings = new HashMap (); 261 private KeyBindingSettingsFactory getKeyBindingSettings (String mimeType) { 262 if (keyBindingSettings.containsKey (mimeType)) 263 return (KeyBindingSettingsFactory) keyBindingSettings.get (mimeType); 264 KeyBindingSettingsFactory kbs = EditorSettings.getDefault (). 265 getKeyBindingSettings (new String [] {mimeType}); 266 keyBindingSettings.put (mimeType, kbs); 267 getListener ().add (kbs); 268 return kbs; 269 } 270 271 private Listener listener; 272 private Listener getListener () { 273 if (listener == null) 274 listener = new Listener (this); 275 return listener; 276 } 277 278 private static class Listener implements PropertyChangeListener { 279 280 private WeakReference model; 281 private Set settings = new HashSet (); 282 283 Listener (EditorBridge model) { 284 this.model = new WeakReference (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 it = settings.iterator (); 296 while (it.hasNext ()) 297 ((KeyBindingSettingsFactory) it.next ()). 298 removePropertyChangeListener (this); 299 settings = new HashSet (); 300 return null; 301 } 302 303 public void propertyChange (PropertyChangeEvent evt) { 304 EditorBridge model = getModel (); 305 if (model == null) return; 306 } 308 } 309 310 314 private void readKeymap ( 315 String profile, 316 String mimeType, 317 boolean defaults, 318 Map map 319 ) { 320 KeyBindingSettingsFactory kbs = getKeyBindingSettings (mimeType); 322 if (kbs == null) return; 323 List keyBindings = defaults ? 324 kbs.getKeyBindingDefaults (profile) : 325 kbs.getKeyBindings (profile); 326 if (keyBindings == null) return; 327 328 Map actionNameToShortcuts = convertKeymap (keyBindings); 330 331 Iterator it = actionNameToShortcuts.keySet ().iterator (); 333 while (it.hasNext ()) { 334 String actionName = (String ) it.next (); 335 Set keyStrokes = (Set ) 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 s = (Set ) map.get (action); 344 if (s == null) 345 map.put (action, keyStrokes); 346 else 347 s.addAll (keyStrokes); 348 } 349 } 350 351 356 private static Map convertKeymap (List keyBindings) { 357 Map actionNameToShortcuts = new HashMap (); 358 int i, k = keyBindings.size (); 359 for (i = 0; i < k; i++) { 360 MultiKeyBinding mkb = (MultiKeyBinding) keyBindings.get (i); 361 String keyStroke = ""; 362 Iterator it = mkb.getKeyStrokeList ().iterator (); 363 if (it.hasNext ()) { 364 StringBuffer sb = new StringBuffer 365 (Utilities.keyToString ((KeyStroke ) it.next ())); 366 while (it.hasNext ()) 367 sb.append (' ').append 368 (Utilities.keyToString ((KeyStroke ) it.next ())); 369 keyStroke = sb.toString (); 370 } 371 372 Set keyStrokes = (Set ) actionNameToShortcuts.get 373 (mkb.getActionName ()); 374 if (keyStrokes == null) { 375 keyStrokes = new HashSet (); 376 actionNameToShortcuts.put (mkb.getActionName (), keyStrokes); 377 } 378 keyStrokes.add (keyStroke); 379 } 381 return actionNameToShortcuts; 382 } 383 384 private static Map readCategories () { 385 Map result = new HashMap (); 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 categoryName = categories [i].getName (); 393 String bundleName = (String ) 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 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 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 action; 416 private String name; 417 private String id; 418 private String delegaitngActionId; 419 420 public EditorAction (TextAction a) { 421 action = a; 422 } 423 424 public String getDisplayName () { 425 if (name == null) { 426 name = (String ) action.getValue (Action.SHORT_DESCRIPTION); 427 name = name.replaceAll ("&", "").trim (); 428 } 429 return name; 430 } 431 432 public String getId () { 433 if (id == null) 434 id = (String ) action.getValue (Action.NAME); 435 return id; 436 } 437 438 public String getDelegatingActionId () { 439 if (delegaitngActionId == null) 440 delegaitngActionId = (String ) action.getValue 441 (NbEditorKit.SYSTEM_ACTION_CLASS_NAME_PROPERTY); 442 return delegaitngActionId; 443 } 444 445 public boolean equals (Object 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 toString () { 455 return super.toString () + ":" + getId (); 456 } 457 } 458 } 459 | Popular Tags |