| /* |
| * Copyright (c) 2009-2013, 2015 Eike Stepper (Berlin, Germany) 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: |
| * Victor Roldan Betancort - initial API and implementation |
| * Eike Stepper - maintenance |
| * Christian W. Damus (CEA LIST) - bug 418452 |
| */ |
| package org.eclipse.emf.cdo.ui; |
| |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.eresource.CDOResourceLeaf; |
| import org.eclipse.emf.cdo.internal.ui.CDOEditorInputImpl; |
| import org.eclipse.emf.cdo.internal.ui.CDOLobEditorInput; |
| import org.eclipse.emf.cdo.internal.ui.bundle.OM; |
| import org.eclipse.emf.cdo.internal.ui.editor.CDOEditor; |
| import org.eclipse.emf.cdo.view.CDOView; |
| |
| import org.eclipse.net4j.util.ObjectUtil; |
| |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.edit.domain.IEditingDomainProvider; |
| |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.swt.widgets.Display; |
| 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.IWorkbenchPage; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.WeakHashMap; |
| |
| /** |
| * Some utility methods to cope with CDOEditor and CDOEditorInput |
| * |
| * @author Victor Roldan Betancort |
| * @since 2.0 |
| */ |
| public final class CDOEditorUtil |
| { |
| /** |
| * @since 4.1 |
| */ |
| public static final String EDITOR_ID = "org.eclipse.emf.cdo.ui.CDOEditor"; //$NON-NLS-1$ |
| |
| /** |
| * @since 4.4 |
| */ |
| public static final String TEXT_EDITOR_ID = "org.eclipse.ui.DefaultTextEditor"; |
| |
| private static final IEditorRegistry EDITOR_REGISTRY = PlatformUI.getWorkbench().getEditorRegistry(); |
| |
| private static final Map<CDOResourceLeaf, String> EDITOR_OVERRIDES = new WeakHashMap<CDOResourceLeaf, String>(); |
| |
| private static String editorID = EDITOR_ID; |
| |
| private CDOEditorUtil() |
| { |
| } |
| |
| /** |
| * @since 4.1 |
| */ |
| public static String getEditorID() |
| { |
| return editorID; |
| } |
| |
| /** |
| * @since 4.1 |
| */ |
| public static void setEditorID(String editorID) |
| { |
| CDOEditorUtil.editorID = editorID; |
| } |
| |
| /** |
| * Returns an implementation of the CDOEditorInput interface. |
| */ |
| public static CDOEditorInput createCDOEditorInput(CDOView view, String resourcePath, boolean viewOwned) |
| { |
| return new CDOEditorInputImpl(view, resourcePath, viewOwned); |
| } |
| |
| /** |
| * Creates a {@link CDOEditorInput} based on the given {@code input} that adapts to |
| * the {@link IEditingDomainProvider} interface to provide a particular {@code editingDomain}. |
| * |
| * @param input an editor input to copy |
| * @param editingDomain the editing domain to associate with the editor input |
| * |
| * @return the editing-domain-providing editor input |
| * |
| * @since 4.3 |
| */ |
| public static CDOEditorInput createCDOEditorInputWithEditingDomain(CDOEditorInput input, EditingDomain editingDomain) |
| { |
| return createCDOEditorInputWithEditingDomain(input.getView(), input.getResourcePath(), input.isViewOwned(), |
| editingDomain); |
| } |
| |
| /** |
| * Creates a {@link CDOEditorInput} that adapts to the {@link IEditingDomainProvider} interface |
| * to provide a particular {@code editingDomain}. |
| * |
| * @param view the CDO view of the editor input |
| * @param resourcePath the path to the resource to edit |
| * @param viewOwned whether the opened editor should assume ownership of the {@code view} |
| * @param editingDomain the editing domain to associate with the editor input |
| * |
| * @return the editing-domain-providing editor input |
| * |
| * @since 4.3 |
| */ |
| public static CDOEditorInput createCDOEditorInputWithEditingDomain(CDOView view, String resourcePath, |
| boolean viewOwned, EditingDomain editingDomain) |
| { |
| class CDOEditorInputWithEditingDomain extends CDOEditorInputImpl implements IEditingDomainProvider |
| { |
| private final EditingDomain editingDomain; |
| |
| CDOEditorInputWithEditingDomain(CDOView view, String resourcePath, boolean viewOwned, EditingDomain editingDomain) |
| { |
| super(view, resourcePath, viewOwned); |
| this.editingDomain = editingDomain; |
| } |
| |
| public EditingDomain getEditingDomain() |
| { |
| return editingDomain; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public <T> T getAdapter(Class<T> adapter) |
| { |
| if (adapter == IEditingDomainProvider.class) |
| { |
| return (T)this; |
| } |
| |
| return super.getAdapter(adapter); |
| } |
| } |
| |
| return new CDOEditorInputWithEditingDomain(view, resourcePath, viewOwned, editingDomain); |
| } |
| |
| /** |
| * Opens the specified resource in CDOEditor |
| * |
| * @param page |
| * The page in which the editor will be opened |
| * @param view |
| * the CDOView that will be used to access the resource |
| * @param resourcePath |
| * absolute path to the resource in the repository |
| */ |
| public static void openEditor(final IWorkbenchPage page, final CDOView view, final String resourcePath) |
| { |
| Display display = page.getWorkbenchWindow().getShell().getDisplay(); |
| display.asyncExec(new Runnable() |
| { |
| public void run() |
| { |
| try |
| { |
| IEditorReference[] references = findEditor(page, view, resourcePath); |
| if (references.length != 0) |
| { |
| IEditorPart editor = references[0].getEditor(true); |
| page.activate(editor); |
| } |
| else |
| { |
| IEditorInput input = createCDOEditorInput(view, resourcePath, false); |
| page.openEditor(input, editorID); |
| } |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * Returns references to possibly opened instances of CDOEditor with certain CDOView and resource |
| * |
| * @param page |
| * The page where to search for opened editors |
| * @param view |
| * The editors to find are using the specified CDOView |
| * @param resourcePath |
| * The editors are editing the CDOResource specified with this path |
| */ |
| public static IEditorReference[] findEditor(IWorkbenchPage page, CDOView view, String resourcePath) |
| { |
| List<IEditorReference> result = new ArrayList<IEditorReference>(); |
| IEditorReference[] editorReferences = page.getEditorReferences(); |
| for (IEditorReference editorReference : editorReferences) |
| { |
| try |
| { |
| if (ObjectUtil.equals(editorReference.getId(), editorID)) |
| { |
| IEditorInput editorInput = editorReference.getEditorInput(); |
| if (editorInput instanceof CDOEditorInput) |
| { |
| CDOEditorInput cdoInput = (CDOEditorInput)editorInput; |
| if (cdoInput.getView() == view) |
| { |
| if (resourcePath == null || ObjectUtil.equals(cdoInput.getResourcePath(), resourcePath)) |
| { |
| result.add(editorReference); |
| } |
| } |
| } |
| } |
| } |
| catch (PartInitException ex) |
| { |
| OM.LOG.error(ex); |
| } |
| } |
| |
| return result.toArray(new IEditorReference[result.size()]); |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| public static void populateMenu(IMenuManager manager, CDOResourceLeaf resource, IWorkbenchPage page) |
| { |
| String effectiveEditorID = getEffectiveEditorID(resource); |
| manager.add(new OpenEditorAction(page, effectiveEditorID, resource, false)); |
| |
| String[] editorIDs = getAllEditorIDs(resource); |
| if (editorIDs.length > 1 || editorIDs.length == 1 && !editorIDs[0].equals(effectiveEditorID)) |
| { |
| MenuManager subMenu = new MenuManager("Open With"); |
| manager.add(subMenu); |
| |
| for (String id : editorIDs) |
| { |
| OpenEditorAction action = new OpenEditorAction(page, id, resource, true); |
| subMenu.add(action); |
| if (id.equals(effectiveEditorID)) |
| { |
| action.setChecked(true); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| public static String getEffectiveEditorID(CDOResourceLeaf resource) |
| { |
| String editorID = EDITOR_OVERRIDES.get(resource); |
| if (editorID != null) |
| { |
| return editorID; |
| } |
| |
| if (resource instanceof CDOResource) |
| { |
| return EDITOR_ID; |
| } |
| |
| String name = resource.getName(); |
| IEditorDescriptor editorDescriptor = EDITOR_REGISTRY.getDefaultEditor(name); |
| if (editorDescriptor != null) |
| { |
| return editorDescriptor.getId(); |
| } |
| |
| return TEXT_EDITOR_ID; |
| } |
| |
| /** |
| * @since 4.2 |
| */ |
| public static String[] getAllEditorIDs(CDOResourceLeaf resource) |
| { |
| List<String> editorIDs = new ArrayList<String>(); |
| if (resource instanceof CDOResource) |
| { |
| editorIDs.add(EDITOR_ID); |
| } |
| |
| String name = resource.getName(); |
| for (IEditorDescriptor editorDescriptor : EDITOR_REGISTRY.getEditors(name)) |
| { |
| editorIDs.add(editorDescriptor.getId()); |
| } |
| |
| if (!editorIDs.contains(TEXT_EDITOR_ID) && EDITOR_REGISTRY.findEditor(TEXT_EDITOR_ID) != null) |
| { |
| editorIDs.add(TEXT_EDITOR_ID); |
| } |
| |
| Collections.sort(editorIDs); |
| return editorIDs.toArray(new String[editorIDs.size()]); |
| } |
| |
| /** |
| * @since 4.4 |
| */ |
| public static IEditorInput createEditorInput(String editorID, CDOResourceLeaf resource, boolean viewOwned, |
| boolean lobCommitOnSave) |
| { |
| if (resource instanceof CDOResource) |
| { |
| if (EDITOR_ID.equals(editorID)) |
| { |
| CDOView view = resource.cdoView(); |
| String path = resource.getPath(); |
| return createCDOEditorInput(view, path, lobCommitOnSave); |
| } |
| } |
| |
| return new CDOLobEditorInput(resource, lobCommitOnSave); |
| } |
| |
| /** |
| * Returns an implementation of the IEditorInput interface. |
| * |
| * @since 4.2 |
| */ |
| public static IEditorInput createEditorInput(String editorID, CDOResourceLeaf resource, boolean viewOwned) |
| { |
| return createEditorInput(editorID, resource, viewOwned, false); |
| } |
| |
| /** |
| * Returns an implementation of the IEditorInput interface. |
| * |
| * @since 4.2 |
| */ |
| public static IEditorInput createEditorInput(String editorID, CDOResourceLeaf resource) |
| { |
| return createEditorInput(editorID, resource, false); |
| } |
| |
| /** |
| * Opens the specified resource in CDOEditor |
| * |
| * @param page |
| * The page in which the editor will be opened |
| * @since 4.2 |
| */ |
| public static void openEditor(IWorkbenchPage page, CDOResourceLeaf resource) |
| { |
| String editorID = CDOEditorUtil.getEffectiveEditorID(resource); |
| if (editorID != null) |
| { |
| openEditor(page, editorID, resource); |
| } |
| } |
| |
| /** |
| * Opens the specified resource in CDOEditor |
| * |
| * @param page |
| * The page in which the editor will be opened |
| * @since 4.2 |
| */ |
| public static void openEditor(final IWorkbenchPage page, final String editorID, final CDOResourceLeaf resource) |
| { |
| Display display = page.getWorkbenchWindow().getShell().getDisplay(); |
| display.asyncExec(new Runnable() |
| { |
| public void run() |
| { |
| try |
| { |
| IEditorInput editorInput = createEditorInput(editorID, resource); |
| page.openEditor(editorInput, editorID); |
| } |
| catch (Exception ex) |
| { |
| OM.LOG.error(ex); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * Refreshes all editor's viewers that are using certain CDOView. |
| * |
| * @param page |
| * the IWorkbenchPage where CDOEditor is opened |
| * @param view |
| * instance of CDOView our editors are using |
| */ |
| public static void refreshEditors(IWorkbenchPage page, CDOView view) |
| { |
| IEditorReference[] references = findEditor(page, view, null); |
| for (IEditorReference reference : references) |
| { |
| CDOEditor editor = (CDOEditor)reference.getEditor(false); |
| if (editor != null) |
| { |
| editor.refreshViewer(null); |
| } |
| } |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| private static class OpenEditorAction extends Action |
| { |
| private IWorkbenchPage page; |
| |
| private String editorID; |
| |
| private CDOResourceLeaf resource; |
| |
| private boolean overrideOnRun; |
| |
| public OpenEditorAction(IWorkbenchPage page, String editorID, CDOResourceLeaf resource, boolean overrideOnRun) |
| { |
| this.page = page; |
| this.editorID = editorID; |
| this.resource = resource; |
| this.overrideOnRun = overrideOnRun; |
| |
| IEditorDescriptor editorDescriptor = EDITOR_REGISTRY.findEditor(editorID); |
| String label = editorDescriptor.getLabel(); |
| if (overrideOnRun) |
| { |
| setText(label); |
| } |
| else |
| { |
| setText("Open With " + label); |
| } |
| |
| setImageDescriptor(editorDescriptor.getImageDescriptor()); |
| setToolTipText("Open the " + label + " editor on this resource"); |
| } |
| |
| @Override |
| public void run() |
| { |
| if (overrideOnRun) |
| { |
| EDITOR_OVERRIDES.put(resource, editorID); |
| } |
| |
| openEditor(page, editorID, resource); |
| } |
| } |
| } |