diff --git a/platform/configuration-store-impl/src/ExportSettingsAction.kt b/platform/configuration-store-impl/src/ExportSettingsAction.kt index 00911ebf79b4..50058f45943a 100644 --- a/platform/configuration-store-impl/src/ExportSettingsAction.kt +++ b/platform/configuration-store-impl/src/ExportSettingsAction.kt @@ -7,7 +7,7 @@ import com.intellij.configurationStore.schemeManager.ROOT_CONFIG import com.intellij.configurationStore.schemeManager.SchemeManagerFactoryBase import com.intellij.ide.IdeBundle import com.intellij.ide.actions.ImportSettingsFilenameFilter -import com.intellij.ide.actions.ShowFilePathAction +import com.intellij.ide.actions.RevealFileAction import com.intellij.ide.plugins.IdeaPluginDescriptor import com.intellij.ide.plugins.PluginManager import com.intellij.ide.plugins.PluginManagerCore @@ -86,8 +86,8 @@ open class ExportSettingsAction : AnAction(), DumbAware { } exportSettings(saveFile, markedComponents) - ShowFilePathAction.showDialog(getEventProject(e), IdeBundle.message("message.settings.exported.successfully"), - IdeBundle.message("title.export.successful"), saveFile.toFile(), null) + RevealFileAction.showDialog(getEventProject(e), IdeBundle.message("message.settings.exported.successfully"), + IdeBundle.message("title.export.successful"), saveFile.toFile(), null) } catch (e: IOException) { Messages.showErrorDialog(IdeBundle.message("error.writing.settings", e.toString()), IdeBundle.message("title.error.writing.file")) diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInExplorerTarget.java b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInExplorerTarget.java index 1646dc399aff..317e4c428123 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInExplorerTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/ProjectViewSelectInExplorerTarget.java @@ -1,25 +1,10 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.impl; import com.intellij.ide.SelectInContext; import com.intellij.ide.SelectInTarget; import com.intellij.ide.StandardTargetWeights; import com.intellij.ide.actions.RevealFileAction; -import com.intellij.ide.actions.ShowFilePathAction; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.vfs.VirtualFile; @@ -31,15 +16,15 @@ import java.io.File; public class ProjectViewSelectInExplorerTarget implements DumbAware, SelectInTarget { @Override public boolean canSelect(SelectInContext context) { - VirtualFile file = ShowFilePathAction.findLocalFile(context.getVirtualFile()); + VirtualFile file = RevealFileAction.findLocalFile(context.getVirtualFile()); return file != null; } @Override public void selectIn(SelectInContext context, boolean requestFocus) { - VirtualFile file = ShowFilePathAction.findLocalFile(context.getVirtualFile()); + VirtualFile file = RevealFileAction.findLocalFile(context.getVirtualFile()); if (file != null) { - ShowFilePathAction.openFile(new File(file.getPresentableUrl())); + RevealFileAction.openFile(new File(file.getPresentableUrl())); } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/PsiNavigationSupportImpl.java b/platform/lang-impl/src/com/intellij/ide/util/PsiNavigationSupportImpl.java index 91af21cf1c6d..b8232d9b816d 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/PsiNavigationSupportImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/util/PsiNavigationSupportImpl.java @@ -1,7 +1,7 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.util; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.ide.impl.ProjectViewSelectInTarget; import com.intellij.ide.projectView.impl.ProjectViewPane; import com.intellij.openapi.fileEditor.OpenFileDescriptor; @@ -43,6 +43,6 @@ public class PsiNavigationSupportImpl extends PsiNavigationSupport { @Override public void openDirectoryInSystemFileManager(@NotNull File file) { - ShowFilePathAction.openDirectory(file); + RevealFileAction.openDirectory(file); } } diff --git a/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java b/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java index 3b4b63bdb416..9f53a22767f6 100644 --- a/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java +++ b/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java @@ -1,25 +1,11 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.history.core; import com.intellij.history.core.changes.ChangeSet; import com.intellij.history.utils.LocalHistoryLog; import com.intellij.ide.BrowserUtil; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; @@ -146,7 +132,7 @@ public class ChangeListStorageImpl implements ChangeListStorage { } else { File file = new File(logFile); - ShowFilePathAction.openFile(file); + RevealFileAction.openFile(file); } } }), null); diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java index 098e8e7da757..79eb1c7c9ac9 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java @@ -18,7 +18,7 @@ import com.intellij.history.integration.ui.models.RevisionProcessingProgress; import com.intellij.history.utils.LocalHistoryLog; import com.intellij.icons.AllIcons; import com.intellij.ide.actions.ContextHelpAction; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.ide.ui.SplitterProportionsDataImpl; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -436,7 +436,7 @@ public abstract class HistoryDialog extends FrameW myModel.createPatch(p.getFileName(), p.getBaseDirName(), p.isReversePatch(), p.getEncoding()); showNotification(LocalHistoryBundle.message("message.patch.created")); - ShowFilePathAction.openFile(new File(p.getFileName())); + RevealFileAction.openFile(new File(p.getFileName())); } catch (VcsException | IOException e) { showError(message("message.error.during.create.patch", e)); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CollectZippedLogsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CollectZippedLogsAction.java index 0fd932f62332..caf360a16059 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CollectZippedLogsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CollectZippedLogsAction.java @@ -1,4 +1,4 @@ -// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.actions; import com.intellij.ide.troubleshooting.CompositeGeneralTroubleInfoCollector; @@ -44,7 +44,7 @@ public class CollectZippedLogsAction extends AnAction implements DumbAware { if (!doNotShowDialog) { Messages.showIdeaMessageDialog( project, "Included logs and settings may contain sensitive data.", "Sensitive Data", - new String[]{"Show in " + ShowFilePathAction.getFileManagerName()}, 1, Messages.getWarningIcon(), + new String[]{"Show in " + RevealFileAction.getFileManagerName()}, 1, Messages.getWarningIcon(), new DialogWrapper.DoNotAskOption.Adapter() { @Override public void rememberChoice(final boolean selected, final int exitCode) { @@ -62,8 +62,8 @@ public class CollectZippedLogsAction extends AnAction implements DumbAware { return createZip(troubleshooting); } }); - if (ShowFilePathAction.isSupported()) { - ShowFilePathAction.openFile(zippedLogsFile); + if (RevealFileAction.isSupported()) { + RevealFileAction.openFile(zippedLogsFile); } else { Messages.showInfoMessage(zippedLogsFile.getAbsolutePath(), "Log File"); @@ -134,6 +134,6 @@ public class CollectZippedLogsAction extends AnAction implements DumbAware { @NotNull private static String getActionName() { - return "Compress Logs and Show in " + ShowFilePathAction.getFileManagerName(); + return "Compress Logs and Show in " + RevealFileAction.getFileManagerName(); } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/actions/DumpThreadsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/DumpThreadsAction.java index ef88c517ed7a..19f8084e208b 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/DumpThreadsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/DumpThreadsAction.java @@ -34,7 +34,7 @@ public class DumpThreadsAction extends AnAction implements DumbAware { if (file != null) { String url = FileUtil.getUrl(file); String message = CommonBundle.message("thread.dump.is.taken", url); - return GROUP.createNotification("", message, NotificationType.INFORMATION, ShowFilePathAction.FILE_SELECTING_LISTENER); + return GROUP.createNotification("", message, NotificationType.INFORMATION, RevealFileAction.FILE_SELECTING_LISTENER); } else { return GROUP.createNotification(CommonBundle.message("failed.to.take.thread.dump"), NotificationType.INFORMATION); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/RevealFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/RevealFileAction.java index 831408264a60..7d421e91684d 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/RevealFileAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/RevealFileAction.java @@ -1,17 +1,70 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.actions; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.process.CapturingProcessHandler; +import com.intellij.execution.util.ExecUtil; +import com.intellij.ide.IdeBundle; +import com.intellij.idea.ActionsBundle; +import com.intellij.jna.JnaLoader; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAwareAction; -import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.*; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileSystem; +import com.intellij.openapi.vfs.newvfs.ArchiveFileSystem; +import com.intellij.util.SystemProperties; +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinDef; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.io.File; +import javax.swing.event.HyperlinkEvent; +import java.awt.*; +import java.io.*; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Stream; +import static com.intellij.openapi.util.text.StringUtil.defaultIfEmpty; + +/** + * This helpful action opens a file or directory in a system file manager. + * + * @see ShowFilePathAction + */ public class RevealFileAction extends DumbAwareAction { + private static final Logger LOG = Logger.getInstance(RevealFileAction.class); + + public static final NotificationListener FILE_SELECTING_LISTENER = new NotificationListener.Adapter() { + @Override + protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) { + URL url = e.getURL(); + if (url != null) { + try { + openFile(new File(url.toURI())); + } + catch (URISyntaxException ex) { + LOG.warn("invalid URL: " + url, ex); + } + } + notification.expire(); + } + }; public RevealFileAction() { getTemplatePresentation().setText(getActionName()); @@ -19,22 +72,210 @@ public class RevealFileAction extends DumbAwareAction { @Override public void update(@NotNull AnActionEvent e) { - VirtualFile file = ShowFilePathAction.findLocalFile(e.getData(CommonDataKeys.VIRTUAL_FILE)); + VirtualFile file = findLocalFile(e.getData(CommonDataKeys.VIRTUAL_FILE)); Presentation presentation = e.getPresentation(); presentation.setText(getActionName()); presentation.setEnabled(file != null); } - @NotNull - public static String getActionName() { - return SystemInfo.isMac ? "Reveal in Finder" : "Show in " + ShowFilePathAction.getFileManagerName(); - } - @Override public void actionPerformed(@NotNull AnActionEvent e) { - VirtualFile file = ShowFilePathAction.findLocalFile(e.getData(CommonDataKeys.VIRTUAL_FILE)); + VirtualFile file = findLocalFile(e.getData(CommonDataKeys.VIRTUAL_FILE)); if (file != null) { - ShowFilePathAction.openFile(new File(file.getPresentableUrl())); + openFile(new File(file.getPresentableUrl())); } } -} + + public static boolean isSupported() { + return SystemInfo.isWindows || SystemInfo.isMac || SystemInfo.hasXdgOpen() || + Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN); + } + + @NotNull + public static String getActionName() { + return SystemInfo.isMac ? ActionsBundle.message("action.RevealIn.name.mac") : ActionsBundle.message("action.RevealIn.name.other", getFileManagerName()); + } + + @NotNull + public static String getFileManagerName() { + return fileManagerName.getValue(); + } + + @Nullable + public static VirtualFile findLocalFile(@Nullable VirtualFile file) { + if (file == null || file.isInLocalFileSystem()) { + return file; + } + + VirtualFileSystem fs = file.getFileSystem(); + if (fs instanceof ArchiveFileSystem && file.getParent() == null) { + return ((ArchiveFileSystem)fs).getLocalByEntry(file); + } + + return null; + } + + public static void showDialog(Project project, String message, String title, @NotNull File file, @Nullable DialogWrapper.DoNotAskOption option) { + String ok = getActionName(); + String cancel = IdeBundle.message("action.close"); + if (Messages.showOkCancelDialog(project, message, title, ok, cancel, Messages.getInformationIcon(), option) == Messages.OK) { + openFile(file); + } + } + + /** + * Opens a system file manager with given file's parent directory open and the file highlighted in it + * (note that not all platforms support highlighting). + */ + public static void openFile(@NotNull File file) { + if (!file.exists()) { + LOG.info("does not exist: " + file); + return; + } + + File parent = file.getAbsoluteFile().getParentFile(); + if (parent != null) { + doOpen(parent, file); + } + else { + doOpen(file, null); + } + } + + /** + * Opens a system file manager with given directory open in it. + */ + public static void openDirectory(@NotNull File directory) { + if (!directory.isDirectory()) { + LOG.info("not a directory: " + directory); + return; + } + + doOpen(directory.getAbsoluteFile(), null); + } + + private static void doOpen(@NotNull File _dir, @Nullable File _toSelect) { + String dir = FileUtil.toSystemDependentName(FileUtil.toCanonicalPath(_dir.getPath())); + String toSelect = _toSelect != null ? FileUtil.toSystemDependentName(FileUtil.toCanonicalPath(_toSelect.getPath())) : null; + + if (SystemInfo.isWindows) { + spawn(toSelect != null ? "explorer /select,\"" + shortPath(toSelect) + '"' : "explorer /root,\"" + shortPath(dir) + '"'); + } + else if (SystemInfo.isMac) { + if (toSelect != null) { + spawn("open", "-R", toSelect); + } + else { + spawn("open", dir); + } + } + else if (fileManagerApp.getValue() != null) { + spawn(fileManagerApp.getValue(), toSelect != null ? toSelect : dir); + } + else if (SystemInfo.hasXdgOpen()) { + spawn("xdg-open", dir); + } + else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) { + LOG.debug("opening " + dir + " via Desktop API"); + ApplicationManager.getApplication().executeOnPooledThread(() -> { + try { + Desktop.getDesktop().open(new File(dir)); + } + catch (Exception e) { + LOG.warn(e); + } + }); + } + else { + Messages.showErrorDialog("This action isn't supported on the current platform", "Cannot Open File"); + } + } + + private static String shortPath(String path) { + if (path.contains(" ") && JnaLoader.isLoaded()) { + // On the way from Runtime.exec() to CreateProcess(), a command line goes through couple rounds of merging and splitting + // which breaks paths containing a sequence of two or more spaces. + // Conversion to a short format is an ugly hack allowing to open such paths in Explorer. + char[] result = new char[WinDef.MAX_PATH]; + if (Kernel32.INSTANCE.GetShortPathName(path, result, result.length) <= result.length) { + return Native.toString(result); + } + } + + return path; + } + + private static void spawn(String... command) { + LOG.debug(Arrays.toString(command)); + + ApplicationManager.getApplication().executeOnPooledThread(() -> { + try { + CapturingProcessHandler handler; + if (SystemInfo.isWindows) { + Process process = Runtime.getRuntime().exec(command[0]); // no quoting/escaping is needed + handler = new CapturingProcessHandler(process, null, command[0]); + } + else { + handler = new CapturingProcessHandler(new GeneralCommandLine(command)); + } + handler.runProcess(10000, false).checkSuccess(LOG); + } + catch (Exception e) { + LOG.warn(e); + } + }); + } + + private static final NullableLazyValue fileManagerApp = new AtomicNullableLazyValue() { + @Override + protected String compute() { + return readDesktopEntryKey("Exec") + .map(line -> line.split(" ")[0]) + .filter(exec -> exec.endsWith("nautilus") || exec.endsWith("pantheon-files")) + .orElse(null); + } + }; + + private static final NotNullLazyValue fileManagerName = new AtomicNotNullLazyValue() { + @NotNull + @Override + protected String compute() { + if (SystemInfo.isMac) return "Finder"; + if (SystemInfo.isWindows) return "Explorer"; + return readDesktopEntryKey("Name").orElse("File Manager"); + } + }; + + private static Optional readDesktopEntryKey(String key) { + if (SystemInfo.hasXdgMime()) { + String appName = ExecUtil.execAndReadLine(new GeneralCommandLine("xdg-mime", "query", "default", "inode/directory")); + if (appName != null && appName.endsWith(".desktop")) { + return Stream.of(getXdgDataDirectories().split(":")) + .map(dir -> new File(dir, "applications/" + appName)) + .filter(File::exists) + .findFirst() + .map(file -> readDesktopEntryKey(file, key)); + } + } + + return Optional.empty(); + } + + private static String getXdgDataDirectories() { + String dataHome = System.getenv("XDG_DATA_HOME"); + String dataDirs = System.getenv("XDG_DATA_DIRS"); + return defaultIfEmpty(dataHome, SystemProperties.getUserHome() + "/.local/share") + ':' + defaultIfEmpty(dataDirs, "/usr/local/share:/usr/share"); + } + + private static String readDesktopEntryKey(File file, String key) { + LOG.debug("looking for '" + key + "' in " + file); + String prefix = key + '='; + try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { + return reader.lines().filter(l -> l.startsWith(prefix)).map(l -> l.substring(prefix.length())).findFirst().orElse(null); + } + catch (IOException | UncheckedIOException e) { + LOG.info("Cannot read: " + file, e); + return null; + } + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java index b7b7ed7fe4a6..539498955c6f 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowFilePathAction.java @@ -1,140 +1,51 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.actions; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.CapturingProcessHandler; -import com.intellij.execution.util.ExecUtil; import com.intellij.ide.DataManager; -import com.intellij.ide.IdeBundle; import com.intellij.idea.ActionsBundle; -import com.intellij.jna.JnaLoader; -import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; -import com.intellij.openapi.util.*; -import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileSystem; -import com.intellij.openapi.vfs.newvfs.ArchiveFileSystem; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Consumer; -import com.intellij.util.SystemProperties; import com.intellij.util.ui.EmptyIcon; -import com.sun.jna.Native; -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.WinDef; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.HyperlinkEvent; import javax.swing.filechooser.FileSystemView; -import java.awt.*; import java.awt.event.MouseEvent; -import java.io.*; -import java.net.URISyntaxException; -import java.net.URL; -import java.nio.charset.StandardCharsets; +import java.io.File; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - -import static com.intellij.openapi.util.text.StringUtil.defaultIfEmpty; +/** + * A rarely needed action that shows a popup with a path to a file (a list of parent directory names). + * Clicking/hitting enter on a directory opens it in a system file manager. + * + * @see RevealFileAction + */ public class ShowFilePathAction extends DumbAwareAction { - private static final Logger LOG = Logger.getInstance(ShowFilePathAction.class); - - public static final NotificationListener FILE_SELECTING_LISTENER = new NotificationListener.Adapter() { - @Override - protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) { - URL url = e.getURL(); - if (url != null) { - try { - openFile(new File(url.toURI())); - } - catch (URISyntaxException ex) { - LOG.warn("invalid URL: " + url, ex); - } - } - notification.expire(); - } - }; - - private static final NullableLazyValue fileManagerApp = new AtomicNullableLazyValue() { - @Override - protected String compute() { - return readDesktopEntryKey("Exec") - .map(line -> line.split(" ")[0]) - .filter(exec -> exec.endsWith("nautilus") || exec.endsWith("pantheon-files")) - .orElse(null); - } - }; - - private static final NotNullLazyValue fileManagerName = new AtomicNotNullLazyValue() { - @NotNull - @Override - protected String compute() { - if (SystemInfo.isMac) return "Finder"; - if (SystemInfo.isWindows) return "Explorer"; - return readDesktopEntryKey("Name").orElse("File Manager"); - } - }; - - private static Optional readDesktopEntryKey(String key) { - if (SystemInfo.hasXdgMime()) { - String appName = ExecUtil.execAndReadLine(new GeneralCommandLine("xdg-mime", "query", "default", "inode/directory")); - if (appName != null && appName.endsWith(".desktop")) { - return Stream.of(getXdgDataDirectories().split(":")) - .map(dir -> new File(dir, "applications/" + appName)) - .filter(File::exists) - .findFirst() - .map(file -> readDesktopEntryKey(file, key)); - } - } - - return Optional.empty(); - } - - private static String getXdgDataDirectories() { - String dataHome = System.getenv("XDG_DATA_HOME"); - String dataDirs = System.getenv("XDG_DATA_DIRS"); - return defaultIfEmpty(dataHome, SystemProperties.getUserHome() + "/.local/share") + ':' + defaultIfEmpty(dataDirs, "/usr/local/share:/usr/share"); - } - - private static String readDesktopEntryKey(File file, String key) { - LOG.debug("looking for '" + key + "' in " + file); - String prefix = key + '='; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { - return reader.lines().filter(l -> l.startsWith(prefix)).map(l -> l.substring(prefix.length())).findFirst().orElse(null); - } - catch (IOException | UncheckedIOException e) { - LOG.info("Cannot read: " + file, e); - return null; - } - } - @Override public void update(@NotNull AnActionEvent e) { - boolean visible = !SystemInfo.isMac && isSupported(); + boolean visible = !SystemInfo.isMac && RevealFileAction.isSupported(); e.getPresentation().setVisible(visible); if (visible) { VirtualFile file = getFile(e); e.getPresentation().setEnabled(file != null); - e.getPresentation().setText(ActionsBundle.message("action.ShowFilePath.tuned", file != null && file.isDirectory() ? 1 : 0)); + e.getPresentation().setText(ActionsBundle.message(file != null && file.isDirectory() ? "action.ShowFilePath.directory" : "action.ShowFilePath.file")); } } @@ -166,7 +77,7 @@ public class ShowFilePathAction extends DumbAwareAction { } private static void show(@NotNull VirtualFile file, @NotNull Consumer action) { - if (!isSupported()) return; + if (!RevealFileAction.isSupported()) return; List files = new ArrayList<>(); List fileUrls = new ArrayList<>(); @@ -202,15 +113,15 @@ public class ShowFilePathAction extends DumbAwareAction { BaseListPopupStep step = new BaseListPopupStep(RevealFileAction.getActionName(), files, icons) { @NotNull @Override - public String getTextFor(final VirtualFile value) { + public String getTextFor(VirtualFile value) { return value.getPresentableName(); } @Override - public PopupStep onChosen(final VirtualFile selectedValue, final boolean finalChoice) { - final File selectedFile = new File(getPresentableUrl(selectedValue)); + public PopupStep onChosen(VirtualFile selectedValue, boolean finalChoice) { + File selectedFile = new File(getPresentableUrl(selectedValue)); if (selectedFile.exists()) { - ApplicationManager.getApplication().executeOnPooledThread(() -> openFile(selectedFile)); + ApplicationManager.getApplication().executeOnPooledThread(() -> RevealFileAction.openFile(selectedFile)); } return FINAL_CHOICE; } @@ -219,142 +130,52 @@ public class ShowFilePathAction extends DumbAwareAction { return JBPopupFactory.getInstance().createListPopup(step); } + // + /** @deprecated use {@link RevealFileAction#FILE_SELECTING_LISTENER} (to be removed in IDEA 2021.3) */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2021.3") + public static final NotificationListener FILE_SELECTING_LISTENER = RevealFileAction.FILE_SELECTING_LISTENER; + + /** @deprecated use {@link RevealFileAction#isSupported} (to be removed in IDEA 2021.3) */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2021.3") public static boolean isSupported() { - return SystemInfo.isWindows || SystemInfo.isMac || SystemInfo.hasXdgOpen() || - Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN); + return RevealFileAction.isSupported(); } - @NotNull - public static String getFileManagerName() { - return fileManagerName.getValue(); + /** @deprecated use {@link RevealFileAction#getFileManagerName} (to be removed in IDEA 2021.3) */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2021.3") + public static @NotNull String getFileManagerName() { + return RevealFileAction.getFileManagerName(); } - /** - * Shows system file manager with given file's parent directory open and the file highlighted in it
- * (note that not all platforms support highlighting). - * - * @param file a file or directory to show and highlight in a file manager. - */ + /** @deprecated use {@link RevealFileAction#openFile} (to be removed in IDEA 2021.3) */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2021.3") public static void openFile(@NotNull File file) { - if (!file.exists()) { - LOG.info("does not exist: " + file); - return; - } - - File parent = file.getAbsoluteFile().getParentFile(); - if (parent != null) { - doOpen(parent, file); - } - else { - doOpen(file, null); - } + RevealFileAction.openFile(file); } - /** - * Shows system file manager with given directory open in it. - * - * @param directory a directory to open in a file manager. - */ + /** @deprecated use {@link RevealFileAction#openDirectory} (to be removed in IDEA 2021.3) */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2021.3") public static void openDirectory(@NotNull File directory) { - if (!directory.isDirectory()) { - LOG.info("not a directory: " + directory); - return; - } - - doOpen(directory.getAbsoluteFile(), null); - } - - private static void doOpen(@NotNull File _dir, @Nullable File _toSelect) { - String dir = FileUtil.toSystemDependentName(FileUtil.toCanonicalPath(_dir.getPath())); - String toSelect = _toSelect != null ? FileUtil.toSystemDependentName(FileUtil.toCanonicalPath(_toSelect.getPath())) : null; - - if (SystemInfo.isWindows) { - spawn(toSelect != null ? "explorer /select,\"" + shortPath(toSelect) + '"' : "explorer /root,\"" + shortPath(dir) + '"'); - } - else if (SystemInfo.isMac) { - if (toSelect != null) { - spawn("open", "-R", toSelect); - } - else { - spawn("open", dir); - } - } - else if (fileManagerApp.getValue() != null) { - spawn(fileManagerApp.getValue(), toSelect != null ? toSelect : dir); - } - else if (SystemInfo.hasXdgOpen()) { - spawn("xdg-open", dir); - } - else if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) { - LOG.debug("opening " + dir + " via Desktop API"); - ApplicationManager.getApplication().executeOnPooledThread(() -> { - try { - Desktop.getDesktop().open(new File(dir)); - } - catch (Exception e) { - LOG.warn(e); - } - }); - } - else { - Messages.showErrorDialog("This action isn't supported on the current platform", "Cannot Open File"); - } - } - - private static String shortPath(String path) { - if (path.contains(" ") && JnaLoader.isLoaded()) { - // On the way from Runtime.exec() to CreateProcess(), a command line goes through couple rounds of merging and splitting - // which breaks paths containing a sequence of two or more spaces. - // Conversion to a short format is an ugly hack allowing to open such paths in Explorer. - char[] result = new char[WinDef.MAX_PATH]; - if (Kernel32.INSTANCE.GetShortPathName(path, result, result.length) <= result.length) { - return Native.toString(result); - } - } - - return path; - } - - private static void spawn(String... command) { - LOG.debug(Arrays.toString(command)); - - ApplicationManager.getApplication().executeOnPooledThread(() -> { - try { - CapturingProcessHandler handler; - if (SystemInfo.isWindows) { - Process process = Runtime.getRuntime().exec(command[0]); // no quoting/escaping is needed - handler = new CapturingProcessHandler(process, null, command[0]); - } - else { - handler = new CapturingProcessHandler(new GeneralCommandLine(command)); - } - handler.runProcess(10000, false).checkSuccess(LOG); - } - catch (Exception e) { - LOG.warn(e); - } - }); + RevealFileAction.openDirectory(directory); } + /** @deprecated use {@link RevealFileAction#showDialog} (to be removed in IDEA 2021.3) */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2021.3") public static void showDialog(Project project, String message, String title, @NotNull File file, @Nullable DialogWrapper.DoNotAskOption option) { - String ok = RevealFileAction.getActionName(); - String cancel = IdeBundle.message("action.close"); - if (Messages.showOkCancelDialog(project, message, title, ok, cancel, Messages.getInformationIcon(), option) == Messages.OK) { - openFile(file); - } + RevealFileAction.showDialog(project, message, title, file, option); } - @Nullable - public static VirtualFile findLocalFile(@Nullable VirtualFile file) { - if (file == null || file.isInLocalFileSystem()) { - return file; - } - - VirtualFileSystem fs = file.getFileSystem(); - if (fs instanceof ArchiveFileSystem && file.getParent() == null) { - return ((ArchiveFileSystem)fs).getLocalByEntry(file); - } - - return null; + /** @deprecated use {@link RevealFileAction#findLocalFile} (to be removed in IDEA 2021.3) */ + @Deprecated + @ApiStatus.ScheduledForRemoval(inVersion = "2021.3") + public static @Nullable VirtualFile findLocalFile(@Nullable VirtualFile file) { + return RevealFileAction.findLocalFile(file); } + //
} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowLogAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowLogAction.java index d3f74e71bc67..af4a7ec5bdbe 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowLogAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowLogAction.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.actions; import com.intellij.openapi.actionSystem.AnAction; @@ -35,18 +21,18 @@ public class ShowLogAction extends AnAction implements DumbAware { @Override public void actionPerformed(@NotNull AnActionEvent e) { final File logFile = new File(PathManager.getLogPath(), "idea.log"); - ShowFilePathAction.openFile(logFile); + RevealFileAction.openFile(logFile); } @Override public void update(@NotNull AnActionEvent e) { Presentation presentation = e.getPresentation(); - presentation.setVisible(ShowFilePathAction.isSupported()); + presentation.setVisible(RevealFileAction.isSupported()); presentation.setText(getActionName()); } @NotNull public static String getActionName() { - return "Show Log in " + ShowFilePathAction.getFileManagerName(); + return "Show Log in " + RevealFileAction.getFileManagerName(); } } diff --git a/platform/platform-impl/src/com/intellij/internal/cachedValueProfiler/DumpCachedValueProfilerInfoAction.java b/platform/platform-impl/src/com/intellij/internal/cachedValueProfiler/DumpCachedValueProfilerInfoAction.java index ec94c03c407e..7b943a928f0d 100644 --- a/platform/platform-impl/src/com/intellij/internal/cachedValueProfiler/DumpCachedValueProfilerInfoAction.java +++ b/platform/platform-impl/src/com/intellij/internal/cachedValueProfiler/DumpCachedValueProfilerInfoAction.java @@ -2,7 +2,7 @@ package com.intellij.internal.cachedValueProfiler; import com.intellij.CommonBundle; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationGroup; import com.intellij.notification.NotificationType; @@ -31,8 +31,8 @@ public class DumpCachedValueProfilerInfoAction extends DumbAwareAction { try { File file = CachedValueProfilerDumper.dumpResults(new File(PathManager.getLogPath())); String url = FileUtil.getUrl(file); - String message = CommonBundle.message("cached.value.snapshot.success", file, url, ShowFilePathAction.getFileManagerName()); - GROUP.createNotification("", message, NotificationType.INFORMATION, ShowFilePathAction.FILE_SELECTING_LISTENER).notify(project); + String message = CommonBundle.message("cached.value.snapshot.success", file, url, RevealFileAction.getFileManagerName()); + GROUP.createNotification("", message, NotificationType.INFORMATION, RevealFileAction.FILE_SELECTING_LISTENER).notify(project); } catch (IOException exception) { GROUP.createNotification(CommonBundle.message("cached.value.snapshot.error", exception.getMessage()), diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java index 02baac0d39d8..c07c432a7e7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/NativeFileWatcherImpl.java @@ -3,7 +3,7 @@ package com.intellij.openapi.vfs.impl.local; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.process.ProcessOutputTypes; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.notification.NotificationListener; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationBundle; @@ -80,7 +80,7 @@ public class NativeFileWatcherImpl extends PluggableFileWatcher { } else if (!myExecutable.canExecute()) { String message = ApplicationBundle.message("watcher.exe.not.exe", myExecutable); - notifyOnFailure(message, (notification, event) -> ShowFilePathAction.openFile(myExecutable)); + notifyOnFailure(message, (notification, event) -> RevealFileAction.openFile(myExecutable)); } else { try { diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 168a3c7a6f08..3662b3bed706 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -419,7 +419,8 @@ action.FileStructurePopup.text=F_ile Structure action.FileStructurePopup.description=Popup structure of the current file for quick navigation action.ShowFilePath.text=File _Path action.ShowFilePath.description=Popup path of the current file for opening in external file manager -action.ShowFilePath.tuned={0,choice,0#File|1#Directory} _Path +action.ShowFilePath.file=SFile _Path +action.ShowFilePath.directory=Directory _Path action.SelectIn.text=Se_lect In... action.SelectIn.description=Select the current class or method in any view action.FixDocComment.text=Fix doc comment @@ -1576,6 +1577,8 @@ action.Console.History.Next.description=Next entry in console history action.Console.History.Browse.text=Browse Console History action.Console.History.Browse.description=Browse console history action.RevealIn.description=Highlights the file in platform's file manager +action.RevealIn.name.mac=Reveal in Finder +action.RevealIn.name.other=Show in {0} action.GoToLinkTarget.text=Go to Link Target action.GoToLinkTarget.description=Opens a target of this symlink in the Project View diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java index 598897450ba5..98cbf949928b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java @@ -2,7 +2,7 @@ package com.intellij.openapi.vcs.changes.patch; import com.intellij.CommonBundle; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; @@ -153,7 +153,7 @@ public class CreatePatchCommitExecutor extends LocalCommitExecutor implements Pr WaitForProgressToShow.runOrInvokeLaterAboveProgress(() -> { final VcsConfiguration configuration = VcsConfiguration.getInstance(myProject); if (Boolean.TRUE.equals(configuration.SHOW_PATCH_IN_EXPLORER)) { - ShowFilePathAction.openFile(file); + RevealFileAction.openFile(file); } else if (configuration.SHOW_PATCH_IN_EXPLORER == null) { configuration.SHOW_PATCH_IN_EXPLORER = showDialog(file); @@ -232,7 +232,7 @@ public class CreatePatchCommitExecutor extends LocalCommitExecutor implements Pr } }; - ShowFilePathAction.showDialog(myProject, message, title, file, option); + RevealFileAction.showDialog(myProject, message, title, file, option); return ref[0]; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java index 465ef28f3611..e558f5d55779 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsGeneralConfigurationPanel.java @@ -1,7 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.vcs.configurable; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; @@ -57,7 +57,7 @@ public class VcsGeneralConfigurationPanel { myProject = project; myOnPatchCreationLabel.setText(VcsBundle.message("combobox.show.patch.in.explorer.after.creation", - ShowFilePathAction.getFileManagerName())); + RevealFileAction.getFileManagerName())); myOnFileAddingGroup = new JRadioButton[]{ myShowDialogOnAddingFile, @@ -92,7 +92,7 @@ public class VcsGeneralConfigurationPanel { myPromptsPanel.setSize(myPromptsPanel.getPreferredSize()); // todo check text! myOnPatchCreation.setName((SystemInfo.isMac ? "Reveal patch in" : "Show patch in ") + - ShowFilePathAction.getFileManagerName() + " after creation:"); + RevealFileAction.getFileManagerName() + " after creation:"); } public void apply() { diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/GradleVersionQuickFix.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/GradleVersionQuickFix.kt index 09e4bd2e812b..36916eeed016 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/GradleVersionQuickFix.kt +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/issue/quickfix/GradleVersionQuickFix.kt @@ -4,7 +4,7 @@ package org.jetbrains.plugins.gradle.issue.quickfix import com.intellij.build.SyncViewManager import com.intellij.build.issue.BuildIssueQuickFix import com.intellij.execution.executors.DefaultRunExecutor -import com.intellij.ide.actions.ShowFilePathAction +import com.intellij.ide.actions.RevealFileAction import com.intellij.ide.actions.ShowLogAction import com.intellij.openapi.application.PathManager import com.intellij.openapi.diagnostic.logger @@ -60,7 +60,7 @@ class GradleVersionQuickFix(private val projectPath: String, .apply { isBalloonNotification = true balloonGroup = "Gradle Import" - setListener("#open_log") { _, _ -> ShowFilePathAction.openFile(File(PathManager.getLogPath(), "idea.log")) } + setListener("#open_log") { _, _ -> RevealFileAction.openFile(File(PathManager.getLogPath(), "idea.log")) } } ExternalSystemNotificationManager.getInstance(project).showNotification(GradleConstants.SYSTEM_ID, notification) throw it diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenTestConsoleFilter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenTestConsoleFilter.java index acedc4518a3f..be82edba89c9 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenTestConsoleFilter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenTestConsoleFilter.java @@ -1,23 +1,9 @@ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * Licensed 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.idea.maven.project; import com.intellij.execution.filters.Filter; import com.intellij.execution.filters.HyperlinkInfo; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -46,7 +32,7 @@ public class MavenTestConsoleFilter implements Filter { public void navigate(Project project) { File f = new File(path); if (f.isDirectory()) { - ShowFilePathAction.openDirectory(f); + RevealFileAction.openDirectory(f); } } }); diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/action/RevealFileInTerminalAction.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/action/RevealFileInTerminalAction.java index 18e7d092bc36..7eb62a30bd6f 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/action/RevealFileInTerminalAction.java +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/action/RevealFileInTerminalAction.java @@ -1,21 +1,7 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed 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. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.plugins.terminal.action; -import com.intellij.ide.actions.ShowFilePathAction; +import com.intellij.ide.actions.RevealFileAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.project.DumbAwareAction; @@ -37,7 +23,7 @@ public class RevealFileInTerminalAction extends DumbAwareAction { @Nullable private static VirtualFile getSelectedFile(@NotNull AnActionEvent e) { - return ShowFilePathAction.findLocalFile(e.getData(CommonDataKeys.VIRTUAL_FILE)); + return RevealFileAction.findLocalFile(e.getData(CommonDataKeys.VIRTUAL_FILE)); } @Override