Bug 107436 - [IDE] navigator: show file/folder in "Windows Explorer", Finder, Nautilus Use a platform dependent command to open the external file explorer Signed-off-by: Alexandros Karypidis <akarypid@yahoo.gr> Change-Id: I849baa6c86bef25422b1eebd501693a0640aa768
diff --git a/bundles/org.eclipse.ui.ide/plugin.properties b/bundles/org.eclipse.ui.ide/plugin.properties index 88c04fb..91aecfd 100644 --- a/bundles/org.eclipse.ui.ide/plugin.properties +++ b/bundles/org.eclipse.ui.ide/plugin.properties
@@ -195,6 +195,9 @@ command.showResourceByPath.description= Show a resource in the Navigator given its path commandParameter.showResourceByPath.resourcePath.name= Resource Path +command.showInSystemExplorer.name = Show In (System Explorer) +command.showInSystemExplorer.description = Show in system's explorer (file manager) + KeyBindingActionSet.label = Keyboard Shortcuts KeyBindingActionSet.showKeyAssist.label = &Key Assist...
diff --git a/bundles/org.eclipse.ui.ide/plugin.xml b/bundles/org.eclipse.ui.ide/plugin.xml index 66688ca..eaae206 100644 --- a/bundles/org.eclipse.ui.ide/plugin.xml +++ b/bundles/org.eclipse.ui.ide/plugin.xml
@@ -999,6 +999,12 @@ id="org.eclipse.ui.ide.copyConfigCommand" name="%command.copyConfigCommand.name"> </command> + <command + categoryId="org.eclipse.ui.category.navigate" + name="%command.showInSystemExplorer.name" + id="org.eclipse.ui.ide.showInSystemExplorer" + description="%command.showInSystemExplorer.description"> + </command> </extension> <extension @@ -2034,6 +2040,13 @@ style="push"> </command> </menuContribution> + <menuContribution + locationURI="popup:org.eclipse.ui.menus.showInMenu"> + <command + commandId="org.eclipse.ui.ide.showInSystemExplorer" + style="push"> + </command> + </menuContribution> </extension> <extension point="org.eclipse.ui.handlers"> @@ -2217,6 +2230,18 @@ </iterate> </enabledWhen> </handler> + <handler + class="org.eclipse.ui.internal.ide.handlers.ShowInSystemExplorerHandler" + commandId="org.eclipse.ui.ide.showInSystemExplorer"> + <enabledWhen> + <with variable="selection"> + <count value="1" /> + <iterate ifEmpty="false"> + <adapt type="org.eclipse.core.resources.IResource" /> + </iterate> + </with> + </enabledWhen> + </handler> </extension> <extension point="org.eclipse.core.expressions.propertyTesters">
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEInternalPreferences.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEInternalPreferences.java index 479d2b5..228bd43 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEInternalPreferences.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEInternalPreferences.java
@@ -118,5 +118,12 @@ /** * Workspace name, will be displayed in the window title. */ - public static final String WORKSPACE_NAME = "WORKSPACE_NAME"; //$NON-NLS-1$ + public static final String WORKSPACE_NAME = "WORKSPACE_NAME"; //$NON-NLS-1$ + + /** + * System explore command, used to launch file manager showing selected resource. + */ + public static final String WORKBENCH_SYSTEM_EXPLORER = "SYSTEM_EXPLORER"; //$NON-NLS-1$ + + }
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEPreferenceInitializer.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEPreferenceInitializer.java index 279d539..806f376 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEPreferenceInitializer.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEPreferenceInitializer.java
@@ -17,6 +17,7 @@ import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.internal.ide.handlers.ShowInSystemExplorerHandler; import org.eclipse.ui.internal.views.markers.MarkerSupportInternalUtilities; /** @@ -87,6 +88,8 @@ node.put(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE, IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT); node.put(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_VIRTUAL_FOLDER_MODE, IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT); + + node.put(IDEInternalPreferences.WORKBENCH_SYSTEM_EXPLORER, ShowInSystemExplorerHandler.getDefaultCommand()); } private String getHelpSeparatorKey(String groupId) {
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java index 56041f6..a13bb3c 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java
@@ -513,6 +513,11 @@ public static String IDEWorkspacePreference_openReferencedProjects; public static String IDEWorkspacePreference_closeUnrelatedProjectsToolTip; public static String IDEWorkspacePreference_workspaceName; + public static String IDEWorkbenchPreference_workbenchSystemExplorer; + + public static String ShowInSystemExplorerHandler_LinuxDefaultCommand; + public static String ShowInSystemExplorerHandler_MacOSXDefaultCommand; + public static String ShowInSystemExplorerHandler_Win32DefaultCommand; // --- Linked Resources --- public static String LinkedResourcesPreference_explanation;
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java index 45f370d..957be9d 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkspacePreferencePage.java
@@ -82,6 +82,8 @@ private RadioGroupFieldEditor openReferencesEditor; + private StringFieldEditor systemExplorer; + /* * (non-Javadoc) * @@ -115,6 +117,10 @@ createSpace(composite); createOpenPrefControls(composite); + + createSpace(composite); + createSystemExplorerGroup(composite); + createSpace(composite); Composite lower = new Composite(composite,SWT.NONE); GridLayout lowerLayout = new GridLayout(); @@ -323,6 +329,38 @@ lineSeparatorEditor = new LineDelimiterEditor(lineComposite); lineSeparatorEditor.doLoad(); } + + /** + * Create the widget for the system explorer command. + * + * @param composite + */ + protected void createSystemExplorerGroup(Composite composite) { + Composite groupComposite = new Composite(composite, SWT.LEFT); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + groupComposite.setLayout(layout); + GridData gd = new GridData(); + gd.horizontalAlignment = GridData.FILL; + gd.grabExcessHorizontalSpace = true; + groupComposite.setLayoutData(gd); + + systemExplorer = new StringFieldEditor(IDEInternalPreferences.WORKBENCH_SYSTEM_EXPLORER, + IDEWorkbenchMessages.IDEWorkbenchPreference_workbenchSystemExplorer, 40, groupComposite); + systemExplorer.setPreferenceStore(getIDEPreferenceStore()); + systemExplorer.setPage(this); + + systemExplorer.load(); + + systemExplorer.setPropertyChangeListener(new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(FieldEditor.IS_VALID)) { + setValid(systemExplorer.isValid()); + } + } + }); + } + /** * Returns the IDE preference store. * @return the preference store. @@ -408,6 +446,8 @@ lineSeparatorEditor.loadDefault(); openReferencesEditor.loadDefault(); + systemExplorer.loadDefault(); + super.performDefaults(); } @@ -459,7 +499,9 @@ } workspaceName.store(); - + + systemExplorer.store(); + Preferences preferences = ResourcesPlugin.getPlugin() .getPluginPreferences(); @@ -478,7 +520,8 @@ encodingEditor.store(); lineSeparatorEditor.store(); openReferencesEditor.store(); - return super.performOk(); + + return super.performOk(); } }
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/handlers/ShowInSystemExplorerHandler.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/handlers/ShowInSystemExplorerHandler.java new file mode 100644 index 0000000..87eb6b3 --- /dev/null +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/handlers/ShowInSystemExplorerHandler.java
@@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2013 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ui.internal.ide.handlers; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.common.NotDefinedException; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.internal.ide.IDEInternalPreferences; +import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; +import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; + +/** + * @since 3.106 + */ +public class ShowInSystemExplorerHandler extends AbstractHandler { + + /** + * Command id + */ + public static final String ID = "org.eclipse.ui.showIn.systemExplorer"; //$NON-NLS-1$ + + private static final String VARIABLE_RE = "\\$\\{selected_resource_loc\\}"; //$NON-NLS-1$ + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands. + * ExecutionEvent) + */ + public Object execute(ExecutionEvent event) throws ExecutionException { + ILog log = IDEWorkbenchPlugin.getDefault().getLog(); + + ISelection selection = HandlerUtil.getCurrentSelection(event); + if ((selection == null) || (selection.isEmpty()) + || (!(selection instanceof IStructuredSelection))) { + return null; + } + + Object selectedObject = ((IStructuredSelection) selection) + .getFirstElement(); + IResource item = (IResource) org.eclipse.ui.internal.util.Util + .getAdapter(selectedObject, IResource.class); + if (item == null) { + return null; + } + + String logMsgPrefix; + try { + logMsgPrefix = event.getCommand().getName() + ": "; //$NON-NLS-1$ + } catch (NotDefinedException e) { + // will used id instead... + logMsgPrefix = event.getCommand().getId() + ": "; //$NON-NLS-1$ + } + + try { + String canonicalPath = getSystemExplorerPath(item); + if (canonicalPath == null) { + ErrorDialog + .openError( + Display.getDefault().getActiveShell(), + "Could not determine resource location", //$NON-NLS-1$ + "The system could not determine the selected resource's location.", //$NON-NLS-1$ + new Status( + IStatus.ERROR, + IDEWorkbenchPlugin.getDefault() + .getBundle().getSymbolicName(), + logMsgPrefix + + "Could not determine resource's location.")); //$NON-NLS-1$ + return null; + } + String launchCmd = formShowInSytemExplorerCommand(canonicalPath); + + if ("".equals(launchCmd)) { //$NON-NLS-1$ + ErrorDialog + .openError( + Display.getDefault().getActiveShell(), + "System explorer is not set", //$NON-NLS-1$ + "Please set the system explorer command in the workbench preferences.", //$NON-NLS-1$ + new Status(IStatus.ERROR, IDEWorkbenchPlugin + .getDefault().getBundle() + .getSymbolicName(), logMsgPrefix + + "Command for launching is not set.")); //$NON-NLS-1$ + return null; + } + + log.log(new Status(IStatus.INFO, IDEWorkbenchPlugin.getDefault() + .getBundle().getSymbolicName(), launchCmd)); + + Process p = Runtime.getRuntime().exec(launchCmd, null, + item.getWorkspace().getRoot().getLocation().toFile()); + int retCode = p.waitFor(); + if (retCode != 0) { + log.log(new Status( + IStatus.ERROR, + IDEWorkbenchPlugin.getDefault().getBundle() + .getSymbolicName(), + logMsgPrefix + + "Execution of launch command failed with return code: " + retCode)); //$NON-NLS-1$ + } + } catch (Exception e) { + log.log(new Status(IStatus.ERROR, IDEWorkbenchPlugin.getDefault() + .getBundle().getSymbolicName(), logMsgPrefix + + "Unhandled failure.", e)); //$NON-NLS-1$ + throw new ExecutionException("Show in Explorer command failed.", e); //$NON-NLS-1$ + } + return null; + } + + /** + * Prepare command for launching system explorer to show a path + * + * @param path + * the path to show + * @return the command that shows the path + */ + private String formShowInSytemExplorerCommand(String path) { + String command = IDEWorkbenchPlugin.getDefault().getPreferenceStore() + .getString(IDEInternalPreferences.WORKBENCH_SYSTEM_EXPLORER); + return command.replaceAll(VARIABLE_RE, path); + } + + /** + * Returns the path used for a resource when showing it in the system + * explorer + * + * @see File#getCanonicalPath() + * @param resource + * the {@link IResource} object to be used + * @return the canonical path to show in the system explorer for this + * resource, or null if it cannot be determined + * @throws IOException + * if an I/O error occurs while trying to determine the path + */ + private String getSystemExplorerPath(IResource resource) throws IOException { + IPath location = resource.getLocation(); + if (location == null) + return null; + File f = location.toFile(); + return f.getCanonicalPath(); + } + + /** + * The default command for launching the system explorer on this platform. + * + * @return The default command which launches the system explorer on this + * system, or an empty string if no default exists. + */ + public static String getDefaultCommand() { + if (Util.isGtk()) { + return IDEWorkbenchMessages.ShowInSystemExplorerHandler_LinuxDefaultCommand; + } else if (Util.isWindows()) { + return IDEWorkbenchMessages.ShowInSystemExplorerHandler_Win32DefaultCommand; + } else if (Util.isMac()) { + return IDEWorkbenchMessages.ShowInSystemExplorerHandler_MacOSXDefaultCommand; + } + + // if all else fails, return empty default + return ""; //$NON-NLS-1$ + } +}
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties index f710cc1..cdc9bff 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties
@@ -488,6 +488,11 @@ IDEWorkspacePreference_openReferencedProjects = Open referenced projects when a project is opened IDEWorkspacePreference_closeUnrelatedProjectsToolTip = Close unrelated projects without prompt IDEWorkspacePreference_workspaceName=Wor&kspace name (shown in window title): +IDEWorkbenchPreference_workbenchSystemExplorer=Command for launching system explorer. + +ShowInSystemExplorerHandler_LinuxDefaultCommand=gdbus call -e -d org.freedesktop.FileManager1 -o /org/freedesktop/FileManager1 -m org.freedesktop.FileManager1.ShowItems ['file://${selected_resource_loc}'] '' +ShowInSystemExplorerHandler_Win32DefaultCommand=explorer /E,/select=${selected_resource_loc} +ShowInSystemExplorerHandler_MacOSXDefaultCommand=open -R '${selected_resource_loc}' # --- Linked Resources --- LinkedResourcesPreference_explanation = Path variables specify locations in the file system. The locations of linked resources\nmay be specified relative to these path variables.