| /******************************************************************************* |
| * Copyright (c) 2003, 2010 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.ide; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.IResourceStatus; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.resources.mapping.IModelProviderDescriptor; |
| import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; |
| import org.eclipse.core.resources.mapping.ModelProvider; |
| import org.eclipse.core.resources.mapping.ModelStatus; |
| import org.eclipse.core.resources.mapping.ResourceChangeValidator; |
| import org.eclipse.core.resources.mapping.ResourceMapping; |
| import org.eclipse.core.resources.mapping.ResourceMappingContext; |
| import org.eclipse.core.resources.mapping.ResourceTraversal; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IAdapterFactory; |
| import org.eclipse.core.runtime.IAdapterManager; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.QualifiedName; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.content.IContentDescription; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.core.runtime.content.IContentTypeMatcher; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.util.SafeRunnable; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorDescriptor; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorReference; |
| import org.eclipse.ui.IEditorRegistry; |
| import org.eclipse.ui.IMarkerHelpRegistry; |
| import org.eclipse.ui.ISaveableFilter; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.MultiPartInitException; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.Saveable; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; |
| import org.eclipse.ui.internal.ide.model.StandardPropertiesAdapterFactory; |
| import org.eclipse.ui.internal.ide.model.WorkbenchAdapterFactory; |
| import org.eclipse.ui.internal.ide.registry.MarkerHelpRegistry; |
| import org.eclipse.ui.internal.ide.registry.MarkerHelpRegistryReader; |
| import org.eclipse.ui.internal.misc.UIStats; |
| import org.eclipse.ui.part.FileEditorInput; |
| |
| /** |
| * Collection of IDE-specific APIs factored out of existing workbench. This |
| * class cannot be instantiated; all functionality is provided by static methods |
| * and fields. |
| * |
| * @since 3.0 |
| */ |
| public final class IDE { |
| /** |
| * The persistent property key used on IFile resources to contain the |
| * preferred editor ID to use. |
| * <p> |
| * Example of retrieving the persisted editor id: |
| * |
| * <pre><code> |
| * IFile file = ... |
| * IEditorDescriptor editorDesc = null; |
| * try { |
| * String editorID = file.getPersistentProperty(EDITOR_KEY); |
| * if (editorID != null) { |
| * editorDesc = editorReg.findEditor(editorID); |
| * } |
| * } catch (CoreException e) { |
| * // handle problem accessing persistent property here |
| * } |
| * </code></pre> |
| * |
| * </p> |
| * <p> |
| * Example of persisting the editor id: |
| * |
| * <pre><code> |
| * IFile file = ... |
| * try { |
| * file.setPersistentProperty(EDITOR_KEY, editorDesc.getId()); |
| * } catch (CoreException e) { |
| * // handle problem setting persistent property here |
| * } |
| * </code></pre> |
| * |
| * </p> |
| */ |
| public static final QualifiedName EDITOR_KEY = new QualifiedName( |
| "org.eclipse.ui.internal.registry.ResourceEditorRegistry", "EditorProperty");//$NON-NLS-2$//$NON-NLS-1$ |
| |
| /** |
| * An optional attribute within a workspace marker (<code>IMarker</code>) |
| * which identifies the preferred editor type to be opened. |
| */ |
| public static final String EDITOR_ID_ATTR = "org.eclipse.ui.editorID"; //$NON-NLS-1$ |
| |
| /** |
| * The resource based perspective identifier. |
| */ |
| public static final String RESOURCE_PERSPECTIVE_ID = "org.eclipse.ui.resourcePerspective"; //$NON-NLS-1$ |
| |
| /** |
| * Marker help registry mapping markers to help context ids and resolutions; |
| * lazily initialized on fist access. |
| */ |
| private static MarkerHelpRegistry markerHelpRegistry = null; |
| |
| /** |
| * Standard shared images defined by the IDE. These are over and above the |
| * standard workbench images declared in {@link org.eclipse.ui.ISharedImages |
| * ISharedImages}. |
| * <p> |
| * This interface is not intended to be implemented by clients. |
| * </p> |
| * |
| * @see org.eclipse.ui.ISharedImages |
| */ |
| public interface SharedImages { |
| /** |
| * Identifies a project image. |
| */ |
| public final static String IMG_OBJ_PROJECT = "IMG_OBJ_PROJECT"; //$NON-NLS-1$ |
| |
| /** |
| * Identifies a closed project image. |
| */ |
| public final static String IMG_OBJ_PROJECT_CLOSED = "IMG_OBJ_PROJECT_CLOSED"; //$NON-NLS-1$ |
| |
| /** |
| * Identifies the image used for "open marker". |
| */ |
| public final static String IMG_OPEN_MARKER = "IMG_OPEN_MARKER"; //$NON-NLS-1$ |
| |
| /** |
| * Identifies the default image used to indicate a task. |
| */ |
| public final static String IMG_OBJS_TASK_TSK = "IMG_OBJS_TASK_TSK"; //$NON-NLS-1$ |
| |
| /** |
| * Identifies the default image used to indicate a bookmark. |
| */ |
| public final static String IMG_OBJS_BKMRK_TSK = "IMG_OBJS_BKMRK_TSK"; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Preferences defined by the IDE workbench. |
| * <p> |
| * This interface is not intended to be implemented by clients. |
| * </p> |
| */ |
| public interface Preferences { |
| |
| /** |
| * A named preference for how a new perspective should be opened when a |
| * new project is created. |
| * <p> |
| * Value is of type <code>String</code>. The possible values are |
| * defined by the constants |
| * <code>OPEN_PERSPECTIVE_WINDOW, OPEN_PERSPECTIVE_PAGE, |
| * OPEN_PERSPECTIVE_REPLACE, and NO_NEW_PERSPECTIVE</code>. |
| * </p> |
| * |
| * @see org.eclipse.ui.IWorkbenchPreferenceConstants#OPEN_PERSPECTIVE_WINDOW |
| * @see org.eclipse.ui.IWorkbenchPreferenceConstants#OPEN_PERSPECTIVE_PAGE |
| * @see org.eclipse.ui.IWorkbenchPreferenceConstants#OPEN_PERSPECTIVE_REPLACE |
| * @see org.eclipse.ui.IWorkbenchPreferenceConstants#NO_NEW_PERSPECTIVE |
| */ |
| public static final String PROJECT_OPEN_NEW_PERSPECTIVE = "PROJECT_OPEN_NEW_PERSPECTIVE"; //$NON-NLS-1$ |
| |
| /** |
| * <p> |
| * Specifies whether or not the workspace selection dialog should be |
| * shown on startup. |
| * </p> |
| * <p> |
| * The default value for this preference is <code>true</code>. |
| * </p> |
| * |
| * @since 3.1 |
| */ |
| public static final String SHOW_WORKSPACE_SELECTION_DIALOG = "SHOW_WORKSPACE_SELECTION_DIALOG"; //$NON-NLS-1$ |
| |
| /** |
| * <p> |
| * Stores the maximum number of workspaces that should be displayed in |
| * the ChooseWorkspaceDialog. |
| * </p> |
| * |
| * @since 3.1 |
| */ |
| public static final String MAX_RECENT_WORKSPACES = "MAX_RECENT_WORKSPACES"; //$NON-NLS-1$ |
| |
| /** |
| * <p> |
| * Stores a comma separated list of the recently used workspace paths. |
| * </p> |
| * |
| * @since 3.1 |
| */ |
| public static final String RECENT_WORKSPACES = "RECENT_WORKSPACES"; //$NON-NLS-1$ |
| |
| /** |
| * <p> |
| * Stores the version of the protocol used to decode/encode the list of |
| * recent workspaces. |
| * </p> |
| * |
| * @since 3.1 |
| */ |
| public static final String RECENT_WORKSPACES_PROTOCOL = "RECENT_WORKSPACES_PROTOCOL"; //$NON-NLS-1$ |
| |
| } |
| |
| /** |
| * A saveable filter that selects savables that contain resources that |
| * are descendants of the roots of the filter. |
| * @since 3.3 |
| * |
| */ |
| private static class SaveFilter implements ISaveableFilter { |
| private final IResource[] roots; |
| |
| /** |
| * Create the filter |
| * @param roots the save roots |
| */ |
| public SaveFilter(IResource[] roots) { |
| this.roots = roots; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.ISaveableFilter#select(org.eclipse.ui.Saveable, org.eclipse.ui.IWorkbenchPart[]) |
| */ |
| public boolean select(Saveable saveable, |
| IWorkbenchPart[] containingParts) { |
| if (isDescendantOfRoots(saveable)) { |
| return true; |
| } |
| // For backwards compatibility, we need to check the parts |
| for (int i = 0; i < containingParts.length; i++) { |
| IWorkbenchPart workbenchPart = containingParts[i]; |
| if (workbenchPart instanceof IEditorPart) { |
| IEditorPart editorPart = (IEditorPart) workbenchPart; |
| if (isEditingDescendantOf(editorPart)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Return whether the given saveable contains any resources that |
| * are descendants of the root resources. |
| * @param saveable the saveable |
| * @return whether the given saveable contains any resources that |
| * are descendants of the root resources |
| */ |
| private boolean isDescendantOfRoots(Saveable saveable) { |
| // First, try and adapt the saveable to a resource mapping. |
| ResourceMapping mapping = ResourceUtil.getResourceMapping(saveable); |
| if (mapping != null) { |
| try { |
| ResourceTraversal[] traversals = mapping.getTraversals( |
| ResourceMappingContext.LOCAL_CONTEXT, null); |
| for (int i = 0; i < traversals.length; i++) { |
| ResourceTraversal traversal = traversals[i]; |
| IResource[] resources = traversal.getResources(); |
| for (int j = 0; j < resources.length; j++) { |
| IResource resource = resources[j]; |
| if (isDescendantOfRoots(resource)) { |
| return true; |
| } |
| } |
| } |
| } catch (CoreException e) { |
| IDEWorkbenchPlugin |
| .log( |
| NLS |
| .bind( |
| "An internal error occurred while determining the resources for {0}", saveable.getName()), e); //$NON-NLS-1$ |
| } |
| } else { |
| // If there is no mapping, try to adapt to a resource or file directly |
| IFile file = ResourceUtil.getFile(saveable); |
| if (file != null) { |
| return isDescendantOfRoots(file); |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Return whether the given resource is either equal to or a descendant of |
| * one of the given roots. |
| * |
| * @param resource the resource to be tested |
| * @return whether the given resource is either equal to or a descendant of |
| * one of the given roots |
| */ |
| private boolean isDescendantOfRoots(IResource resource) { |
| for (int l = 0; l < roots.length; l++) { |
| IResource root = roots[l]; |
| if (root.getFullPath().isPrefixOf(resource.getFullPath())) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Return whether the given dirty editor part is editing resources that are |
| * descendants of the given roots. |
| * |
| * @param part the dirty editor part |
| * @return whether the given dirty editor part is editing resources that are |
| * descendants of the given roots |
| */ |
| private boolean isEditingDescendantOf(IEditorPart part) { |
| IFile file = ResourceUtil.getFile(part.getEditorInput()); |
| if (file != null) { |
| return isDescendantOfRoots(file); |
| } |
| return false; |
| } |
| |
| } |
| |
| /** |
| * Block instantiation. |
| */ |
| private IDE() { |
| // do nothing |
| } |
| |
| /** |
| * Returns the marker help registry for the workbench. |
| * |
| * @return the marker help registry |
| */ |
| public static IMarkerHelpRegistry getMarkerHelpRegistry() { |
| if (markerHelpRegistry == null) { |
| markerHelpRegistry = new MarkerHelpRegistry(); |
| new MarkerHelpRegistryReader().addHelp(markerHelpRegistry); |
| } |
| return markerHelpRegistry; |
| } |
| |
| /** |
| * Sets the cursor and selection state for the given editor to reveal the |
| * position of the given marker. This is done on a best effort basis. If the |
| * editor does not provide an <code>IGotoMarker</code> interface (either |
| * directly or via <code>IAdaptable.getAdapter</code>), this has no |
| * effect. |
| * |
| * @param editor |
| * the editor |
| * @param marker |
| * the marker |
| */ |
| public static void gotoMarker(IEditorPart editor, IMarker marker) { |
| IGotoMarker gotoMarker = null; |
| if (editor instanceof IGotoMarker) { |
| gotoMarker = (IGotoMarker) editor; |
| } else { |
| gotoMarker = (IGotoMarker) editor.getAdapter(IGotoMarker.class); |
| } |
| if (gotoMarker != null) { |
| gotoMarker.gotoMarker(marker); |
| } |
| } |
| |
| /** |
| * Opens an editor on the given object. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. |
| * <p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param input |
| * the editor input |
| * @param editorId |
| * the id of the editor extension to use |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String) |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, |
| IEditorInput input, String editorId) throws PartInitException { |
| // sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // open the editor on the file |
| return page.openEditor(input, editorId); |
| } |
| |
| /** |
| * Opens an editor on the given IFileStore object. |
| * <p> |
| * Unlike the other <code>openEditor</code> methods, this one can be used |
| * to open files that reside outside the workspace resource set. |
| * </p> |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. |
| * </p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param uri |
| * the URI of the file store representing the file to open |
| * @param editorId |
| * the id of the editor extension to use |
| * @param activate |
| * if <code>true</code> the editor will be activated opened |
| * @return an open editor or <code>null</code> if an external editor was |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String) |
| * @see EFS#getStore(URI) |
| * |
| * @since 3.3 |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, URI uri, |
| String editorId, boolean activate) throws PartInitException { |
| // sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| IFileStore fileStore; |
| try { |
| fileStore = EFS.getStore(uri); |
| } catch (CoreException e) { |
| throw new PartInitException( |
| IDEWorkbenchMessages.IDE_coreExceptionFileStore, e); |
| } |
| |
| IEditorInput input = getEditorInput(fileStore); |
| |
| // open the editor on the file |
| return page.openEditor(input, editorId, activate); |
| } |
| |
| /** |
| * Create the Editor Input appropriate for the given <code>IFileStore</code>. |
| * The result is a normal file editor input if the file exists in the |
| * workspace and, if not, we create a wrapper capable of managing an |
| * 'external' file using its <code>IFileStore</code>. |
| * |
| * @param fileStore |
| * The file store to provide the editor input for |
| * @return The editor input associated with the given file store |
| * @since 3.3 |
| */ |
| private static IEditorInput getEditorInput(IFileStore fileStore) { |
| IFile workspaceFile = getWorkspaceFile(fileStore); |
| if (workspaceFile != null) |
| return new FileEditorInput(workspaceFile); |
| return new FileStoreEditorInput(fileStore); |
| } |
| |
| /** |
| * Determine whether or not the <code>IFileStore</code> represents a file |
| * currently in the workspace. |
| * |
| * @param fileStore |
| * The <code>IFileStore</code> to test |
| * @return The workspace's <code>IFile</code> if it exists or |
| * <code>null</code> if not |
| */ |
| private static IFile getWorkspaceFile(IFileStore fileStore) { |
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
| IFile[] files = root.findFilesForLocationURI(fileStore.toURI()); |
| files = filterNonExistentFiles(files); |
| if (files == null || files.length == 0) |
| return null; |
| |
| // for now only return the first file |
| return files[0]; |
| } |
| |
| /** |
| * Filter the incoming array of <code>IFile</code> elements by removing |
| * any that do not currently exist in the workspace. |
| * |
| * @param files |
| * The array of <code>IFile</code> elements |
| * @return The filtered array |
| */ |
| private static IFile[] filterNonExistentFiles(IFile[] files) { |
| if (files == null) |
| return null; |
| |
| int length = files.length; |
| ArrayList existentFiles = new ArrayList(length); |
| for (int i = 0; i < length; i++) { |
| if (files[i].exists()) |
| existentFiles.add(files[i]); |
| } |
| return (IFile[]) existentFiles.toArray(new IFile[existentFiles.size()]); |
| } |
| |
| /** |
| * Opens an editor on the given object. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. If |
| * <code>activate == true</code> the editor will be activated. |
| * <p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param input |
| * the editor input |
| * @param editorId |
| * the id of the editor extension to use |
| * @param activate |
| * if <code>true</code> the editor will be activated |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String, |
| * boolean) |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, |
| IEditorInput input, String editorId, boolean activate) |
| throws PartInitException { |
| // sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // open the editor on the file |
| return page.openEditor(input, editorId, activate); |
| } |
| |
| /** |
| * Opens an editor on the given file resource. This method will attempt to |
| * resolve the editor based on content-type bindings as well as traditional |
| * name/extension bindings. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. If |
| * <code>activate == true</code> the editor will be activated. |
| * <p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param input |
| * the editor input |
| * @param activate |
| * if <code>true</code> the editor will be activated |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(org.eclipse.ui.IEditorInput, |
| * String, boolean) |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, IFile input, |
| boolean activate) throws PartInitException { |
| return openEditor(page, input, activate, true); |
| } |
| |
| /** |
| * Opens an editor on the given file resource. This method will attempt to |
| * resolve the editor based on content-type bindings as well as traditional |
| * name/extension bindings if <code>determineContentType</code> is |
| * <code>true</code>. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. If |
| * <code>activate == true</code> the editor will be activated. |
| * <p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param input |
| * the editor input |
| * @param activate |
| * if <code>true</code> the editor will be activated |
| * @param determineContentType |
| * attempt to resolve the content type for this file |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(org.eclipse.ui.IEditorInput, |
| * String, boolean) |
| * @since 3.1 |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, IFile input, |
| boolean activate, boolean determineContentType) |
| throws PartInitException { |
| // sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // open the editor on the file |
| IEditorDescriptor editorDesc = getEditorDescriptor(input, |
| determineContentType); |
| return page.openEditor(new FileEditorInput(input), editorDesc.getId(), |
| activate); |
| } |
| |
| /** |
| * Opens an editor on the given file resource. This method will attempt to |
| * resolve the editor based on content-type bindings as well as traditional |
| * name/extension bindings. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. |
| * <p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param input |
| * the editor input |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String) |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, IFile input) |
| throws PartInitException { |
| // sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // open the editor on the file |
| IEditorDescriptor editorDesc = getEditorDescriptor(input); |
| return page.openEditor(new FileEditorInput(input), editorDesc.getId()); |
| } |
| |
| /** |
| * Opens an editor on the given file resource. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. |
| * <p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param input |
| * the editor input |
| * @param editorId |
| * the id of the editor extension to use |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String) |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, IFile input, |
| String editorId) throws PartInitException { |
| // sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // open the editor on the file |
| return page.openEditor(new FileEditorInput(input), editorId); |
| } |
| |
| /** |
| * Opens an editor on the given file resource. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. If |
| * <code>activate == true</code> the editor will be activated. |
| * <p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param input |
| * the editor input |
| * @param editorId |
| * the id of the editor extension to use |
| * @param activate |
| * if <code>true</code> the editor will be activated |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String, |
| * boolean) |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, IFile input, |
| String editorId, boolean activate) throws PartInitException { |
| // sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // open the editor on the file |
| return page.openEditor(new FileEditorInput(input), editorId, activate); |
| } |
| |
| /** |
| * Returns an editor descriptor appropriate for opening the given file |
| * resource. |
| * <p> |
| * The editor descriptor is determined using a multi-step process. This |
| * method will attempt to resolve the editor based on content-type bindings |
| * as well as traditional name/extension bindings. |
| * </p> |
| * <ol> |
| * <li>The file is consulted for a persistent property named |
| * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be |
| * used.</li> |
| * <li>The workbench editor registry is consulted to determine if an editor |
| * extension has been registered for the file type. If so, an instance of |
| * the editor extension is opened on the file. See |
| * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li> |
| * <li>The operating system is consulted to determine if an in-place |
| * component editor is available (e.g. OLE editor on Win32 platforms).</li> |
| * <li>The operating system is consulted to determine if an external editor |
| * is available.</li> |
| * </ol> |
| * </p> |
| * |
| * @param file |
| * the file |
| * @return an editor descriptor, appropriate for opening the file |
| * @throws PartInitException |
| * if no editor can be found |
| */ |
| public static IEditorDescriptor getEditorDescriptor(IFile file) |
| throws PartInitException { |
| return getEditorDescriptor(file, true); |
| } |
| |
| /** |
| * Returns an editor descriptor appropriate for opening the given file |
| * resource. |
| * <p> |
| * The editor descriptor is determined using a multi-step process. This |
| * method will attempt to resolve the editor based on content-type bindings |
| * as well as traditional name/extension bindings if |
| * <code>determineContentType</code>is <code>true</code>. |
| * </p> |
| * <ol> |
| * <li>The file is consulted for a persistent property named |
| * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be |
| * used.</li> |
| * <li>The workbench editor registry is consulted to determine if an editor |
| * extension has been registered for the file type. If so, an instance of |
| * the editor extension is opened on the file. See |
| * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li> |
| * <li>The operating system is consulted to determine if an in-place |
| * component editor is available (e.g. OLE editor on Win32 platforms).</li> |
| * <li>The operating system is consulted to determine if an external editor |
| * is available.</li> |
| * </ol> |
| * </p> |
| * |
| * @param file |
| * the file |
| * @param determineContentType |
| * query the content type system for the content type of the file |
| * @return an editor descriptor, appropriate for opening the file |
| * @throws PartInitException |
| * if no editor can be found |
| * @since 3.1 |
| */ |
| public static IEditorDescriptor getEditorDescriptor(IFile file, |
| boolean determineContentType) throws PartInitException { |
| |
| if (file == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| return getEditorDescriptor(file.getName(), PlatformUI.getWorkbench() |
| .getEditorRegistry(), getDefaultEditor(file, |
| determineContentType)); |
| } |
| |
| /** |
| * Returns an editor id appropriate for opening the given file |
| * store. |
| * <p> |
| * The editor descriptor is determined using a multi-step process. This |
| * method will attempt to resolve the editor based on content-type bindings |
| * as well as traditional name/extension bindings. |
| * </p> |
| * <ol> |
| * <li>The workbench editor registry is consulted to determine if an editor |
| * extension has been registered for the file type. If so, an instance of |
| * the editor extension is opened on the file. See |
| * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li> |
| * <li>The operating system is consulted to determine if an in-place |
| * component editor is available (e.g. OLE editor on Win32 platforms).</li> |
| * <li>The operating system is consulted to determine if an external editor |
| * is available.</li> |
| * </ol> |
| * </p> |
| * |
| * @param fileStore |
| * the file store |
| * @return the id of an editor, appropriate for opening the file |
| * @throws PartInitException |
| * if no editor can be found |
| */ |
| private static String getEditorId(IFileStore fileStore) throws PartInitException { |
| String name = fileStore.fetchInfo().getName(); |
| if (name == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| IContentType contentType= null; |
| try { |
| InputStream is = null; |
| try { |
| is = fileStore.openInputStream(EFS.NONE, null); |
| contentType= Platform.getContentTypeManager().findContentTypeFor(is, name); |
| } finally { |
| if (is != null) { |
| is.close(); |
| } |
| } |
| } catch (CoreException ex) { |
| // continue without content type |
| } catch (IOException ex) { |
| // continue without content type |
| } |
| |
| IEditorRegistry editorReg= PlatformUI.getWorkbench().getEditorRegistry(); |
| |
| return getEditorDescriptor(name, editorReg, editorReg.getDefaultEditor(name, contentType)).getId(); |
| } |
| |
| /** |
| * Returns an editor descriptor appropriate for opening a file resource with |
| * the given name. |
| * <p> |
| * The editor descriptor is determined using a multi-step process. This |
| * method will attempt to infer content type from the file name. |
| * </p> |
| * <ol> |
| * <li>The file is consulted for a persistent property named |
| * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be |
| * used.</li> |
| * <li>The workbench editor registry is consulted to determine if an editor |
| * extension has been registered for the file type. If so, an instance of |
| * the editor extension is opened on the file. See |
| * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li> |
| * <li>The operating system is consulted to determine if an in-place |
| * component editor is available (e.g. OLE editor on Win32 platforms).</li> |
| * <li>The operating system is consulted to determine if an external editor |
| * is available.</li> |
| * </ol> |
| * </p> |
| * |
| * @param name |
| * the file name |
| * @return an editor descriptor, appropriate for opening the file |
| * @throws PartInitException |
| * if no editor can be found |
| * @since 3.1 |
| */ |
| public static IEditorDescriptor getEditorDescriptor(String name) |
| throws PartInitException { |
| return getEditorDescriptor(name, true); |
| } |
| |
| /** |
| * Returns an editor descriptor appropriate for opening a file resource with |
| * the given name. |
| * <p> |
| * The editor descriptor is determined using a multi-step process. This |
| * method will attempt to infer the content type of the file if |
| * <code>inferContentType</code> is <code>true</code>. |
| * </p> |
| * <ol> |
| * <li>The file is consulted for a persistent property named |
| * <code>IDE.EDITOR_KEY</code> containing the preferred editor id to be |
| * used.</li> |
| * <li>The workbench editor registry is consulted to determine if an editor |
| * extension has been registered for the file type. If so, an instance of |
| * the editor extension is opened on the file. See |
| * <code>IEditorRegistry.getDefaultEditor(String)</code>.</li> |
| * <li>The operating system is consulted to determine if an in-place |
| * component editor is available (e.g. OLE editor on Win32 platforms).</li> |
| * <li>The operating system is consulted to determine if an external editor |
| * is available.</li> |
| * </ol> |
| * </p> |
| * |
| * @param name |
| * the file name |
| * @param inferContentType |
| * attempt to infer the content type from the file name if this |
| * is <code>true</code> |
| * @return an editor descriptor, appropriate for opening the file |
| * @throws PartInitException |
| * if no editor can be found |
| * @since 3.1 |
| */ |
| public static IEditorDescriptor getEditorDescriptor(String name, |
| boolean inferContentType) throws PartInitException { |
| |
| if (name == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| IContentType contentType = inferContentType ? Platform |
| .getContentTypeManager().findContentTypeFor(name) : null; |
| IEditorRegistry editorReg = PlatformUI.getWorkbench() |
| .getEditorRegistry(); |
| |
| return getEditorDescriptor(name, editorReg, editorReg.getDefaultEditor( |
| name, contentType)); |
| } |
| |
| /** |
| * Get the editor descriptor for a given name using the editorDescriptor |
| * passed in as a default as a starting point. |
| * |
| * @param name |
| * The name of the element to open. |
| * @param editorReg |
| * The editor registry to do the lookups from. |
| * @param defaultDescriptor |
| * IEditorDescriptor or <code>null</code> |
| * @return IEditorDescriptor |
| * @throws PartInitException |
| * if no valid editor can be found |
| * |
| * @since 3.1 |
| */ |
| private static IEditorDescriptor getEditorDescriptor(String name, |
| IEditorRegistry editorReg, IEditorDescriptor defaultDescriptor) |
| throws PartInitException { |
| |
| if (defaultDescriptor != null) { |
| return defaultDescriptor; |
| } |
| |
| IEditorDescriptor editorDesc = defaultDescriptor; |
| |
| // next check the OS for in-place editor (OLE on Win32) |
| if (editorReg.isSystemInPlaceEditorAvailable(name)) { |
| editorDesc = editorReg |
| .findEditor(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID); |
| } |
| |
| // next check with the OS for an external editor |
| if (editorDesc == null |
| && editorReg.isSystemExternalEditorAvailable(name)) { |
| editorDesc = editorReg |
| .findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID); |
| } |
| |
| // next lookup the default text editor |
| if (editorDesc == null) { |
| editorDesc = editorReg |
| .findEditor(IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID); |
| } |
| |
| // if no valid editor found, bail out |
| if (editorDesc == null) { |
| throw new PartInitException( |
| IDEWorkbenchMessages.IDE_noFileEditorFound); |
| } |
| |
| return editorDesc; |
| } |
| |
| /** |
| * Opens an editor on the file resource of the given marker. |
| * <p> |
| * If this page already has an editor open on the marker resource file that |
| * editor is brought to front; otherwise, a new editor is opened.The cursor |
| * and selection state of the editor are then updated from information |
| * recorded in the marker. |
| * </p> |
| * <p> |
| * If the marker contains an <code>EDITOR_ID_ATTR</code> attribute the |
| * attribute value will be used to determine the editor type to be opened. |
| * If not, the registered editor for the marker resource file will be used. |
| * </p> |
| * |
| * @param page |
| * the workbench page to open the editor in |
| * @param marker |
| * the marker to open |
| * @return an open editor or <code>null</code> not possible |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see #openEditor(org.eclipse.ui.IWorkbenchPage, |
| * org.eclipse.core.resources.IMarker, boolean) |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, IMarker marker) |
| throws PartInitException { |
| return openEditor(page, marker, true); |
| } |
| |
| /** |
| * Opens an editor on the file resource of the given marker. |
| * <p> |
| * If this page already has an editor open on the marker resource file that |
| * editor is brought to front; otherwise, a new editor is opened. If |
| * <code>activate == true</code> the editor will be activated. The cursor |
| * and selection state of the editor are then updated from information |
| * recorded in the marker. |
| * </p> |
| * <p> |
| * If the marker contains an <code>EDITOR_ID_ATTR</code> attribute the |
| * attribute value will be used to determine the editor type to be opened. |
| * If not, the registered editor for the marker resource file will be used. |
| * </p> |
| * |
| * @param page |
| * the workbench page to open the editor in |
| * @param marker |
| * the marker to open |
| * @param activate |
| * if <code>true</code> the editor will be activated |
| * @return an open editor or <code>null</code> not possible |
| * @exception PartInitException |
| * if the editor could not be initialized |
| */ |
| public static IEditorPart openEditor(IWorkbenchPage page, IMarker marker, |
| boolean activate) throws PartInitException { |
| // sanity checks |
| if (page == null || marker == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| // get the marker resource file |
| if (!(marker.getResource() instanceof IFile)) { |
| IDEWorkbenchPlugin |
| .log("Open editor on marker failed; marker resource not an IFile"); //$NON-NLS-1$ |
| return null; |
| } |
| IFile file = (IFile) marker.getResource(); |
| |
| // get the preferred editor id from the marker |
| IEditorRegistry editorReg = PlatformUI.getWorkbench() |
| .getEditorRegistry(); |
| IEditorDescriptor editorDesc = null; |
| try { |
| String editorID = (String) marker.getAttribute(EDITOR_ID_ATTR); |
| if (editorID != null) { |
| editorDesc = editorReg.findEditor(editorID); |
| } |
| } catch (CoreException e) { |
| // ignore this |
| } |
| |
| // open the editor on the marker resource file |
| IEditorPart editor = null; |
| if (editorDesc == null) { |
| editor = openEditor(page, file, activate); |
| } else { |
| editor = page.openEditor(new FileEditorInput(file), editorDesc |
| .getId(), activate); |
| } |
| |
| // get the editor to update its position based on the marker |
| if (editor != null) { |
| gotoMarker(editor, marker); |
| } |
| |
| return editor; |
| } |
| |
| /** |
| * Opens an editor on the given IFileStore object. |
| * <p> |
| * Unlike the other <code>openEditor</code> methods, this one |
| * can be used to open files that reside outside the workspace |
| * resource set. |
| * </p> |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. |
| * </p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param fileStore |
| * the IFileStore representing the file to open |
| * @return an open editor or <code>null</code> if an external editor was opened |
| * @exception PartInitException |
| * if the editor could not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String) |
| * @since 3.3 |
| */ |
| public static IEditorPart openEditorOnFileStore(IWorkbenchPage page, IFileStore fileStore) throws PartInitException { |
| //sanity checks |
| if (page == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| IEditorInput input = getEditorInput(fileStore); |
| String editorId = getEditorId(fileStore); |
| |
| // open the editor on the file |
| return page.openEditor(input, editorId); |
| } |
| |
| /** |
| * Opens an internal editor on the given IFileStore object. |
| * <p> |
| * Unlike the other <code>openEditor</code> methods, this one can be used to |
| * open files that reside outside the workspace resource set. |
| * </p> |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. |
| * </p> |
| * |
| * @param page |
| * the page in which the editor will be opened |
| * @param fileStore |
| * the IFileStore representing the file to open |
| * @return an open editor or <code>null</code> if an external editor was |
| * opened |
| * @exception PartInitException |
| * if no internal editor can be found or if the editor could |
| * not be initialized |
| * @see org.eclipse.ui.IWorkbenchPage#openEditor(IEditorInput, String) |
| * @since 3.6 |
| */ |
| public static IEditorPart openInternalEditorOnFileStore(IWorkbenchPage page, IFileStore fileStore) throws PartInitException { |
| if (page == null) |
| throw new IllegalArgumentException(); |
| if (fileStore == null) |
| throw new IllegalArgumentException(); |
| |
| IEditorInput input = getEditorInput(fileStore); |
| String name = fileStore.fetchInfo().getName(); |
| if (name == null) |
| throw new IllegalArgumentException(); |
| |
| IContentType[] contentTypes = null; |
| InputStream is = null; |
| try { |
| is = fileStore.openInputStream(EFS.NONE, null); |
| contentTypes = Platform.getContentTypeManager().findContentTypesFor(is, name); |
| } catch (CoreException ex) { |
| // it's OK, ignore |
| } catch (IOException ex) { |
| // it's OK, ignore |
| } finally { |
| if (is != null) { |
| try { |
| is.close(); |
| } catch (IOException e) { |
| // nothing good can be done here, ignore |
| } |
| } |
| } |
| |
| IEditorRegistry editorReg = PlatformUI.getWorkbench().getEditorRegistry(); |
| if (contentTypes != null) { |
| for(int i = 0 ; i < contentTypes.length; i++) { |
| IEditorDescriptor editorDesc = editorReg.getDefaultEditor(name, contentTypes[i]); |
| if ((editorDesc != null) && (editorDesc.isInternal())) |
| return page.openEditor(input, editorDesc.getId()); |
| } |
| } |
| |
| // no content types are available, use file name associations |
| IEditorDescriptor[] editors = editorReg.getEditors(name); |
| if (editors != null) { |
| for(int i = 0 ; i < editors.length; i++) { |
| if ((editors[i] != null) && (editors[i].isInternal())) |
| return page.openEditor(input, editors[i].getId()); |
| } |
| } |
| |
| // fallback to the default text editor |
| IEditorDescriptor textEditor = editorReg.findEditor(IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID); |
| if (textEditor == null) |
| throw new PartInitException(IDEWorkbenchMessages.IDE_noFileEditorFound); |
| return page.openEditor(input, textEditor.getId()); |
| } |
| |
| /** |
| * Save all dirty editors in the workbench whose editor input is a child |
| * resource of one of the <code>IResource</code>'s provided. Opens a |
| * dialog to prompt the user if <code>confirm</code> is true. Return true |
| * if successful. Return false if the user has canceled the command. |
| * |
| * @since 3.0 |
| * |
| * @param resourceRoots the resource roots under which editor input should |
| * be saved, other will be left dirty |
| * @param confirm <code>true</code> to ask the user before saving unsaved |
| * changes (recommended), and <code>false</code> to save |
| * unsaved changes without asking |
| * @return <code>true</code> if the command succeeded, and |
| * <code>false</code> if the operation was canceled by the user or |
| * an error occurred while saving |
| */ |
| public static boolean saveAllEditors(final IResource[] resourceRoots, |
| final boolean confirm) { |
| |
| if (resourceRoots.length == 0) { |
| return true; |
| } |
| |
| final boolean[] result = new boolean[] { true }; |
| SafeRunner.run(new SafeRunnable(IDEWorkbenchMessages.ErrorOnSaveAll) { |
| public void run() { |
| IWorkbenchWindow w = PlatformUI.getWorkbench() |
| .getActiveWorkbenchWindow(); |
| if (w == null) { |
| IWorkbenchWindow[] windows = PlatformUI.getWorkbench() |
| .getWorkbenchWindows(); |
| if (windows.length > 0) |
| w = windows[0]; |
| } |
| if (w != null) { |
| result[0] = PlatformUI.getWorkbench().saveAll(w, w, |
| new SaveFilter(resourceRoots), confirm); |
| } |
| } |
| }); |
| return result[0]; |
| } |
| |
| /** |
| * Sets the default editor id for a given file. This value will be used to |
| * determine the default editor descriptor for the file in future calls to |
| * <code>getDefaultEditor(IFile)</code>. |
| * |
| * @param file |
| * the file |
| * @param editorID |
| * the editor id |
| */ |
| public static void setDefaultEditor(IFile file, String editorID) { |
| try { |
| file.setPersistentProperty(EDITOR_KEY, editorID); |
| } catch (CoreException e) { |
| // do nothing |
| } |
| } |
| |
| /** |
| * Returns the default editor for a given file. This method will attempt to |
| * resolve the editor based on content-type bindings as well as traditional |
| * name/extension bindings. |
| * <p> |
| * A default editor id may be registered for a specific file using |
| * <code>setDefaultEditor</code>. If the given file has a registered |
| * default editor id the default editor will derived from it. If not, the |
| * default editor is determined by taking the file name for the file and |
| * obtaining the default editor for that name. |
| * </p> |
| * |
| * @param file |
| * the file |
| * @return the descriptor of the default editor, or <code>null</code> if |
| * not found |
| */ |
| public static IEditorDescriptor getDefaultEditor(IFile file) { |
| return getDefaultEditor(file, true); |
| } |
| |
| /** |
| * Returns the default editor for a given file. This method will attempt to |
| * resolve the editor based on content-type bindings as well as traditional |
| * name/extension bindings if <code>determineContentType</code> is |
| * <code>true</code>. |
| * <p> |
| * A default editor id may be registered for a specific file using |
| * <code>setDefaultEditor</code>. If the given file has a registered |
| * default editor id the default editor will derived from it. If not, the |
| * default editor is determined by taking the file name for the file and |
| * obtaining the default editor for that name. |
| * </p> |
| * |
| * @param file |
| * the file |
| * @param determineContentType |
| * determine the content type for the given file |
| * @return the descriptor of the default editor, or <code>null</code> if |
| * not found |
| * @since 3.1 |
| */ |
| public static IEditorDescriptor getDefaultEditor(IFile file, |
| boolean determineContentType) { |
| // Try file specific editor. |
| IEditorRegistry editorReg = PlatformUI.getWorkbench() |
| .getEditorRegistry(); |
| try { |
| String editorID = file.getPersistentProperty(EDITOR_KEY); |
| if (editorID != null) { |
| IEditorDescriptor desc = editorReg.findEditor(editorID); |
| if (desc != null) { |
| return desc; |
| } |
| } |
| } catch (CoreException e) { |
| // do nothing |
| } |
| |
| IContentType contentType = null; |
| if (determineContentType) { |
| contentType = getContentType(file); |
| } |
| // Try lookup with filename |
| return editorReg.getDefaultEditor(file.getName(), contentType); |
| } |
| |
| /** |
| * Extracts and returns the <code>IResource</code>s in the given |
| * selection or the resource objects they adapts to. |
| * |
| * @param originalSelection |
| * the original selection, possibly empty |
| * @return list of resources (element type: <code>IResource</code>), |
| * possibly empty |
| */ |
| public static List computeSelectedResources( |
| IStructuredSelection originalSelection) { |
| List resources = null; |
| for (Iterator e = originalSelection.iterator(); e.hasNext();) { |
| Object next = e.next(); |
| Object resource = null; |
| if (next instanceof IResource) { |
| resource = next; |
| } else if (next instanceof IAdaptable) { |
| resource = ((IAdaptable) next).getAdapter(IResource.class); |
| } |
| if (resource != null) { |
| if (resources == null) { |
| // lazy init to avoid creating empty lists |
| // assume selection contains mostly resources most times |
| resources = new ArrayList(originalSelection.size()); |
| } |
| resources.add(resource); |
| } |
| } |
| if (resources == null) { |
| return Collections.EMPTY_LIST; |
| } |
| return resources; |
| |
| } |
| |
| /** |
| * Return the content type for the given file. |
| * |
| * @param file |
| * the file to test |
| * @return the content type, or <code>null</code> if it cannot be |
| * determined. |
| * @since 3.1 |
| */ |
| public static IContentType getContentType(IFile file) { |
| try { |
| UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, file.getName()); |
| IContentDescription contentDescription = file |
| .getContentDescription(); |
| if (contentDescription == null) { |
| return null; |
| } |
| return contentDescription.getContentType(); |
| } catch (CoreException e) { |
| if (e.getStatus().getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) { |
| // Determine the content type from the file name. |
| return Platform.getContentTypeManager() |
| .findContentTypeFor(file.getName()); |
| } |
| return null; |
| } finally { |
| UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, file.getName()); |
| } |
| } |
| |
| /** |
| * Guess at the content type of the given file based on the filename. |
| * |
| * @param file |
| * the file to test |
| * @return the content type, or <code>null</code> if it cannot be |
| * determined. |
| * @since 3.2 |
| */ |
| public static IContentType guessContentType(IFile file) { |
| String fileName = file.getName(); |
| try { |
| UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, fileName); |
| IContentTypeMatcher matcher = file.getProject() |
| .getContentTypeMatcher(); |
| return matcher.findContentTypeFor(fileName); |
| } catch (CoreException e) { |
| return null; |
| } finally { |
| UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, fileName); |
| } |
| } |
| |
| /** |
| * Prompt the user to inform them of the possible side effects of an |
| * operation on resources. Do not prompt for side effects from ignored model |
| * providers. A model provider can be ignored if it is the client calling |
| * this API. Any message from the provided model provider id or any model |
| * providers it extends will be ignored. |
| * |
| * @param shell |
| * the shell to parent the prompt dialog |
| * @param title |
| * the title of the dialog |
| * @param message |
| * the message for the dialog |
| * @param delta |
| * a delta built using an |
| * {@link IResourceChangeDescriptionFactory} |
| * @param ignoreModelProviderIds |
| * model providers to be ignored |
| * @param syncExec |
| * prompt in a sync exec (required when called from a non-UI |
| * thread) |
| * @return whether the user chose to continue |
| * @since 3.2 |
| */ |
| public static boolean promptToConfirm(final Shell shell, |
| final String title, String message, IResourceDelta delta, |
| String[] ignoreModelProviderIds, boolean syncExec) { |
| IStatus status = ResourceChangeValidator.getValidator().validateChange( |
| delta, null); |
| if (status.isOK()) { |
| return true; |
| } |
| final IStatus displayStatus; |
| if (status.isMultiStatus()) { |
| List result = new ArrayList(); |
| IStatus[] children = status.getChildren(); |
| for (int i = 0; i < children.length; i++) { |
| IStatus child = children[i]; |
| if (!isIgnoredStatus(child, ignoreModelProviderIds)) { |
| result.add(child); |
| } |
| } |
| if (result.isEmpty()) { |
| return true; |
| } |
| if (result.size() == 1) { |
| displayStatus = (IStatus) result.get(0); |
| } else { |
| displayStatus = new MultiStatus(status.getPlugin(), status |
| .getCode(), (IStatus[]) result |
| .toArray(new IStatus[result.size()]), status |
| .getMessage(), status.getException()); |
| } |
| } else { |
| if (isIgnoredStatus(status, ignoreModelProviderIds)) { |
| return true; |
| } |
| displayStatus = status; |
| } |
| |
| if (message == null) { |
| message = IDEWorkbenchMessages.IDE_sideEffectWarning; |
| } |
| final String dialogMessage = NLS.bind( |
| IDEWorkbenchMessages.IDE_areYouSure, message); |
| |
| final boolean[] result = new boolean[] { false }; |
| Runnable runnable = new Runnable() { |
| public void run() { |
| ErrorDialog dialog = new ErrorDialog(shell, title, |
| dialogMessage, displayStatus, IStatus.ERROR |
| | IStatus.WARNING | IStatus.INFO) { |
| protected void createButtonsForButtonBar(Composite parent) { |
| createButton(parent, IDialogConstants.YES_ID, |
| IDialogConstants.YES_LABEL, false); |
| createButton(parent, IDialogConstants.NO_ID, |
| IDialogConstants.NO_LABEL, true); |
| createDetailsButton(parent); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.dialogs.ErrorDialog#buttonPressed(int) |
| */ |
| protected void buttonPressed(int id) { |
| if (id == IDialogConstants.YES_ID) { |
| super.buttonPressed(IDialogConstants.OK_ID); |
| } else if (id == IDialogConstants.NO_ID) { |
| super.buttonPressed(IDialogConstants.CANCEL_ID); |
| } |
| super.buttonPressed(id); |
| } |
| protected int getShellStyle() { |
| return super.getShellStyle() | SWT.SHEET; |
| } |
| }; |
| int code = dialog.open(); |
| result[0] = code == 0; |
| } |
| }; |
| if (syncExec) { |
| shell.getDisplay().syncExec(runnable); |
| } else { |
| runnable.run(); |
| } |
| return result[0]; |
| } |
| |
| /** |
| * Register workbench adapters programmatically. This is necessary to enable |
| * certain types of content in the explorers. |
| * <p> |
| * <b>Note:</b> this method should only be called once, in your |
| * application's WorkbenchAdvisor#initialize(IWorkbenchConfigurer) method. |
| * </p> |
| * |
| * @since 3.5 |
| */ |
| public static void registerAdapters() { |
| IAdapterManager manager = Platform.getAdapterManager(); |
| IAdapterFactory factory = new WorkbenchAdapterFactory(); |
| manager.registerAdapters(factory, IWorkspace.class); |
| manager.registerAdapters(factory, IWorkspaceRoot.class); |
| manager.registerAdapters(factory, IProject.class); |
| manager.registerAdapters(factory, IFolder.class); |
| manager.registerAdapters(factory, IFile.class); |
| manager.registerAdapters(factory, IMarker.class); |
| |
| // properties adapters |
| IAdapterFactory paFactory = new StandardPropertiesAdapterFactory(); |
| manager.registerAdapters(paFactory, IWorkspace.class); |
| manager.registerAdapters(paFactory, IWorkspaceRoot.class); |
| manager.registerAdapters(paFactory, IProject.class); |
| manager.registerAdapters(paFactory, IFolder.class); |
| manager.registerAdapters(paFactory, IFile.class); |
| manager.registerAdapters(paFactory, IMarker.class); |
| } |
| |
| private static boolean isIgnoredStatus(IStatus status, |
| String[] ignoreModelProviderIds) { |
| if (ignoreModelProviderIds == null) { |
| return false; |
| } |
| if (status instanceof ModelStatus) { |
| ModelStatus ms = (ModelStatus) status; |
| for (int i = 0; i < ignoreModelProviderIds.length; i++) { |
| String id = ignoreModelProviderIds[i]; |
| if (ms.getModelProviderId().equals(id)) { |
| return true; |
| } |
| IModelProviderDescriptor desc = ModelProvider |
| .getModelProviderDescriptor(id); |
| String[] extended = desc.getExtendedModels(); |
| if (isIgnoredStatus(status, extended)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Opens editors on given file resources. |
| * <p> |
| * If the page already has an editor open on the target object then that |
| * editor is brought to front; otherwise, a new editor is opened. The editor created |
| * for the first input will be activated. |
| * </p> |
| * @param page the page in which the editor will be opened |
| * @param inputs the inputs for the editors |
| * @return references to the editors opened; the corresponding editors might not be materialized |
| * @exception MultiPartInitException if at least one of the editors could not be initialized |
| * @since 3.5 |
| */ |
| public static IEditorReference[] openEditors(IWorkbenchPage page, IFile[] inputs) throws MultiPartInitException { |
| if ((page == null) || (inputs == null)) |
| throw new IllegalArgumentException(); |
| |
| String[] editorDescriptions = new String[inputs.length]; |
| IEditorInput[] editorInputs = new IEditorInput[inputs.length]; |
| for(int i = 0 ; i < inputs.length; i++) { |
| editorInputs[i] = new FileEditorInput(inputs[i]); |
| try { |
| editorDescriptions[i] = getEditorDescriptor(inputs[i]).getId(); |
| } catch (PartInitException e) { |
| PartInitException[] exceptions = new PartInitException[inputs.length]; |
| exceptions[i] = e; |
| throw new MultiPartInitException(new IWorkbenchPartReference[inputs.length], exceptions); |
| } |
| } |
| return page.openEditors(editorInputs, editorDescriptions, IWorkbenchPage.MATCH_INPUT); |
| } |
| |
| } |