blob: ed8be2f45b046b433cd668fbd6a6685a1363e30d [file] [log] [blame]
/*
* 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);
}
}
}