Skip to content

Commit 03eaec4

Browse files
committed
Add open containing folder action.
1 parent 6a9d501 commit 03eaec4

File tree

5 files changed

+332
-128
lines changed

5 files changed

+332
-128
lines changed

platform/core.ui/nbproject/project.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# under the License.
1717

1818
javac.compilerargs=-Xlint:unchecked
19-
javac.source=1.8
19+
javac.source=11
2020
javadoc.arch=${basedir}/arch.xml
2121

2222
test.config.stableBTD.includes=**/*Test.class
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.netbeans.core.ui.sysopen;
20+
21+
import java.awt.Desktop;
22+
import java.awt.event.ActionEvent;
23+
import java.io.File;
24+
import java.io.IOException;
25+
import java.util.HashSet;
26+
import java.util.Set;
27+
import java.util.logging.Level;
28+
import java.util.logging.Logger;
29+
import javax.swing.AbstractAction;
30+
import javax.swing.Action;
31+
import org.openide.awt.ActionID;
32+
import org.openide.awt.ActionReference;
33+
import org.openide.awt.ActionReferences;
34+
import org.openide.awt.ActionRegistration;
35+
import org.openide.awt.DynamicMenuContent;
36+
import org.openide.filesystems.FileUtil;
37+
import org.openide.loaders.DataObject;
38+
import org.openide.util.ContextAwareAction;
39+
import org.openide.util.Lookup;
40+
import org.openide.util.LookupListener;
41+
import org.openide.util.NbBundle;
42+
import org.openide.util.RequestProcessor;
43+
import org.openide.util.Utilities;
44+
import org.openide.util.WeakListeners;
45+
46+
/**
47+
* Open the selected file(s) with the system default tool.
48+
* @author Jesse Glick
49+
*/
50+
public abstract /*sealed*/ class AbstractSystemOpenAction extends AbstractAction implements ContextAwareAction {
51+
52+
private static final RequestProcessor PROC = new RequestProcessor(AbstractSystemOpenAction.class);
53+
54+
private final boolean openParent;
55+
protected final Set<File> files;
56+
57+
protected AbstractSystemOpenAction(String name, Lookup context, boolean parent) {
58+
super(name);
59+
files = new HashSet<>();
60+
openParent = parent;
61+
putValue(DynamicMenuContent.HIDE_WHEN_DISABLED, true);
62+
Lookup.Result<DataObject> result = context.lookupResult(DataObject.class);
63+
result.addLookupListener(WeakListeners.create(LookupListener.class, e -> updateFileSet(result), result));
64+
updateFileSet(result);
65+
}
66+
67+
@Override
68+
public void actionPerformed(ActionEvent e) {
69+
PROC.post(() -> { // #176879: asynch
70+
Desktop desktop = Desktop.getDesktop();
71+
for (File f : files) {
72+
try {
73+
desktop.open(openParent ? f.getParentFile() : f);
74+
} catch (IOException x) {
75+
Logger.getLogger(getClass().getName()).log(Level.INFO, null, x);
76+
// XXX or perhaps notify user of problem; but not very useful on Unix at least (#6940853)
77+
}
78+
}
79+
});
80+
}
81+
82+
@Override
83+
public boolean isEnabled() {
84+
return Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN);
85+
}
86+
87+
private void updateFileSet(Lookup.Result<DataObject> result) {
88+
files.clear();
89+
for (DataObject d : result.allInstances()) {
90+
File f = FileUtil.toFile(d.getPrimaryFile());
91+
if (f != null && !isIgnoredFile(f)) {
92+
files.add(f);
93+
}
94+
}
95+
}
96+
97+
private boolean isIgnoredFile(File f) {
98+
if (Utilities.isWindows() && f.isFile() && !f.getName().contains(".")) {
99+
/* #144575 */
100+
return true;
101+
}
102+
if (f.getName().endsWith(".shadow")) {
103+
return true;
104+
}
105+
return false;
106+
}
107+
108+
@ActionID(id = "org.netbeans.core.ui.sysopen.SystemOpenAction", category = "Edit")
109+
@ActionRegistration(displayName = "#CTL_SystemOpenAction", lazy = false)
110+
@ActionReferences ({
111+
@ActionReference(path = "Editors/TabActions", position = 401),
112+
@ActionReference(path = "UI/ToolActions/Files", position = 2045),
113+
@ActionReference(path = "Projects/Actions", position = 101),
114+
@ActionReference(path = "Shortcuts", name = "SO-S")
115+
})
116+
public final static class SystemOpenAction extends AbstractSystemOpenAction {
117+
118+
public SystemOpenAction() {
119+
this(Utilities.actionsGlobalContext());
120+
}
121+
122+
public SystemOpenAction(Lookup context) {
123+
super(NbBundle.getMessage(AbstractSystemOpenAction.class, "CTL_SystemOpenAction"), context, false);
124+
}
125+
126+
@Override
127+
public Action createContextAwareInstance(Lookup context) {
128+
return new SystemOpenAction(context);
129+
}
130+
131+
@Override
132+
public boolean isEnabled() {
133+
return !files.isEmpty() && super.isEnabled();
134+
}
135+
}
136+
137+
@ActionID(id = "org.netbeans.core.ui.sysopen.SystemOpenParentAction", category = "Edit")
138+
@ActionRegistration(displayName = "#CTL_SystemOpenParentAction", lazy = false)
139+
@ActionReferences ({
140+
@ActionReference(path = "Editors/TabActions", position = 402),
141+
@ActionReference(path = "UI/ToolActions/Files", position = 2046),
142+
@ActionReference(path = "Projects/Actions", position = 102)
143+
})
144+
public final static class SystemOpenParentAction extends AbstractSystemOpenAction {
145+
146+
public SystemOpenParentAction() {
147+
this(Utilities.actionsGlobalContext());
148+
}
149+
150+
public SystemOpenParentAction(Lookup context) {
151+
super(NbBundle.getMessage(AbstractSystemOpenAction.class, "CTL_SystemOpenParentAction"), context, true);
152+
}
153+
154+
@Override
155+
public Action createContextAwareInstance(Lookup context) {
156+
return new SystemOpenParentAction(context);
157+
}
158+
159+
@Override
160+
public boolean isEnabled() {
161+
return files.size() == 1 && files.iterator().next().getParent() != null && super.isEnabled();
162+
}
163+
}
164+
165+
}

platform/core.ui/src/org/netbeans/core/ui/sysopen/Bundle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
# under the License.
1717

1818
CTL_SystemOpenAction=Open in System
19+
CTL_SystemOpenParentAction=Open Parent in System

platform/core.ui/src/org/netbeans/core/ui/sysopen/SystemOpenAction.java

Lines changed: 0 additions & 127 deletions
This file was deleted.

0 commit comments

Comments
 (0)