/*********************************************************************** * Copyright (c) 2007 Anyware Technologies * Copyright (c) 2015 IRT AESE (IRT Saint Exupery) * * 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: * David Sciamma / Jacques Lescot (Anyware Technologies) - initial API and implementation * Pierre Gaufillet (IRT Saint Exupery) - Extension to a general purpose * EClass information view * * $Id: EClassHierarchyView.java,v 1.6 2008/05/19 09:26:31 jlescot Exp $ **********************************************************************/ package org.eclipse.emf.ecoretools.ui.views; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecoretools.ui.Activator; import org.eclipse.emf.ecoretools.ui.Messages; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.viewers.ISelection; 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.sirius.viewpoint.DSemanticDecorator; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.ui.progress.WorkbenchJob; /** * This view analyzes the hierarchy of an EClass (ascendant, descendant...) * * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a> * @author <a href="pierre.gaufillet@irt-saintexupery.com">Pierre Gaufillet</a> */ public class EClassHierarchyView extends AnalysisView { /** * The ID of the view */ public static final String VIEW_ID = "org.eclipse.emf.ecoretools.internal.views.EClassHierarchyView"; //$NON-NLS-1$ private static enum SortDirection { ASCENDANT, DESCENDANT }; private final static int JOB_DELAY = 0; /** * UI parts */ private SashForm splitter; private TreeViewer hierarchyTree; private TreeViewer featuresViewer; private FeatureLabelProvider featureLabelProvider; private SortDirection kind = SortDirection.ASCENDANT; private ISelectionChangedListener hierarchicalTreeSelectionChangedListener; /** * The job used to refresh the EClass hierarchy. */ private Job refreshHierarchyJob; /** * The job used to refresh the features. */ private Job refreshFeaturesJob; /** * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ @Override public void createPartControl(Composite parent) { super.createPartControl(parent); splitter = new SashForm(parent, SWT.HORIZONTAL); hierarchicalTreeSelectionChangedListener = new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { doSelectionChanged(event); }; }; hierarchyTree = new TreeViewer(splitter, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL); hierarchyTree.addPostSelectionChangedListener(hierarchicalTreeSelectionChangedListener); hierarchyTree.getControl().addDisposeListener(new DisposeListener() { /** * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) */ @Override public void widgetDisposed(DisposeEvent e) { if (refreshHierarchyJob != null) { refreshHierarchyJob.cancel(); } if (refreshFeaturesJob != null) { refreshFeaturesJob.cancel(); } } }); prepareViewerForDragToSirius(hierarchyTree); setKind(SortDirection.ASCENDANT); featuresViewer = new TreeViewer(splitter, SWT.H_SCROLL | SWT.V_SCROLL); featuresViewer.setContentProvider(new FeatureContentProvider()); featureLabelProvider = new FeatureLabelProvider(); featuresViewer.setLabelProvider(featureLabelProvider); refresh(); } private void doSelectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { EObject selectedObject = getSelection((IStructuredSelection) selection); if (selectedObject != null /* && sProvider.equals(hierarchyTree) */) { refreshFeatures(findEClass(selectedObject)); } } } /** * Changes the kind of hierarchy displayed in this view * * @param hierarchyKind * the new kind of hierarchy */ private void setKind(SortDirection hierarchyKind) { kind = hierarchyKind; hierarchyTree.setLabelProvider(new EClassInformationLabelProvider()); switch (kind) { case ASCENDANT: hierarchyTree.setContentProvider(new EClassHierarchyContentProvider()); break; case DESCENDANT: hierarchyTree.setContentProvider(new EClassDescendentHierarchyContentProvider()); break; default: break; } } /* * (non-Javadoc) * * @see * org.eclipse.emf.ecoretools.ui.AnalysisView#refresh(org.eclipse.emf.ecore.EObject * ) */ @Override protected void refresh(EObject object) { refreshHierarchy(object); } private void refreshHierarchy(EObject object) { // cancel currently running job first, to prevent unnecessary redraw if (refreshHierarchyJob != null) { refreshHierarchyJob.cancel(); } EClass selectedEClass = findEClass(object); if (selectedEClass != null) { refreshHierarchyJob = createRefreshHierarchyJob(selectedEClass); refreshHierarchyJob.schedule(JOB_DELAY); } } private void refreshFeatures(EObject object) { // cancel currently running job first, to prevent unnecessary redraw if (refreshFeaturesJob != null) { refreshFeaturesJob.cancel(); } EClass selectedEClass = findEClass(object); if (selectedEClass != null) { refreshFeaturesJob = createRefreshFeaturesJob(selectedEClass); refreshFeaturesJob.schedule(JOB_DELAY); } } private EClass findEClass(EObject object) { if (object instanceof DSemanticDecorator) { object = ((DSemanticDecorator) object).getTarget(); } if (!(object instanceof EClass)) { object = object.eClass(); } return (EClass) object; } private Job createRefreshHierarchyJob(final EClass selection) { Job job = new WorkbenchJob(Messages.EClassHierarchyView_RefreshHierarchy) { /** * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) */ @Override public IStatus runInUIThread(IProgressMonitor monitor) { if (hierarchyTree.getControl().isDisposed()) { return Status.CANCEL_STATUS; } try { hierarchyTree.getControl().setRedraw(false); hierarchyTree.setInput(new EClass[] { selection }); hierarchyTree.refresh(); hierarchyTree.expandToLevel(2); hierarchyTree.setSelection(new StructuredSelection(selection), true); } finally { // done updating the tree - set redraw back to true hierarchyTree.getControl().setRedraw(true); } return Status.OK_STATUS; } }; job.setSystem(true); return job; } private Job createRefreshFeaturesJob(final EClass selection) { Job job = new WorkbenchJob(Messages.EClassHierarchyView_RefreshHierarchy) { /** * @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor) */ @Override public IStatus runInUIThread(IProgressMonitor monitor) { if (featuresViewer.getControl().isDisposed()) { return Status.CANCEL_STATUS; } try { featuresViewer.getControl().setRedraw(false); featuresViewer.setInput(new EClass[] { selection }); featureLabelProvider.setSelection(selection); featuresViewer.refresh(); } finally { // done updating the tree - set redraw back to true featuresViewer.getControl().setRedraw(true); } return Status.OK_STATUS; } }; job.setSystem(true); return job; } /* * (non-Javadoc) * * @see * org.eclipse.emf.ecoretools.ui.AnalysisView#fillToolBar(org.eclipse.jface.action * .IToolBarManager) */ @Override protected void fillToolBar(IToolBarManager toolBar) { IAction ascendantAction = new Action(Messages.EClassHierarchyView_Ascendant, IAction.AS_RADIO_BUTTON) { @Override public void run() { EClassHierarchyView.this.setKind(SortDirection.ASCENDANT); refresh(); } }; ascendantAction.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/elcl16/super_co.gif")); //$NON-NLS-1$ ascendantAction.setChecked(true); IAction descendantAction = new Action(Messages.EClassHierarchyView_Descendant, IAction.AS_RADIO_BUTTON) { @Override public void run() { EClassHierarchyView.this.setKind(SortDirection.DESCENDANT); refresh(); } }; descendantAction.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/elcl16/sub_co.gif")); //$NON-NLS-1$ toolBar.add(ascendantAction); toolBar.add(descendantAction); super.fillToolBar(toolBar); } }