| /**
|
| * Copyright (c) 2014, 2019 Mia-Software, and Soft-Maint.
|
| * All rights reserved. This program and the accompanying materials
|
| * are made available under the terms of the Eclipse Public License v2.0
|
| * which accompanies this distribution, and is available at
|
| * http://www.eclipse.org/legal/epl-v20.html
|
| *
|
| * Contributors:
|
| * Gregoire Dupe (Mia-Software) - Bug 358914 - [Move to EMF Facet][Browser] Switch to EMF Facet
|
| * Thomas Cicognani (Soft-Maint) - Bug 442718 - Implement copy action in the new MoDisco Browser
|
| * Thomas Cicognani (Soft-Maint) - Bug 442800 - API to open new MoDisco Browser
|
| * Grégoire Dupé (Mia-Software) - Bug 442800 - API to open new MoDisco Browser
|
| * Thomas Cicognani (Mia-Software) - Bug 470962 - Add shortcuts to activate customs
|
| * Grégoire Dupé (Mia-Software) - Bug 507310 - [New Browser] The selection should contains unwrapped EObjects
|
| * Grégoire Dupé (Mia-Software) - Bug 506466 - [New Browser] doSave has to implemented
|
| * Grégoire Dupé (Mia-Software) - Bug 506318 - [New Browser] Drag and drop support
|
| */ |
| package org.eclipse.modisco.infra.browser.editor.ui.internal.editor;
|
|
|
| import java.io.IOException;
|
| import java.util.ArrayList;
|
| import java.util.Collections;
|
| import java.util.EventObject;
|
| import java.util.List;
|
|
|
| import org.eclipse.core.resources.IFile;
|
| import org.eclipse.core.runtime.IPath;
|
| import org.eclipse.core.runtime.IProgressMonitor;
|
| import org.eclipse.emf.common.command.BasicCommandStack;
|
| import org.eclipse.emf.common.command.CommandStackListener;
|
| import org.eclipse.emf.common.util.URI;
|
| import org.eclipse.emf.ecore.EObject;
|
| import org.eclipse.emf.ecore.resource.Resource;
|
| import org.eclipse.emf.ecore.resource.ResourceSet;
|
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
|
| import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
|
| import org.eclipse.emf.edit.domain.EditingDomain;
|
| import org.eclipse.emf.edit.domain.IEditingDomainProvider;
|
| import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
|
| import org.eclipse.jface.action.MenuManager;
|
| import org.eclipse.jface.viewers.IContentProvider;
|
| import org.eclipse.jface.viewers.ILabelProvider;
|
| import org.eclipse.jface.viewers.ISelectionProvider;
|
| import org.eclipse.jface.viewers.TreeViewer;
|
| import org.eclipse.modisco.facet.custom.core.ICustomizationManager;
|
| import org.eclipse.modisco.facet.custom.core.ICustomizationManagerFactory;
|
| import org.eclipse.modisco.facet.custom.ui.ICustomizationManagerProvider2;
|
| import org.eclipse.modisco.facet.custom.ui.ICustomizedContentProviderFactory;
|
| import org.eclipse.modisco.facet.custom.ui.IResolvingCustomizedLabelProviderFactory;
|
| import org.eclipse.modisco.facet.custom.ui.ICustomizedContentProviderFactory.IContentListener;
|
| import org.eclipse.modisco.facet.efacet.core.IFacetManager;
|
| import org.eclipse.modisco.facet.efacet.core.IFacetManagerFactory;
|
| import org.eclipse.modisco.facet.efacet.core.IFacetManagerListener;
|
| import org.eclipse.modisco.facet.efacet.ui.IFacetManagerProvider2;
|
| import org.eclipse.modisco.facet.util.ui.internal.exported.dialog.IOkDialog;
|
| import org.eclipse.modisco.facet.util.ui.internal.exported.dialog.IOkDialogFactory;
|
| import org.eclipse.modisco.infra.browser.editor.ui.ITreeEditor;
|
| import org.eclipse.modisco.infra.browser.editor.ui.internal.Activator;
|
| import org.eclipse.modisco.infra.browser.editor.ui.internal.opener.ResourceEditorInput;
|
| import org.eclipse.modisco.infra.browser.editor.ui.internal.opener.ResourceSetEditorInput;
|
| import org.eclipse.swt.widgets.Composite;
|
| import org.eclipse.swt.widgets.Display;
|
| import org.eclipse.swt.widgets.Menu;
|
| import org.eclipse.swt.widgets.Shell;
|
| import org.eclipse.ui.IEditorInput;
|
| import org.eclipse.ui.IEditorPart;
|
| import org.eclipse.ui.IEditorSite;
|
| import org.eclipse.ui.PartInitException;
|
| import org.eclipse.ui.part.EditorPart;
|
| import org.eclipse.ui.part.FileEditorInput;
|
|
|
| public class TreeEditor extends EditorPart implements IEditingDomainProvider,
|
| IFacetManagerProvider2, ICustomizationManagerProvider2, ITreeEditor {
|
|
|
| private static final String EDITOR_ID = Activator.getDefault().getBundle()
|
| .getSymbolicName() + ".TreeEditor"; //$NON-NLS-1$
|
| private Resource resource;
|
| private ResourceSet resourceSet;
|
| private EditingDomain editingDomain;
|
| private IFacetManager facetManager;
|
| private ICustomizationManager customManager;
|
| private TreeViewer tree;
|
| private IFacetManagerListener facetMgrListener;
|
| private List<IFacetSetShortcut> facetSetShortcuts;
|
| private List<ICustomShortcut> customShortcuts;
|
| private ISelectionProvider selectionProvider;
|
|
|
| @Override
|
| public void doSave(final IProgressMonitor monitor) {
|
| doSave();
|
| }
|
|
|
| public IOkDialog doSave() {
|
| IOkDialog result = null;
|
| try {
|
| this.resource.save(Collections.EMPTY_MAP);
|
| } catch (final IOException e) {
|
| final URI uri = this.resource.getURI();
|
| final String message = String.format("Failed to save %s", uri); //$NON-NLS-1$
|
| result = IOkDialogFactory.DEFAULT.openErrorDialog(
|
| this.getSite().getShell(), e, message);
|
| }
|
| final BasicCommandStack commandStack =
|
| (BasicCommandStack) this.editingDomain.getCommandStack();
|
| commandStack.saveIsDone();
|
| firePropertyChange(IEditorPart.PROP_DIRTY);
|
| return result;
|
| }
|
|
|
| @Override
|
| public void doSaveAs() {
|
| // TODO Auto-generated method stub
|
| }
|
|
|
| @Override
|
| public void init(final IEditorSite site, final IEditorInput input)
|
| throws PartInitException {
|
| setSite(site);
|
| setInput(input);
|
| if (input instanceof FileEditorInput) {
|
| final FileEditorInput fileEI = (FileEditorInput) input;
|
| final IFile file = fileEI.getFile();
|
| final IPath path = file.getFullPath();
|
| final String pathStr = path.toString();
|
| final URI uri = URI.createPlatformResourceURI(pathStr, true);
|
| this.resourceSet = new ResourceSetImpl();
|
| this.resource = this.resourceSet.getResource(uri, true);
|
| } else if (input instanceof ResourceEditorInput) {
|
| final ResourceEditorInput resourceEI = (ResourceEditorInput) input;
|
| this.resource = resourceEI.getResource();
|
| this.resourceSet = this.resource.getResourceSet();
|
| } else if (input instanceof ResourceSetEditorInput) {
|
| final ResourceSetEditorInput resourceSetEI = (ResourceSetEditorInput) input;
|
| this.resourceSet = resourceSetEI.getResourceSet();
|
| } else {
|
| final String message = String.format(
|
| "The EditorInput (%s) is not compatible with the TreeEditor", //$NON-NLS-1$
|
| input.getClass().getName()
|
| );
|
| throw new IllegalArgumentException(message);
|
| }
|
| if (this.resourceSet == null) {
|
| /*
|
| * "this.resourceSet" is null while opening an ecore model stored in
|
| * EPackage.Registry.INSTANCE. this.resourceSet must not be null,
|
| * because we need it to instantiate the facetManager.
|
| */
|
| this.resourceSet = new ResourceSetImpl();
|
| }
|
| this.editingDomain = initEditingDomain();
|
| this.facetSetShortcuts = TreeEditorShortcutUtils.getFacetSetShortcuts(this.resourceSet);
|
| this.customShortcuts = TreeEditorShortcutUtils.getCustomShortcuts(this.resourceSet);
|
| }
|
|
|
| private final EditingDomain initEditingDomain() {
|
| final ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(
|
| ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
|
| final BasicCommandStack commandStack = new BasicCommandStack();
|
| commandStack.addCommandStackListener(new CommandStackListener() {
|
| public void commandStackChanged(final EventObject event) {
|
| onCommandStackChanged();
|
| }
|
| });
|
| return new AdapterFactoryEditingDomain(adapterFactory,
|
| commandStack, this.resourceSet);
|
| }
|
|
|
| private void createPopupMenu() {
|
| final MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
|
| menuMgr.setRemoveAllWhenShown(true);
|
| final Menu menu = menuMgr.createContextMenu(this.tree.getControl());
|
| this.tree.getControl().setMenu(menu);
|
| getSite().registerContextMenu(menuMgr, this.selectionProvider);
|
| }
|
|
|
| protected final void onCommandStackChanged() {
|
| firePropertyChange(IEditorPart.PROP_DIRTY);
|
| }
|
|
|
| @Override
|
| public boolean isDirty() {
|
| final BasicCommandStack basicCommandStack =
|
| (BasicCommandStack) this.editingDomain.getCommandStack();
|
| final boolean saveNeeded = basicCommandStack.isSaveNeeded();
|
| return this.isReadWriteResource() && saveNeeded;
|
| }
|
|
|
| private boolean isReadWriteResource() {
|
| final URI uri = this.resource.getURI();
|
| final String uriStr = uri.toString();
|
| return uriStr.matches("(platform:/resource/.*)|(file:/)"); //$NON-NLS-1$
|
| }
|
|
|
| @Override
|
| public boolean isSaveAsAllowed() {
|
| return isDirty();
|
| }
|
|
|
| @Override
|
| public void createPartControl(final Composite parent) {
|
| this.tree = new TreeViewer(parent);
|
| this.facetManager = IFacetManagerFactory.DEFAULT
|
| .getOrCreateFacetManager(this.resourceSet);
|
| this.customManager = ICustomizationManagerFactory.DEFAULT
|
| .getOrCreateICustomizationManager(this.resourceSet);
|
| final ILabelProvider labelProvider = IResolvingCustomizedLabelProviderFactory.DEFAULT
|
| .createCustomizedLabelProvider(this.customManager);
|
| final IContentProvider contentProvider = ICustomizedContentProviderFactory.DEFAULT
|
| .createCustomizedTreeContentProvider(this.customManager, new IContentListener() {
|
| public void onUpdate(final Object object) {
|
| TreeEditor.this.syncRefresh(object);
|
| }
|
| });
|
| this.tree.setContentProvider(contentProvider);
|
| this.tree.setLabelProvider(labelProvider);
|
| final List<EObject> contents = new ArrayList<EObject>();
|
| if (this.resource == null) {
|
| for (final Resource res : this.resourceSet.getResources()) {
|
| contents.addAll(res.getContents());
|
| }
|
| } else {
|
| contents.addAll(this.resource.getContents());
|
| }
|
| TreeEditorDragAndDropUtils.addDragAndDropSupport(this.tree,
|
| this.editingDomain);
|
| this.tree.setInput(contents);
|
| this.selectionProvider = new TreeEditorSelectionProvider(this.tree);
|
| getSite().setSelectionProvider(this.selectionProvider);
|
| this.facetMgrListener = new IFacetManagerListener() {
|
| public void facetManagerChanged() {
|
| TreeEditor.this.refresh();
|
| }
|
| };
|
| createPopupMenu();
|
| this.facetManager.addListener(this.facetMgrListener);
|
| } |
| |
| protected void syncRefresh(final Object object) { |
| final Shell shell = this.getSite().getShell(); |
| final Display display = shell.getDisplay(); |
| display.asyncExec(new Runnable() { |
| public void run() { |
| internalRefresh(object); |
| } |
| }); |
| } |
| |
| protected void internalRefresh(final Object object) { |
| this.tree.refresh(object);
|
| }
|
|
|
| protected void refresh() {
|
| final Object[] expanededElts = this.tree.getExpandedElements();
|
| this.tree.refresh();
|
| this.tree.setExpandedElements(expanededElts);
|
| }
|
|
|
| @Override
|
| public void setFocus() {
|
| // TODO Auto-generated method stub
|
|
|
| }
|
|
|
| public static String getEditorId() {
|
| return EDITOR_ID;
|
| }
|
|
|
| public EditingDomain getEditingDomain() {
|
| return this.editingDomain;
|
| }
|
|
|
| @Override
|
| public Object getAdapter(@SuppressWarnings("rawtypes") final Class adapter) {
|
| /* @SuppressWarnings("rawtypes"): gdupe> Imposed by the super class */
|
| Object result = null;
|
| if (adapter.isInstance(this)) {
|
| result = this;
|
| } else if (adapter == ISelectionProvider.class) {
|
| result = this.selectionProvider;
|
| } else {
|
| result = super.getAdapter(adapter);
|
| }
|
| return result;
|
| }
|
|
|
| public ICustomizationManager getCustomizationManager() {
|
| return this.customManager;
|
| }
|
|
|
| public List<ICustomShortcut> getCustomShortcuts() {
|
| return this.customShortcuts;
|
| }
|
|
|
| public IFacetManager getFacetManager() {
|
| return this.facetManager;
|
| }
|
|
|
| public List<IFacetSetShortcut> getFacetSetShortcuts() {
|
| return this.facetSetShortcuts;
|
| }
|
|
|
| @Override
|
| public void dispose() {
|
| this.facetManager.removeListener(this.facetMgrListener);
|
| super.dispose();
|
| }
|
|
|
| public ILabelProvider getViewerLabelProvider() {
|
| return (ILabelProvider) this.tree.getLabelProvider();
|
| }
|
|
|
| }
|