diff --git a/core.output2/nbproject/project.xml b/core.output2/nbproject/project.xml
--- a/core.output2/nbproject/project.xml
+++ b/core.output2/nbproject/project.xml
@@ -50,6 +50,14 @@
org.netbeans.core.output2
+ org.netbeans.modules.options.keymap
+
+
+
+ 1.17
+
+
+
org.openide.actions
diff --git a/core.output2/src/org/netbeans/core/output2/OutputTab.java b/core.output2/src/org/netbeans/core/output2/OutputTab.java
--- a/core.output2/src/org/netbeans/core/output2/OutputTab.java
+++ b/core.output2/src/org/netbeans/core/output2/OutputTab.java
@@ -61,6 +61,7 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
@@ -82,6 +83,8 @@
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.text.Document;
+import org.netbeans.core.options.keymap.api.ShortcutAction;
+import org.netbeans.core.options.keymap.api.ShortcutsFinder;
import org.netbeans.core.output2.Controller.ControllerOutputEvent;
import org.netbeans.core.output2.ui.AbstractOutputPane;
import org.netbeans.core.output2.ui.AbstractOutputTab;
@@ -99,7 +102,9 @@
import org.openide.xml.XMLUtil;
import static org.netbeans.core.output2.OutputTab.ACTION.*;
-import org.openide.windows.IOProvider;
+import org.netbeans.core.output2.ui.OutputKeymapManager;
+import org.netbeans.core.output2.ui.KeyStrokeNameSupport;
+import org.openide.util.Lookup;
/**
@@ -782,10 +787,13 @@
TabAction(ACTION action, String bundleKey) {
if (bundleKey != null) {
String name = NbBundle.getMessage(OutputTab.class, bundleKey);
- KeyStroke accelerator = getAcceleratorFor(bundleKey);
+ KeyStroke[] accels = getAcceleratorFor(action);
this.action = action;
putValue(NAME, name);
- putValue(ACCELERATOR_KEY, accelerator);
+ if (accels != null && accels.length > 0) {
+ putValue(ACCELERATORS_KEY, accels);
+ putValue(ACCELERATOR_KEY, getAccelForPopUp(accels));
+ }
}
}
@@ -814,15 +822,113 @@
* Get a keyboard accelerator from the resource bundle, with special handling
* for the mac keyboard layout.
*
- * @param name The bundle key prefix
+ * @param action Action to get accelerator for.
* @return A keystroke
*/
- private KeyStroke getAcceleratorFor(String name) {
- String key = name + ".accel"; //NOI18N
- if (Utilities.isMac()) {
- key += ".mac"; //NOI18N
+ private KeyStroke[] getAcceleratorFor(ACTION action) {
+ switch (action) {
+ case COPY:
+ return getKeyStrokeForAction(
+ "copy-to-clipboard"); //NOI18N
+ case PASTE:
+ return getKeyStrokeForAction(
+ "paste-from-clipboard"); //NOI18N
+ case SAVEAS:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.SAVE_AS_ACTION_ID);
+ case CLOSE:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.CLOSE_ACTION_ID);
+ case NEXT_ERROR:
+ return getKeyStrokeForAction("next-error"); //NOI18N
+ case PREV_ERROR:
+ return getKeyStrokeForAction("previous-error"); //NOI18N
+ case SELECT_ALL:
+ return getKeyStrokeForAction("select-all"); //NOI18N
+ case FIND:
+ return getKeyStrokeForAction(
+ "incremental-search-forward"); //NOI18N
+ case FIND_NEXT:
+ return getKeyStrokeForAction("find-next"); //NOI18N
+ case FIND_PREVIOUS:
+ return getKeyStrokeForAction("find-previous"); //NOI18N
+ case FILTER:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.FILTER_ACTION_ID);
+ case LARGER_FONT:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.LARGER_FONT_ACTION_ID);
+ case SMALLER_FONT:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.SMALLER_FONT_ACTION_ID);
+ case FONT_TYPE:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.FONT_TYPE_ACTION_ID);
+ case CLEAR:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.CLEAR_ACTION_ID);
+ case WRAP:
+ return getKeyStrokeForAction(
+ OutputKeymapManager.WRAP_ACTION_ID);
+ default:
+ return null;
}
- return Utilities.stringToKey(NbBundle.getMessage(OutputTab.class, key));
+ }
+
+ private KeyStroke[] getKeyStrokeForAction(String actionId) {
+ for (ShortcutsFinder sf : Lookup.getDefault().lookupAll(
+ ShortcutsFinder.class)) {
+ ShortcutAction sa = sf.findActionForId(actionId);
+ if (sa != null) {
+ String[] shortcuts = sf.getShortcuts(sa);
+ if (shortcuts != null && shortcuts.length > 0) {
+ KeyStroke[] ks = new KeyStroke[shortcuts.length];
+ int valid = 0;
+ for (int i = 0; i < shortcuts.length; i++) {
+ if (shortcuts[i] != null) {
+ KeyStroke s = humanStringToStroke(shortcuts[i]);
+ if (s != null) {
+ ks[valid++] = s;
+ }
+ }
+ }
+ return Arrays.copyOfRange(ks, 0, valid);
+ }
+ }
+ }
+ return null;
+ }
+
+ private KeyStroke humanStringToStroke(String s) {
+ if (s == null) {
+ return null;
+ }
+ KeyStroke[] strokes = KeyStrokeNameSupport.stringToKeyStrokes(s);
+ if (strokes.length > 0) {
+ return strokes[0];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the most appropriate accelerator for pop-up menu.
+ */
+ public KeyStroke getAccelForPopUp(KeyStroke[] keystrokes) {
+ KeyStroke best = null;
+ boolean isSolaris =
+ Utilities.getOperatingSystem() == Utilities.OS_SOLARIS;
+ for (KeyStroke ks : keystrokes) {
+ boolean solarisKey = ks.getKeyCode() >= KeyEvent.VK_STOP
+ && ks.getKeyCode() <= KeyEvent.VK_CUT;
+ if (isSolaris == solarisKey
+ && (best == null
+ || best.getKeyCode() > ks.getKeyCode())) {
+ //Solaris key on solaris OS or other key on other OS.
+ best = ks;
+ }
+ }
+ return best == null ? keystrokes[0] : best;
}
public ACTION getAction() {
diff --git a/core.output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java b/core.output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java
--- a/core.output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java
+++ b/core.output2/src/org/netbeans/core/output2/ui/AbstractOutputTab.java
@@ -68,6 +68,7 @@
private boolean inputVisible = false;
private AbstractOutputPane outputPane;
private Action[] actions = new Action[0];
+ protected static final String ACCELERATORS_KEY = "ACCELERATORS_KEY";//NOI18N
private Component toFocus;
@@ -191,22 +192,28 @@
//It is a Controller.ControllerAction - don't create a memory leak by listening to it
a = new WeakAction(a);
}
- KeyStroke accel = null;
+ KeyStroke[] accels = null;
String name;
- Object o = a.getValue (Action.ACCELERATOR_KEY);
- if (o instanceof KeyStroke) {
- accel = (KeyStroke) o;
+ Object o = a.getValue(ACCELERATORS_KEY);
+ if (o instanceof KeyStroke[]) {
+ accels = (KeyStroke[]) o;
}
name = (String) a.getValue(Action.NAME);
- if (accel != null) {
- if (Controller.LOG) Controller.log ("Installed action " + name + " on " + accel);
- // if the logic here changes, check the popup escaping hack in Controller
- // it temporarily removes the VK_ESCAPE from input maps..
- JComponent c = getOutputPane().textView;
- c.getInputMap().put(accel, name);
- c.getActionMap().put(name, a);
- getInputMap (WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (accel, name);
- getActionMap().put(name, a);
+ if (accels != null) {
+ for (KeyStroke accel : accels) {
+ if (Controller.LOG) {
+ Controller.log("Installed action " //NOI18N
+ + name + " on " + accel); //NOI18N
+ }
+ // if the logic here changes, check the popup escaping hack in
+ // Controller it temporarily removes the VK_ESCAPE from input
+ // maps..
+ JComponent c = getOutputPane().textView;
+ c.getInputMap().put(accel, name);
+ c.getActionMap().put(name, a);
+ getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(accel, name);
+ getActionMap().put(name, a);
+ }
}
}
diff --git a/editor.settings.storage/src/org/netbeans/modules/editor/settings/storage/spi/support/StorageSupport.java b/core.output2/src/org/netbeans/core/output2/ui/KeyStrokeNameSupport.java
copy from editor.settings.storage/src/org/netbeans/modules/editor/settings/storage/spi/support/StorageSupport.java
copy to core.output2/src/org/netbeans/core/output2/ui/KeyStrokeNameSupport.java
--- a/editor.settings.storage/src/org/netbeans/modules/editor/settings/storage/spi/support/StorageSupport.java
+++ b/core.output2/src/org/netbeans/core/output2/ui/KeyStrokeNameSupport.java
@@ -41,109 +41,48 @@
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
-package org.netbeans.modules.editor.settings.storage.spi.support;
+package org.netbeans.core.output2.ui;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.KeyStroke;
-import org.netbeans.modules.editor.settings.storage.*;
-import org.openide.filesystems.FileObject;
import org.openide.util.Utilities;
-public final class StorageSupport {
+public final class KeyStrokeNameSupport {
- private static final Logger LOG = Logger.getLogger(StorageSupport.class.getName());
+ private static final Logger LOG = Logger.getLogger(KeyStrokeNameSupport.class.getName());
private static Map names;
- private StorageSupport() {
+ private KeyStrokeNameSupport() {
}
- public static String getLocalizingBundleMessage(FileObject fo, String key, String defaultValue) {
- return Utils.getLocalizedName(fo, key, defaultValue, false);
- }
-
- /**
- * Converts a list of KeyStroke
s to its textual representation. There
- * are two available formats for the textual representation:
- *
- * Human readable - this format encodes a KeyStroke
to
- * a string that looks like for example 'Ctrl+A' or 'Alt+Shift+M'.
- * Emacs style - this format encodes a KeyStroke
to
- * a string that's known from Emacs and that looks like for example 'C-A' or 'AS-M'.
- * It uses methods from org.openide.util.Utilities
, which take
- * care of Mac OS specifics and use 'D' and 'O' wildcards for encoding 'Ctrl'
- * and 'Alt' keys.
- *
- * @param keys The KeyStrokes
to convert.
- * @param emacsStyle If true
the returned string will be in so called
- * Emacs style, ortherwise it will be in human readable format.
- *
- * @return The textual representation of KeyStroke
s passed in.
- * @since 1.16
- */
- public static String keyStrokesToString(Collection extends KeyStroke> keys, boolean emacsStyle) {
- StringBuilder sb = new StringBuilder();
-
- for (Iterator extends KeyStroke> it = keys.iterator(); it.hasNext(); ) {
- KeyStroke keyStroke = it.next();
- if (emacsStyle) {
- sb.append(Utilities.keyToString(keyStroke, true));
- if (it.hasNext()) {
- sb.append('$'); //NOI18N
- }
- } else {
- sb.append(keyStrokeToHumanReadableString(keyStroke));
- if (it.hasNext()) {
- sb.append(' '); //NOI18N
- }
- }
- }
-
- return sb.toString();
- }
-
/**
* Converts a textual representation of key strokes to an array of KeyStroke
- * objects. Please see {@link #keyStrokesToString(Collection, boolean)}
- * ror details about the available formats.
+ * objects.
*
- * @param key The textual representation of keystorkes to convert. Its format
- * depends on the value of emacsStyle
parameter.
- * @param emacsStyle If true
the key
string is expected to be
- * in so called emacs format, ortherwise it will be in human readable format.
- *
+ * @param key The textual representation of keystorkes to convert.
* @return The KeyStroke
s that were represented by the key
* text or null
if the textual representation was malformed.
- * @since 1.16
*/
- public static KeyStroke[] stringToKeyStrokes(String key, boolean emacsStyle) {
+ public static KeyStroke[] stringToKeyStrokes(String key) {
assert key != null : "The parameter key must not be null"; //NOI18N
List result = new ArrayList();
- String delimiter = emacsStyle ? "$" : " "; //NOI18N
+ String delimiter = " "; //NOI18N
for(StringTokenizer st = new StringTokenizer(key, delimiter); st.hasMoreTokens();) { //NOI18N
String ks = st.nextToken().trim();
- KeyStroke keyStroke;
-
- if (emacsStyle) {
- keyStroke = Utilities.stringToKey(ks);
- } else {
- keyStroke = humanReadableStringToKeyStroke(ks);
- }
-
+ KeyStroke keyStroke = humanReadableStringToKeyStroke(ks);
if (keyStroke != null) {
result.add(keyStroke);
} else {
@@ -210,31 +149,4 @@
return names;
}
}
-
- private static String keyStrokeToHumanReadableString(KeyStroke keyStroke) {
- int modifiers = keyStroke.getModifiers();
- StringBuilder sb = new StringBuilder();
- if ((modifiers & InputEvent.CTRL_DOWN_MASK) > 0) {
- sb.append(EMACS_CTRL);
- }
- if ((modifiers & InputEvent.ALT_DOWN_MASK) > 0) {
- sb.append(EMACS_ALT);
- }
- if ((modifiers & InputEvent.SHIFT_DOWN_MASK) > 0) {
- sb.append(EMACS_SHIFT);
- }
- if ((modifiers & InputEvent.META_DOWN_MASK) > 0) {
- sb.append(EMACS_META);
- }
- if (keyStroke.getKeyCode() != KeyEvent.VK_SHIFT &&
- keyStroke.getKeyCode() != KeyEvent.VK_CONTROL &&
- keyStroke.getKeyCode() != KeyEvent.VK_META &&
- keyStroke.getKeyCode() != KeyEvent.VK_ALT &&
- keyStroke.getKeyCode() != KeyEvent.VK_ALT_GRAPH
- ) {
- sb.append(Utilities.keyToString(KeyStroke.getKeyStroke(keyStroke.getKeyCode(), 0)));
- }
- return sb.toString();
- }
-
}
diff --git a/core.output2/src/org/netbeans/core/output2/ui/OutputKeymapManager.java b/core.output2/src/org/netbeans/core/output2/ui/OutputKeymapManager.java
new file mode 100644
--- /dev/null
+++ b/core.output2/src/org/netbeans/core/output2/ui/OutputKeymapManager.java
@@ -0,0 +1,334 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2012 Sun Microsystems, Inc.
+ */
+package org.netbeans.core.output2.ui;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.netbeans.core.options.keymap.api.ShortcutAction;
+import org.netbeans.core.options.keymap.spi.KeymapManager;
+import org.netbeans.core.output2.NbIOProvider;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ *
+ * @author jhavlin
+ */
+@ServiceProvider(service = KeymapManager.class)
+public class OutputKeymapManager extends KeymapManager {
+
+ private static final Logger LOG = Logger.getLogger(
+ OutputKeymapManager.class.getName());
+ private static final String CATEGORY_NAME = NbBundle.getMessage(
+ NbIOProvider.class, "OpenIDE-Module-Name"); //NOI18N
+ /**
+ * ID of actions in keymap settings panel.
+ */
+ public static final String CLEAR_ACTION_ID =
+ "output-window-clear"; //NOI18N
+ public static final String FILTER_ACTION_ID =
+ "output-window-filter"; //NOI18N
+ public static final String LARGER_FONT_ACTION_ID =
+ "output-window-larger-font"; //NOI18N
+ public static final String SMALLER_FONT_ACTION_ID =
+ "output-window-smaller-font"; //NOI18N
+ public static final String CLOSE_ACTION_ID =
+ "output-window-close"; //NOI18N
+ public static final String FONT_TYPE_ACTION_ID =
+ "output-window-font-type"; //NOI18N
+ public static final String SAVE_AS_ACTION_ID =
+ "output-window-save-as"; //NOI18N
+ public static final String WRAP_ACTION_ID =
+ "output-window-wrap"; //NOI18N
+ /**
+ * Constants for persistence.
+ */
+ public static final String STORAGE_DIR =
+ "org-netbeans-core-output2/actions/"; //NOI18N
+ public static final String SHORTCUT_PREFIX = "sc"; //NOI18N
+ /**
+ * Actions
+ */
+ private final OutWinShortCutAction wrap = new OutWinShortCutAction(
+ WRAP_ACTION_ID, "ACTION_WRAP"); //NOI18N
+ private final OutWinShortCutAction clear = new OutWinShortCutAction(
+ CLEAR_ACTION_ID, "ACTION_CLEAR"); //NOI18N
+ private final OutWinShortCutAction filter = new OutWinShortCutAction(
+ FILTER_ACTION_ID, "ACTION_FILTER"); //NOI18N
+ private final OutWinShortCutAction largerFont = new OutWinShortCutAction(
+ LARGER_FONT_ACTION_ID, "ACTION_LARGER_FONT"); //NOI18N
+ private final OutWinShortCutAction smallerFont = new OutWinShortCutAction(
+ SMALLER_FONT_ACTION_ID, "ACTION_SMALLER_FONT"); //NOI18N
+ private final OutWinShortCutAction closeWindow = new OutWinShortCutAction(
+ CLOSE_ACTION_ID, "ACTION_CLOSE"); //NOI18N
+ private final OutWinShortCutAction fontType = new OutWinShortCutAction(
+ FONT_TYPE_ACTION_ID, "ACTION_FONT_TYPE"); //NOI18N
+ private final OutWinShortCutAction saveAs = new OutWinShortCutAction(
+ SAVE_AS_ACTION_ID, "ACTION_SAVEAS"); //NOI18N
+ /**
+ * Map of keymaps. Keys are profile names.
+ */
+ Map>> keymaps =
+ new HashMap>>();
+ /**
+ * The default keymap. Used if keys for a profile are not set.
+ */
+ Map> defaultKeymap =
+ new HashMap>();
+ /**
+ * List of all actions.
+ */
+ private final Set allActions =
+ new HashSet();
+ /**
+ * Map of actions of categories. There is only one category in this case.
+ */
+ Map> actions =
+ new HashMap>();
+
+ public OutputKeymapManager() {
+ super("OutputWindowKeymapManager"); //NOI18N
+ actions = new HashMap>();
+ Collections.addAll(allActions, wrap, clear, filter, largerFont,
+ smallerFont, closeWindow, fontType, saveAs);
+ Set set = new HashSet();
+ set.addAll(allActions);
+ actions.put(CATEGORY_NAME, set);
+ fillDefaultKeyMap();
+ loadShortCuts();
+ }
+
+ private void fillDefaultKeyMap() {
+ for (OutWinShortCutAction a : allActions) {
+ String dflt = a.getDefaultShortcut();
+ defaultKeymap.put(a, (dflt != null && !dflt.isEmpty())
+ ? Collections.singleton(dflt)
+ : Collections.emptySet());
+ }
+ }
+
+ @Override
+ public Map> getActions() {
+ return actions;
+ }
+
+ @Override
+ public void refreshActions() {
+ }
+
+ @Override
+ public Map> getKeymap(String profileName) {
+ Map> km = keymaps.get(profileName);
+ if (km == null) {
+ km = new HashMap>(defaultKeymap);
+ keymaps.put(profileName, km);
+ }
+ return km;
+ }
+
+ @Override
+ public Map> getDefaultKeymap(
+ String profileName) {
+ return defaultKeymap;
+ }
+
+ @Override
+ public void saveKeymap(String profileName,
+ Map> actionToShortcuts) {
+
+ Map> newShortcuts =
+ new HashMap>();
+ keymaps.put(profileName, newShortcuts);
+ for (OutWinShortCutAction owsa : allActions) {
+ Set shortcuts = actionToShortcuts.get(owsa);
+ if (shortcuts == null) {
+ shortcuts = Collections.emptySet();
+ }
+ newShortcuts.put(owsa, shortcuts);
+ }
+ storeShortCuts(profileName);
+ }
+
+ @Override
+ public List getProfiles() {
+ return null;
+ }
+
+ @Override
+ public String getCurrentProfile() {
+ return null;
+ }
+
+ @Override
+ public void setCurrentProfile(String profileName) {
+ }
+
+ @Override
+ public void deleteProfile(String profileName) {
+ }
+
+ @Override
+ public boolean isCustomProfile(String profileName) {
+ return false;
+ }
+
+ private class OutWinShortCutAction implements ShortcutAction {
+
+ private String id;
+ private String bundleKey;
+ private String displayName;
+ private String defaultShortcut;
+
+ public OutWinShortCutAction(String id, String bundleKey) {
+ this.id = id;
+ this.bundleKey = bundleKey;
+ this.displayName = NbBundle.getMessage(
+ NbIOProvider.class, bundleKey);
+ String nbKeysBundleKey = Utilities.isMac()
+ ? bundleKey + ".accel.mac" //NOI18N
+ : bundleKey + ".accel"; //NOI18N
+ String nbKeys = NbBundle.getMessage(NbIOProvider.class,
+ nbKeysBundleKey);
+ this.defaultShortcut = nbKeys;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getBundleKey() {
+ return bundleKey;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getDefaultShortcut() {
+ return defaultShortcut;
+ }
+
+ @Override
+ public String getDelegatingActionId() {
+ return null;
+ }
+
+ @Override
+ public ShortcutAction getKeymapManagerInstance(
+ String keymapManagerName) {
+ return null;
+ }
+ }
+
+ private void storeShortCuts(String profileName) {
+ FileObject root = FileUtil.getConfigRoot();
+ try {
+ FileObject actionsDir = FileUtil.createFolder(
+ root, STORAGE_DIR + profileName);
+ for (OutWinShortCutAction a : allActions) {
+ FileObject data = actionsDir.getFileObject(a.getId());
+ if (data == null) {
+ data = actionsDir.createData(a.getId());
+ } else if (data.isFolder()) {
+ throw new IOException(data + " is a folder."); //NOI18N
+ }
+ Enumeration atts = data.getAttributes();
+ while (atts.hasMoreElements()) {
+ String attName = atts.nextElement();
+ data.setAttribute(attName, null);
+ }
+ int index = 1;
+ if (keymaps.get(profileName).get(a) == null) {
+ continue;
+ }
+ for (String shortCut : keymaps.get(profileName).get(a)) {
+ data.setAttribute(SHORTCUT_PREFIX + index++, shortCut);
+ }
+ }
+ } catch (IOException e) {
+ LOG.log(Level.WARNING, "Cannot create folder", e); //NOI18N
+ }
+ }
+
+ private void loadShortCuts() {
+ FileObject root = FileUtil.getConfigRoot();
+ FileObject actionsDir = root.getFileObject(STORAGE_DIR);
+ if (actionsDir == null) {
+ return;
+ }
+ for (FileObject profileDir : actionsDir.getChildren()) {
+ if (!profileDir.isFolder()) {
+ continue;
+ }
+ Map> keymap =
+ new HashMap>();
+ keymaps.put(profileDir.getName(), keymap);
+ for (OutWinShortCutAction a : allActions) {
+ FileObject actionFile = profileDir.getFileObject(a.getId());
+ if (actionFile == null || !actionFile.isData()) {
+ keymap.put(a, Collections.emptySet());
+ continue;
+ }
+ Enumeration atts = actionFile.getAttributes();
+ Set strokes = new HashSet();
+ while (atts.hasMoreElements()) {
+ String att = atts.nextElement();
+ if (att.startsWith(SHORTCUT_PREFIX)) {
+ strokes.add((String) actionFile.getAttribute(att));
+ }
+ }
+ keymap.put(a, strokes);
+ }
+ }
+ }
+}
diff --git a/options.keymap/nbproject/project.xml b/options.keymap/nbproject/project.xml
--- a/options.keymap/nbproject/project.xml
+++ b/options.keymap/nbproject/project.xml
@@ -152,6 +152,7 @@
+ org.netbeans.core.output2
org.netbeans.modules.editor.macros
org.netbeans.modules.jumpto
org.netbeans.modules.jvi