blob: 00dd06226a9ab03bd8dcb28577d49d3be314dba5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 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 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eike Stepper - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.ecp.ui.views;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecp.core.ECPProject;
import org.eclipse.emf.ecp.core.util.ECPContainer;
import org.eclipse.emf.ecp.core.util.ECPUtil;
import org.eclipse.emf.ecp.internal.ui.model.ModelContentProvider;
import org.eclipse.emf.ecp.spi.ui.UIProvider;
import org.eclipse.emf.ecp.spi.ui.UIProviderRegistry;
import org.eclipse.emf.ecp.spi.ui.util.ECPHandlerHelper;
import org.eclipse.emf.ecp.ui.common.ECPViewerFactory;
import org.eclipse.emf.ecp.ui.e3.Messages;
import org.eclipse.emf.ecp.ui.linkedView.ILinkedWithEditorView;
import org.eclipse.emf.ecp.ui.linkedView.LinkedWithEditorPartListener;
import org.eclipse.emf.ecp.ui.platform.Activator;
import org.eclipse.emf.ecp.ui.tester.ECPSavePropertySource;
import org.eclipse.emf.ecp.ui.tester.SaveButtonEnablementObserver;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchListener;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.services.IEvaluationService;
/**
* @author Eike Stepper
* @author Eugen Neufeld
*/
public class ModelExplorerView extends TreeView implements ILinkedWithEditorView {
private static final String VIEW_SORTER = "viewSorter"; //$NON-NLS-1$
private static final String LINK_WITH_EDITOR_SET = "LinkWithEditorSet"; //$NON-NLS-1$
private static final String LINK_WITH_EDITOR = "LinkWithEditor"; //$NON-NLS-1$
/**
* @author Jonas
* @author Eugen Neufeld
*/
public class DoubleClickListener implements IDoubleClickListener {
/**
* Opens an EObject using the ActionHelper or opens a closed ECPProject. {@inheritDoc}
*/
@Override
public void doubleClick(DoubleClickEvent event) {
if (event.getSelection() instanceof IStructuredSelection) {
final IStructuredSelection structuredSelection = (IStructuredSelection) event.getSelection();
final Object firstElement = structuredSelection.getFirstElement();
if (firstElement instanceof ECPProject) {
final ECPProject project = (ECPProject) firstElement;
if (!project.isOpen()) {
project.open();
}
} else {
final ECPContainer context = ECPUtil
.getModelContext(contentProvider, structuredSelection.toArray());
ECPHandlerHelper.openModelElement(firstElement, (ECPProject) context);
}
}
}
}
/**
* The id of this view.
*/
public static final String ID = "org.eclipse.emf.ecp.ui.ModelExplorerView"; //$NON-NLS-1$
private final IPartListener2 linkWithEditorPartListener = new LinkedWithEditorPartListener(this);
private boolean linkingActive = true;
private ModelContentProvider contentProvider;
private TreeViewer viewer;
private Action linkWithEditorAction;
private ECPSavePropertySource ecpSavePropertySource;
/**
* Default Constructor.
*/
public ModelExplorerView() {
super(ID);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.ecp.ui.views.TreeView#init(org.eclipse.ui.IViewSite)
*/
@Override
public void init(IViewSite site) throws PartInitException {
super.init(site);
@SuppressWarnings("cast")
// Ignore the warning and keep the cast to stay SRC compatible with Luna
final IEvaluationService evaluationService = (IEvaluationService) site.getService(IEvaluationService.class);
ecpSavePropertySource = new ECPSavePropertySource();
evaluationService.addSourceProvider(ecpSavePropertySource);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
@Override
public void dispose() {
@SuppressWarnings("cast")
// Ignore the warning and keep the cast to stay SRC compatible with Luna
final IEvaluationService evaluationService = (IEvaluationService) getSite()
.getService(IEvaluationService.class);
evaluationService.removeSourceProvider(ecpSavePropertySource);
super.dispose();
}
@Override
protected TreeViewer createViewer(final Composite parent) {
viewer = ECPViewerFactory.createModelExplorerViewer(parent, true, createLabelDecorator());
contentProvider = (ModelContentProvider) viewer.getContentProvider();
viewer.addDoubleClickListener(new DoubleClickListener());
viewer.addSelectionChangedListener(new ModelExplorerViewSelectionListener());
viewer.getControl().addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent event) {
}
@Override
public void focusLost(FocusEvent event) {
ECPUtil.getECPObserverBus().notify(SaveButtonEnablementObserver.class)
.notifyChangeButtonState(null, false);
}
});
addViewerSorter(viewer);
getSite().getWorkbenchWindow().getWorkbench().addWorkbenchListener(new IWorkbenchListener() {
@Override
public boolean preShutdown(IWorkbench workbench, boolean forced) {
return ECPHandlerHelper.showDirtyProjectsDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell());
}
@Override
public void postShutdown(IWorkbench workbench) {
// do nothing
}
});
return viewer;
}
@SuppressWarnings("deprecation")
private void addViewerSorter(TreeViewer viewer) {
final IConfigurationElement[] modelExplorerSettings = Platform.getExtensionRegistry()
.getConfigurationElementsFor("org.eclipse.emf.ecp.ui.modelExplorerSettings"); //$NON-NLS-1$
if (modelExplorerSettings.length == 1) {
if (modelExplorerSettings[0].getAttribute(VIEW_SORTER) != null) {
try {
final ViewerSorter sorter = (ViewerSorter) modelExplorerSettings[0]
.createExecutableExtension(VIEW_SORTER);
viewer.setSorter(sorter);
} catch (final CoreException e) {
Activator.log(e);
}
}
}
}
@Override
protected void fillLocalToolBar(IToolBarManager manager) {
if (getDialogSettings().getBoolean(LINK_WITH_EDITOR_SET)) {
linkingActive = getDialogSettings().getBoolean(LINK_WITH_EDITOR);
}
if (linkingActive) {
getSite().getPage().addPartListener(linkWithEditorPartListener);
}
linkWithEditorAction = new Action(Messages.ModelExplorerView_LinkWithEditor, SWT.TOGGLE) {
@Override
public void run() {
if (linkingActive) {
linkingActive = false;
getSite().getPage().removePartListener(linkWithEditorPartListener);
} else {
linkingActive = true;
getSite().getPage().addPartListener(linkWithEditorPartListener);
final IEditorPart editor = getSite().getPage().getActiveEditor();
if (editor != null) {
editorActivated(editor);
}
}
getDialogSettings().put(LINK_WITH_EDITOR, isChecked());
getDialogSettings().put(LINK_WITH_EDITOR_SET, true);
}
};
linkWithEditorAction.setImageDescriptor(Activator.getImageDescriptor("icons/link_with_editor.gif")); //$NON-NLS-1$
linkWithEditorAction.setToolTipText(Messages.ModelExplorerView_LinkWithEditor);
linkWithEditorAction.setChecked(getDialogSettings().getBoolean(LINK_WITH_EDITOR_SET) ? getDialogSettings()
.getBoolean(LINK_WITH_EDITOR) : true);
manager.add(linkWithEditorAction);
}
private IDialogSettings getDialogSettings() {
return Activator.getDefault().getDialogSettings();
}
@Override
protected void fillContextMenu(IMenuManager manager) {
final Object[] elements = getSelection().toArray();
final ECPContainer context = ECPUtil.getModelContext(contentProvider, elements);
if (context != null) {
final UIProvider provider = UIProviderRegistry.INSTANCE.getUIProvider(context);
if (provider != null) {
provider.fillContextMenu(manager, context, elements);
}
}
super.fillContextMenu(manager);
}
/** {@inheritDoc} */
@Override
public void editorActivated(IEditorPart activatedEditor) {
if (!linkingActive || !getViewSite().getPage().isPartVisible(this)) {
return;
}
final Object input = activatedEditor.getEditorInput().getAdapter(EObject.class);
if (input != null) {
viewer.setSelection(new StructuredSelection(input), true);
}
}
/**
*
* @author jfaltermeier
*
*/
private class ModelExplorerViewSelectionListener implements ISelectionChangedListener {
@Override
public void selectionChanged(SelectionChangedEvent event) {
notifyAboutSaveButtonState(event);
if (linkingActive) {
final Object selected = ((IStructuredSelection) event.getSelection()).getFirstElement();
if (selected instanceof EObject) {
for (final IEditorReference editorRef : getSite().getPage().getEditorReferences()) {
Object editorInput = null;
try {
editorInput = editorRef.getEditorInput().getAdapter(EObject.class);
} catch (final PartInitException e) {
e.printStackTrace();
}
if (selected.equals(editorInput)) {
getSite().getPage().bringToTop(editorRef.getPart(true));
return;
}
}
}
}
}
private void notifyAboutSaveButtonState(SelectionChangedEvent event) {
final boolean selectedProjectIsDirty;
final Object selected = ((IStructuredSelection) event.getSelection()).getFirstElement();
final ECPProject project = ECPUtil.getECPProjectManager().getProject(selected);
if (project == null) {
selectedProjectIsDirty = false;
} else {
selectedProjectIsDirty = project.hasDirtyContents();
}
ECPUtil.getECPObserverBus().notify(SaveButtonEnablementObserver.class)
.notifyChangeButtonState(project, selectedProjectIsDirty);
}
}
}