diff --git a/platform/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties b/platform/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties index 67d980400859..89a205979778 100644 --- a/platform/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties +++ b/platform/applemenu/src/org/netbeans/modules/applemenu/Bundle.properties @@ -26,6 +26,3 @@ OpenIDE-Module-Long-Description=Enables Apple menu items to work properly, \ Toolbars/QuickSearch=&Quick Search - -CTL_ShowInFinder=Show In Finder -TXT_NoLocalFile=Cannot find selected file. diff --git a/platform/applemenu/src/org/netbeans/modules/applemenu/ShowInFinder.java b/platform/applemenu/src/org/netbeans/modules/applemenu/ShowInFinder.java deleted file mode 100644 index ee4ad67d8793..000000000000 --- a/platform/applemenu/src/org/netbeans/modules/applemenu/ShowInFinder.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.netbeans.modules.applemenu; - -import java.awt.event.ActionListener; -import java.awt.event.ActionEvent; -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.openide.loaders.DataObject; - -import org.openide.awt.ActionRegistration; -import org.openide.awt.ActionReference; -import org.openide.awt.ActionReferences; -import org.openide.awt.ActionID; -import org.openide.awt.StatusDisplayer; -import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileUtil; -import org.openide.util.NbBundle; -import org.openide.util.RequestProcessor; - -/** - * - * @author Tomas Zezula - */ -@ActionID(category = "Tools", -id = "org.netbeans.modules.applemenu.ShowInFinder") -@ActionRegistration(displayName = "#CTL_ShowInFinder") -@ActionReferences({ - @ActionReference(path = "UI/ToolActions/Files", position = 1001) -}) -public final class ShowInFinder implements ActionListener { - - private static final Logger LOG = Logger.getLogger(ShowInFinder.class.getName()); - - private final DataObject context; - - private static final RequestProcessor RP = new RequestProcessor( "ShowInFinder", 1 ); - - public ShowInFinder(DataObject context) { - this.context = context; - } - - @Override - public void actionPerformed(ActionEvent ev) { - RP.execute(new Runnable() { - @Override - public void run() { - FileObject fobj = context.getPrimaryFile(); - if (fobj == null) { - return; - } - LOG.log(Level.FINE, "Selected file: {0}", FileUtil.getFileDisplayName(fobj)); //NOI18N - if (FileUtil.getArchiveFile(fobj)!=null) { - fobj = FileUtil.getArchiveFile(fobj); - } - LOG.log(Level.FINE, "File to select in Finder: {0}", FileUtil.getFileDisplayName(fobj)); //NOI18N - final File file = FileUtil.toFile(fobj); - if (file == null) { - LOG.log(Level.INFO, "Ignoring non local file: {0}", FileUtil.getFileDisplayName(fobj)); //NOI18N - StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage(ShowInFinder.class, "TXT_NoLocalFile")); //NOI18N - return; - } - try { - final Class fmClz = Class.forName("com.apple.eio.FileManager"); //NOI18N - final Method m = fmClz.getDeclaredMethod("revealInFinder", File.class); //NOI18N - m.invoke(null, file); - } catch (ClassNotFoundException e) { - LOG.log(Level.FINE, "Cannot load com.apple.eio.FileManager class."); //NOI18N - } catch (NoSuchMethodException e) { - LOG.log(Level.FINE, "No method revealInFinder(java.io.File) in the com.apple.eio.FileManager class."); //NOI18N - } catch (InvocationTargetException e) { - LOG.log(Level.FINE, "Cannot invoke method com.apple.eio.FileManager.revealInFinder(java.io.File)."); //NOI18N - } catch (IllegalAccessException e) { - LOG.log(Level.FINE, "The method com.apple.eio.FileManager.revealInFinder(java.io.File) is not accessible"); //NOI18N - } - } - }); - } -} diff --git a/platform/core.ui/src/org/netbeans/core/ui/sysopen/Bundle.properties b/platform/core.ui/src/org/netbeans/core/ui/sysopen/Bundle.properties index d33f167a2d8d..d1fc95c81886 100644 --- a/platform/core.ui/src/org/netbeans/core/ui/sysopen/Bundle.properties +++ b/platform/core.ui/src/org/netbeans/core/ui/sysopen/Bundle.properties @@ -16,3 +16,4 @@ # under the License. CTL_SystemOpenAction=Open in System +CTL_SystemLocateAction=Locate in System diff --git a/platform/core.ui/src/org/netbeans/core/ui/sysopen/SystemLocateAction.java b/platform/core.ui/src/org/netbeans/core/ui/sysopen/SystemLocateAction.java new file mode 100644 index 000000000000..9dedc5b84c7f --- /dev/null +++ b/platform/core.ui/src/org/netbeans/core/ui/sysopen/SystemLocateAction.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.core.ui.sysopen; + +import java.awt.Desktop; +import java.awt.event.ActionEvent; +import java.util.Collection; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.AbstractAction; +import javax.swing.Action; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.awt.ActionRegistration; +import org.openide.awt.DynamicMenuContent; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.loaders.DataObject; +import org.openide.util.ContextAwareAction; +import org.openide.util.Lookup; +import org.openide.util.LookupListener; +import org.openide.util.NbBundle; +import org.openide.util.RequestProcessor; +import org.openide.util.Utilities; +import org.openide.util.WeakListeners; + +/** + * Open the selected file(s) with the system default tool. + * + * @author Jesse Glick + */ +@ActionID(id = "org.netbeans.core.ui.sysopen.SystemLocateAction", category = "Edit") +@ActionRegistration(displayName = "#CTL_SystemLocateAction", lazy = false) +@ActionReferences({ + @ActionReference(path = "Editors/TabActions", position = 402), + @ActionReference(path = "UI/ToolActions/Files", position = 2046), + @ActionReference(path = "Projects/Actions", position = 102), + @ActionReference(path = "Shortcuts", name = "DO-S") +}) +public final class SystemLocateAction extends AbstractAction implements ContextAwareAction { + + private static final RequestProcessor PROC = new RequestProcessor(SystemLocateAction.class); + + private final Lookup.Result result; + private final LookupListener resultListener; + + private FileObject file; + + public SystemLocateAction() { + this(Utilities.actionsGlobalContext()); + } + + private SystemLocateAction(Lookup context) { + super(NbBundle.getMessage(SystemLocateAction.class, "CTL_SystemLocateAction")); + putValue(DynamicMenuContent.HIDE_WHEN_DISABLED, true); + result = context.lookupResult(DataObject.class); + resultListener = e -> updateFile(); + result.addLookupListener(WeakListeners.create(LookupListener.class, resultListener, result)); + updateFile(); + } + + @Override + public void actionPerformed(ActionEvent e) { + FileObject fo = file; + if (fo == null) { + return; + } + PROC.post(() -> { // #176879: asynch + Desktop desktop = Desktop.getDesktop(); + try { + if (desktop.isSupported(Desktop.Action.BROWSE_FILE_DIR)) { + desktop.browseFileDirectory(FileUtil.toFile(fo)); + } else { + desktop.open(FileUtil.toFile(fo.getParent())); + } + } catch (Exception x) { + Logger.getLogger(SystemLocateAction.class.getName()).log(Level.INFO, null, x); + // XXX or perhaps notify user of problem; but not very useful on Unix at least (#6940853) + } + }); + } + + @Override + public Action createContextAwareInstance(Lookup context) { + return new SystemLocateAction(context); + } + + @Override + public boolean isEnabled() { + return file != null && Desktop.isDesktopSupported() + && (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE_FILE_DIR) + || Desktop.getDesktop().isSupported(Desktop.Action.OPEN)); + } + + private void updateFile() { + Collection dobs = result.allInstances(); + if (dobs.size() == 1) { + FileObject fo = dobs.iterator().next().getPrimaryFile(); + if (fo.isData()) { + this.file = fo; + } else { + this.file = null; + } + } else { + file = null; + } + } + +}