Line 0
Link Here
|
|
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2012 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* If you wish your version of this file to be governed by only the CDDL |
28 |
* or only the GPL Version 2, indicate your decision by adding |
29 |
* "[Contributor] elects to include this software in this distribution |
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
31 |
* single choice of license, a recipient has the option to distribute |
32 |
* your version of this file under either the CDDL, the GPL Version 2 or |
33 |
* to extend the choice of license to its licensees as provided above. |
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
35 |
* Version 2 license, then the option applies only if the new code is |
36 |
* made subject to such option by the copyright holder. |
37 |
* |
38 |
* Contributor(s): |
39 |
* |
40 |
* Portions Copyrighted 2012 Sun Microsystems, Inc. |
41 |
*/ |
42 |
package org.netbeans.core.output2.ui; |
43 |
|
44 |
import java.io.IOException; |
45 |
import java.util.Collections; |
46 |
import java.util.Enumeration; |
47 |
import java.util.HashMap; |
48 |
import java.util.HashSet; |
49 |
import java.util.List; |
50 |
import java.util.Map; |
51 |
import java.util.Set; |
52 |
import java.util.logging.Level; |
53 |
import java.util.logging.Logger; |
54 |
import org.netbeans.core.options.keymap.api.ShortcutAction; |
55 |
import org.netbeans.core.options.keymap.spi.KeymapManager; |
56 |
import org.netbeans.core.output2.NbIOProvider; |
57 |
import org.openide.filesystems.FileObject; |
58 |
import org.openide.filesystems.FileUtil; |
59 |
import org.openide.util.NbBundle; |
60 |
import org.openide.util.Utilities; |
61 |
import org.openide.util.lookup.ServiceProvider; |
62 |
|
63 |
/** |
64 |
* |
65 |
* @author jhavlin |
66 |
*/ |
67 |
@ServiceProvider(service = KeymapManager.class) |
68 |
public class OutputKeymapManager extends KeymapManager { |
69 |
|
70 |
private static final Logger LOG = Logger.getLogger( |
71 |
OutputKeymapManager.class.getName()); |
72 |
private static final String CATEGORY_NAME = NbBundle.getMessage( |
73 |
NbIOProvider.class, "OpenIDE-Module-Name"); //NOI18N |
74 |
/** |
75 |
* ID of actions in keymap settings panel. |
76 |
*/ |
77 |
public static final String CLEAR_ACTION_ID = |
78 |
"output-window-clear"; //NOI18N |
79 |
public static final String FILTER_ACTION_ID = |
80 |
"output-window-filter"; //NOI18N |
81 |
public static final String LARGER_FONT_ACTION_ID = |
82 |
"output-window-larger-font"; //NOI18N |
83 |
public static final String SMALLER_FONT_ACTION_ID = |
84 |
"output-window-smaller-font"; //NOI18N |
85 |
public static final String CLOSE_ACTION_ID = |
86 |
"output-window-close"; //NOI18N |
87 |
public static final String FONT_TYPE_ACTION_ID = |
88 |
"output-window-font-type"; //NOI18N |
89 |
public static final String SAVE_AS_ACTION_ID = |
90 |
"output-window-save-as"; //NOI18N |
91 |
public static final String WRAP_ACTION_ID = |
92 |
"output-window-wrap"; //NOI18N |
93 |
/** |
94 |
* Constants for persistence. |
95 |
*/ |
96 |
public static final String STORAGE_DIR = |
97 |
"org-netbeans-core-output2/actions/"; //NOI18N |
98 |
public static final String SHORTCUT_PREFIX = "sc"; //NOI18N |
99 |
/** |
100 |
* Actions |
101 |
*/ |
102 |
private final OutWinShortCutAction wrap = new OutWinShortCutAction( |
103 |
WRAP_ACTION_ID, "ACTION_WRAP"); //NOI18N |
104 |
private final OutWinShortCutAction clear = new OutWinShortCutAction( |
105 |
CLEAR_ACTION_ID, "ACTION_CLEAR"); //NOI18N |
106 |
private final OutWinShortCutAction filter = new OutWinShortCutAction( |
107 |
FILTER_ACTION_ID, "ACTION_FILTER"); //NOI18N |
108 |
private final OutWinShortCutAction largerFont = new OutWinShortCutAction( |
109 |
LARGER_FONT_ACTION_ID, "ACTION_LARGER_FONT"); //NOI18N |
110 |
private final OutWinShortCutAction smallerFont = new OutWinShortCutAction( |
111 |
SMALLER_FONT_ACTION_ID, "ACTION_SMALLER_FONT"); //NOI18N |
112 |
private final OutWinShortCutAction closeWindow = new OutWinShortCutAction( |
113 |
CLOSE_ACTION_ID, "ACTION_CLOSE"); //NOI18N |
114 |
private final OutWinShortCutAction fontType = new OutWinShortCutAction( |
115 |
FONT_TYPE_ACTION_ID, "ACTION_FONT_TYPE"); //NOI18N |
116 |
private final OutWinShortCutAction saveAs = new OutWinShortCutAction( |
117 |
SAVE_AS_ACTION_ID, "ACTION_SAVEAS"); //NOI18N |
118 |
/** |
119 |
* Map of keymaps. Keys are profile names. |
120 |
*/ |
121 |
Map<String, Map<ShortcutAction, Set<String>>> keymaps = |
122 |
new HashMap<String, Map<ShortcutAction, Set<String>>>(); |
123 |
/** |
124 |
* The default keymap. Used if keys for a profile are not set. |
125 |
*/ |
126 |
Map<ShortcutAction, Set<String>> defaultKeymap = |
127 |
new HashMap<ShortcutAction, Set<String>>(); |
128 |
/** |
129 |
* List of all actions. |
130 |
*/ |
131 |
private final Set<OutWinShortCutAction> allActions = |
132 |
new HashSet<OutWinShortCutAction>(); |
133 |
/** |
134 |
* Map of actions of categories. There is only one category in this case. |
135 |
*/ |
136 |
Map<String, Set<ShortcutAction>> actions = |
137 |
new HashMap<String, Set<ShortcutAction>>(); |
138 |
|
139 |
public OutputKeymapManager() { |
140 |
super("OutputWindowKeymapManager"); //NOI18N |
141 |
actions = new HashMap<String, Set<ShortcutAction>>(); |
142 |
Collections.addAll(allActions, wrap, clear, filter, largerFont, |
143 |
smallerFont, closeWindow, fontType, saveAs); |
144 |
Set<ShortcutAction> set = new HashSet<ShortcutAction>(); |
145 |
set.addAll(allActions); |
146 |
actions.put(CATEGORY_NAME, set); |
147 |
fillDefaultKeyMap(); |
148 |
loadShortCuts(); |
149 |
} |
150 |
|
151 |
private void fillDefaultKeyMap() { |
152 |
for (OutWinShortCutAction a : allActions) { |
153 |
String dflt = a.getDefaultShortcut(); |
154 |
defaultKeymap.put(a, (dflt != null && !dflt.isEmpty()) |
155 |
? Collections.singleton(dflt) |
156 |
: Collections.<String>emptySet()); |
157 |
} |
158 |
} |
159 |
|
160 |
@Override |
161 |
public Map<String, Set<ShortcutAction>> getActions() { |
162 |
return actions; |
163 |
} |
164 |
|
165 |
@Override |
166 |
public void refreshActions() { |
167 |
} |
168 |
|
169 |
@Override |
170 |
public Map<ShortcutAction, Set<String>> getKeymap(String profileName) { |
171 |
Map<ShortcutAction, Set<String>> km = keymaps.get(profileName); |
172 |
if (km == null) { |
173 |
km = new HashMap<ShortcutAction, Set<String>>(defaultKeymap); |
174 |
keymaps.put(profileName, km); |
175 |
} |
176 |
return km; |
177 |
} |
178 |
|
179 |
@Override |
180 |
public Map<ShortcutAction, Set<String>> getDefaultKeymap( |
181 |
String profileName) { |
182 |
return defaultKeymap; |
183 |
} |
184 |
|
185 |
@Override |
186 |
public void saveKeymap(String profileName, |
187 |
Map<ShortcutAction, Set<String>> actionToShortcuts) { |
188 |
|
189 |
Map<ShortcutAction, Set<String>> newShortcuts = |
190 |
new HashMap<ShortcutAction, Set<String>>(); |
191 |
keymaps.put(profileName, newShortcuts); |
192 |
for (OutWinShortCutAction owsa : allActions) { |
193 |
Set<String> shortcuts = actionToShortcuts.get(owsa); |
194 |
if (shortcuts == null) { |
195 |
shortcuts = Collections.<String>emptySet(); |
196 |
} |
197 |
newShortcuts.put(owsa, shortcuts); |
198 |
} |
199 |
storeShortCuts(profileName); |
200 |
} |
201 |
|
202 |
@Override |
203 |
public List<String> getProfiles() { |
204 |
return null; |
205 |
} |
206 |
|
207 |
@Override |
208 |
public String getCurrentProfile() { |
209 |
return null; |
210 |
} |
211 |
|
212 |
@Override |
213 |
public void setCurrentProfile(String profileName) { |
214 |
} |
215 |
|
216 |
@Override |
217 |
public void deleteProfile(String profileName) { |
218 |
} |
219 |
|
220 |
@Override |
221 |
public boolean isCustomProfile(String profileName) { |
222 |
return false; |
223 |
} |
224 |
|
225 |
private class OutWinShortCutAction implements ShortcutAction { |
226 |
|
227 |
private String id; |
228 |
private String bundleKey; |
229 |
private String displayName; |
230 |
private String defaultShortcut; |
231 |
|
232 |
public OutWinShortCutAction(String id, String bundleKey) { |
233 |
this.id = id; |
234 |
this.bundleKey = bundleKey; |
235 |
this.displayName = NbBundle.getMessage( |
236 |
NbIOProvider.class, bundleKey); |
237 |
String nbKeysBundleKey = Utilities.isMac() |
238 |
? bundleKey + ".accel.mac" //NOI18N |
239 |
: bundleKey + ".accel"; //NOI18N |
240 |
String nbKeys = NbBundle.getMessage(NbIOProvider.class, |
241 |
nbKeysBundleKey); |
242 |
this.defaultShortcut = nbKeys; |
243 |
} |
244 |
|
245 |
public String getId() { |
246 |
return id; |
247 |
} |
248 |
|
249 |
public String getBundleKey() { |
250 |
return bundleKey; |
251 |
} |
252 |
|
253 |
public String getDisplayName() { |
254 |
return displayName; |
255 |
} |
256 |
|
257 |
public String getDefaultShortcut() { |
258 |
return defaultShortcut; |
259 |
} |
260 |
|
261 |
@Override |
262 |
public String getDelegatingActionId() { |
263 |
return null; |
264 |
} |
265 |
|
266 |
@Override |
267 |
public ShortcutAction getKeymapManagerInstance( |
268 |
String keymapManagerName) { |
269 |
return null; |
270 |
} |
271 |
} |
272 |
|
273 |
private void storeShortCuts(String profileName) { |
274 |
FileObject root = FileUtil.getConfigRoot(); |
275 |
try { |
276 |
FileObject actionsDir = FileUtil.createFolder( |
277 |
root, STORAGE_DIR + profileName); |
278 |
for (OutWinShortCutAction a : allActions) { |
279 |
FileObject data = actionsDir.getFileObject(a.getId()); |
280 |
if (data == null) { |
281 |
data = actionsDir.createData(a.getId()); |
282 |
} else if (data.isFolder()) { |
283 |
throw new IOException(data + " is a folder."); //NOI18N |
284 |
} |
285 |
Enumeration<String> atts = data.getAttributes(); |
286 |
while (atts.hasMoreElements()) { |
287 |
String attName = atts.nextElement(); |
288 |
data.setAttribute(attName, null); |
289 |
} |
290 |
int index = 1; |
291 |
if (keymaps.get(profileName).get(a) == null) { |
292 |
continue; |
293 |
} |
294 |
for (String shortCut : keymaps.get(profileName).get(a)) { |
295 |
data.setAttribute(SHORTCUT_PREFIX + index++, shortCut); |
296 |
} |
297 |
} |
298 |
} catch (IOException e) { |
299 |
LOG.log(Level.WARNING, "Cannot create folder", e); //NOI18N |
300 |
} |
301 |
} |
302 |
|
303 |
private void loadShortCuts() { |
304 |
FileObject root = FileUtil.getConfigRoot(); |
305 |
FileObject actionsDir = root.getFileObject(STORAGE_DIR); |
306 |
if (actionsDir == null) { |
307 |
return; |
308 |
} |
309 |
for (FileObject profileDir : actionsDir.getChildren()) { |
310 |
if (!profileDir.isFolder()) { |
311 |
continue; |
312 |
} |
313 |
Map<ShortcutAction, Set<String>> keymap = |
314 |
new HashMap<ShortcutAction, Set<String>>(); |
315 |
keymaps.put(profileDir.getName(), keymap); |
316 |
for (OutWinShortCutAction a : allActions) { |
317 |
FileObject actionFile = profileDir.getFileObject(a.getId()); |
318 |
if (actionFile == null || !actionFile.isData()) { |
319 |
keymap.put(a, Collections.<String>emptySet()); |
320 |
continue; |
321 |
} |
322 |
Enumeration<String> atts = actionFile.getAttributes(); |
323 |
Set<String> strokes = new HashSet<String>(); |
324 |
while (atts.hasMoreElements()) { |
325 |
String att = atts.nextElement(); |
326 |
if (att.startsWith(SHORTCUT_PREFIX)) { |
327 |
strokes.add((String) actionFile.getAttribute(att)); |
328 |
} |
329 |
} |
330 |
keymap.put(a, strokes); |
331 |
} |
332 |
} |
333 |
} |
334 |
} |