1 19 20 package org.netbeans.modules.editor.options; 21 22 import java.awt.Toolkit ; 23 import java.awt.event.KeyEvent ; 24 import java.io.IOException ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.Map ; 31 32 import org.netbeans.editor.Settings; 33 import org.netbeans.editor.SettingsNames; 34 import org.openide.xml.XMLUtil; 35 36 import org.w3c.dom.Document ; 37 import org.w3c.dom.Element ; 38 import org.w3c.dom.Node ; 39 import org.w3c.dom.NodeList ; 40 import org.w3c.dom.Text ; 41 import java.util.List ; 42 import org.netbeans.editor.MultiKeyBinding; 43 import javax.swing.text.JTextComponent ; 44 45 52 public class KeyBindingsMIMEOptionFile extends MIMEOptionFile{ 53 54 55 public static final String TAG_ROOT = "bindings"; public static final String TAG_BIND = "bind"; 58 59 public static final String ATTR_KEY = "key"; public static final String ATTR_ACTION_NAME = "actionName"; public static final String ATTR_REMOVE = "remove"; 63 64 static final String FILENAME = "keybindings"; 66 public KeyBindingsMIMEOptionFile(BaseOptions base, Object proc) { 67 super(base, proc); 68 } 69 70 private List getKBList(){ 71 Settings.KitAndValue[] kav = Settings.getValueHierarchy(base.getKitClass(), SettingsNames.KEY_BINDING_LIST); 72 List kbList = null; 73 for (int i = 0; i < kav.length; i++) { 74 if (kav[i].kitClass == base.getKitClass()) { 75 kbList = (List )kav[i].value; 76 } 77 } 78 if (kbList == null) { 79 kbList = new ArrayList (); 80 } 81 82 int cnt = kbList.size(); 84 for (int i = 0; i < cnt; i++) { 85 Object o = kbList.get(i); 86 if (!(o instanceof MultiKeyBinding) && o != null) { 87 JTextComponent.KeyBinding b = (JTextComponent.KeyBinding )o; 88 kbList.set(i, new MultiKeyBinding(b.key, b.actionName)); 89 } 90 } 91 return new ArrayList ( kbList ); 92 } 93 94 96 protected void loadSettings(boolean propagate){ 97 synchronized (Settings.class) { 98 if (base.usesNewOptionsDialog()){ 99 return; 100 } 101 Document doc = dom; 102 Element rootElement = doc.getDocumentElement(); 103 104 if (!TAG_ROOT.equals(rootElement.getTagName())) { 105 return; 107 } 108 109 List keybs = getKBList(); 111 Map mapa = OptionUtilities.makeKeyBindingsMap(keybs); 112 properties.clear(); 113 114 NodeList bind = rootElement.getElementsByTagName(TAG_BIND); 115 int len = bind.getLength(); 116 for (int i=0; i<len; i++){ 117 Node node = bind.item(i); 118 Element bindElement = (Element )node; 119 120 if (bindElement == null){ 121 continue; 122 } 123 124 String key = bindElement.getAttribute(ATTR_KEY); 125 String delete = bindElement.getAttribute(ATTR_REMOVE); 126 String actionName = bindElement.getAttribute(ATTR_ACTION_NAME); 127 if (actionName==null) actionName=""; 128 129 130 if ((actionName.length() != 0) && (!Boolean.valueOf(delete).booleanValue())){ 131 if(key.indexOf('$') > 0){ 132 MultiKeyBinding mkb = new MultiKeyBinding( OptionUtilities.stringToKeys(key) , actionName ); 133 properties.put(key, mkb); 134 }else{ 135 MultiKeyBinding mkb = new MultiKeyBinding( OptionUtilities.stringToKey(key) , actionName ); 136 properties.put(key, mkb ); 137 } 138 }else{ 139 properties.put(key, "" ); 140 } 141 142 } 143 144 if (properties.size()>0){ 145 mapa.putAll(properties); 147 148 for( Iterator i = properties.keySet().iterator(); i.hasNext(); ) { 150 String key = (String )i.next(); 151 if(properties.get(key) instanceof String ){ 152 mapa.remove(key); 154 } 155 } 156 157 if (propagate){ 159 setLoaded(true); 160 base.setKeyBindingList(new ArrayList (mapa.values()), false); 161 } 162 } 163 if (propagate) setLoaded(true); 164 } 165 } 166 167 169 protected void updateSettings(Map changedProp){ 170 synchronized (Settings.class) { 171 if (base.usesNewOptionsDialog()){ 172 return; 173 } 174 properties.putAll(changedProp); 176 177 Document doc = XMLUtil.createDocument(TAG_ROOT, null, processor.getPublicID(), processor.getSystemID()); 179 Element rootElem = doc.getDocumentElement(); 180 181 ArrayList removed = new ArrayList (); 182 183 Map defaultKeybs = base.getDefaultKeyBindingsMap(); 184 185 if (defaultKeybs == null) defaultKeybs = new HashMap (); 187 188 for( Iterator i = properties.keySet().iterator(); i.hasNext(); ) { 190 String key = (String )i.next(); 191 193 if (properties.get(key) instanceof String ){ 194 String realKey = tryRemoveKeyFromMap(doc, properties, key, defaultKeybs, rootElem); 195 if (realKey != null) { 196 removed.add(realKey); 197 key = realKey; 198 } 199 200 continue; 202 } 203 204 if (properties.get(key) instanceof MultiKeyBinding){ 205 MultiKeyBinding mkb = (MultiKeyBinding) properties.get(key); 206 String curActionName= mkb.actionName; 207 if (curActionName == null) curActionName=""; 209 boolean save = true; 210 if (defaultKeybs.get(key) instanceof MultiKeyBinding){ 211 String defActionName = ((MultiKeyBinding)defaultKeybs.get(key)).actionName; 212 213 boolean hasKey = defaultKeybs.containsKey(key); 214 if (!hasKey) { 216 String [] s = getPermutations (key); 217 for (int j=0; j < s.length && !hasKey; j++) { 218 hasKey |= defaultKeybs.containsKey(s[j]); 219 if (hasKey) { 220 key = s[j]; 221 break; 222 } 223 } 224 } 225 226 if (hasKey && curActionName.equals(defActionName)) save = false; 228 } 229 230 if (save){ 231 Element keybElem = doc.createElement(TAG_BIND); 232 keybElem.setAttribute(ATTR_KEY, key); 233 keybElem.setAttribute(ATTR_ACTION_NAME, curActionName); 234 rootElem.appendChild(keybElem); 235 } 236 } 237 } 238 239 for (int i=0; i<removed.size(); i++){ 241 properties.remove(removed.get(i)); 242 } 243 244 doc.getDocumentElement().normalize(); 245 246 saveSettings(doc); 247 } 248 } 249 250 private static String tryRemoveKeyFromMap (Document doc, Map props, String key, Map defaultKeybs, Element root) { 251 if (defaultKeybs.containsKey(key)){ 253 removeKeyFromMap (doc, props, key, root); 254 return key; 255 } else { 256 String [] s = getPermutations(key); 257 for (int i=0; i < s.length; i++) { 258 if (defaultKeybs.containsKey(s[i])){ 259 removeKeyFromMap (doc, props, key, root); 260 return s[i]; 261 } 262 } 263 } 264 return null; 265 } 266 267 private static void removeKeyFromMap(Document doc, Map props, String key, Element root) { 268 Element keybElem = doc.createElement(TAG_BIND); 269 keybElem.setAttribute(ATTR_KEY, key); 270 keybElem.setAttribute(ATTR_REMOVE, Boolean.TRUE.toString()); 271 root.appendChild(keybElem); 272 } 273 274 291 static String [] getPermutations (String name) { 292 String key = KeyEvent.META_MASK == Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() ? 296 "M" : "C"; 298 String ctrlWildcard = "D"; 300 String altKey = System.getProperty ("mrj.version") != null ? 301 "C" : "A"; 303 String altWildcard = "O"; 305 306 int pos = name.lastIndexOf ("-"); if (pos == -1) { 308 return new String [] { name }; 310 } 311 String keyPart = name.substring (pos); 312 String modsPart = org.openide.util.Utilities.replaceString (name.substring (0, pos), "-", ""); if (modsPart.length() > 1) { 314 Collection perms = new HashSet (modsPart.length() * modsPart.length()); 315 int idx = name.indexOf(key); 316 if (idx != -1) { 317 StringBuffer sb = new StringBuffer (modsPart); 320 sb.replace(idx, idx+1, ctrlWildcard); 321 perms.add (sb.toString() + keyPart); 322 getAllPossibleOrderings (sb.toString(), keyPart, perms); 323 createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); 324 idx = name.indexOf (altKey); 325 if (idx != -1) { 326 sb.replace (idx, idx+1, altWildcard); 327 perms.add (sb.toString() + keyPart); 328 getAllPossibleOrderings (sb.toString(), keyPart, perms); 329 createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); 330 } else { 331 idx = name.indexOf(altWildcard); 332 if (idx != -1) { 333 sb.replace (idx, idx+1, altKey); 334 perms.add (sb.toString() + keyPart); 335 getAllPossibleOrderings (sb.toString(), keyPart, perms); 336 createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); 337 } 338 } 339 } else { 340 idx = name.indexOf (ctrlWildcard); if (idx != -1) { 342 StringBuffer sb = new StringBuffer (modsPart); 343 sb.replace(idx, idx+1, key); 344 perms.add (sb.toString() + keyPart); 345 getAllPossibleOrderings (sb.toString(), keyPart, perms); 346 createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); 347 idx = name.indexOf (altKey); 348 if (idx != -1) { 349 sb.replace (idx, idx+1, altWildcard); 350 perms.add (sb.toString() + keyPart); 351 getAllPossibleOrderings (sb.toString(), keyPart, perms); 352 } else { 353 idx = name.indexOf(altWildcard); 354 if (idx != -1) { 355 sb.replace (idx, idx+1, altKey); 356 perms.add (sb.toString() + keyPart); 357 getAllPossibleOrderings (sb.toString(), keyPart, perms); 358 createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); 359 } 360 } 361 } 362 } 363 364 idx = name.indexOf (altKey); 365 if (idx != -1) { 366 StringBuffer sb = new StringBuffer (modsPart); 367 sb.replace (idx, idx+1, altWildcard); 368 perms.add (sb.toString() + keyPart); 369 getAllPossibleOrderings (sb.toString(), keyPart, perms); 370 createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); 371 } else { 372 StringBuffer sb = new StringBuffer (modsPart); 373 idx = name.indexOf(altWildcard); 374 if (idx != -1) { 375 sb.replace (idx, idx+1, altKey); 376 perms.add (sb.toString() + keyPart); 377 getAllPossibleOrderings (sb.toString(), keyPart, perms); 378 createHyphenatedPermutation(sb.toString().toCharArray(), perms, keyPart); 379 } 380 } 381 382 getAllPossibleOrderings (modsPart, keyPart, perms); 383 createHyphenatedPermutation(modsPart.toCharArray(), perms, keyPart); 384 return (String []) perms.toArray(new String [perms.size()]); 385 } else { 386 return key.equals (modsPart) ? 387 new String [] {ctrlWildcard + keyPart} : altKey.equals(modsPart) ? 388 new String []{altWildcard + keyPart} : altWildcard.equals(modsPart) ? 389 new String [] {altKey + keyPart} : 390 new String [0]; 391 } 392 } 393 394 398 static void getAllPossibleOrderings (String s, String toAppend, final Collection store) { 399 char[] c = s.toCharArray(); 402 mutate (c, store, 0, toAppend); 403 String [] result = (String []) store.toArray(new String [store.size()]); 404 } 405 406 409 private static void mutate(char[] c, Collection l, int n, String toAppend) { 410 if (n == c.length) { 413 l.add (new String (c) + toAppend); 414 createHyphenatedPermutation(c, l, toAppend); 415 return; 416 } 417 for (int i=0; i < c.length; i++) { 419 char x = c[i]; 420 c[i] = c[n]; 421 c[n] = x; 422 if (n < c.length) { 423 mutate (c, l, n+1, toAppend); 424 } 425 } 426 } 427 428 432 static void createHyphenatedPermutation (char[] c, Collection l, String toAppend) { 433 if (c.length == 1) { 436 return; 437 } 438 StringBuffer sb = new StringBuffer (new String (c)); 439 for (int i=c.length-1; i >= 1; i-=1) { 440 sb.insert (i, '-'); 441 } 442 sb.append (toAppend); 443 l.add (sb.toString()); 444 } 445 } 446 | Popular Tags |