/** * Copyright (c) 2012 committers of YAKINDU 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: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.sct.ui.editor.partitioning; import static org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil.openEditor; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.internal.ui.viewers.breadcrumb.BreadcrumbViewer; import org.eclipse.debug.internal.ui.viewers.breadcrumb.IBreadcrumbDropDownSite; import org.eclipse.debug.internal.ui.viewers.breadcrumb.TreeViewerDropDown; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.emf.workspace.util.WorkspaceSynchronizer; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.jface.viewers.BaseLabelProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.yakindu.sct.model.sgraph.CompositeElement; import org.yakindu.sct.model.sgraph.Region; import org.yakindu.sct.model.sgraph.State; import org.yakindu.sct.model.sgraph.Statechart; import org.yakindu.sct.model.sgraph.Vertex; import org.yakindu.sct.model.sgraph.provider.SGraphItemProviderAdapterFactory; import org.yakindu.sct.model.sgraph.provider.StateItemProvider; import org.yakindu.sct.model.sgraph.provider.StatechartItemProvider; import org.yakindu.sct.ui.editor.StatechartImages; /** * * @author andreas muelder - Initial contribution and API * */ @SuppressWarnings("restriction") public class DiagramPartitioningBreadcrumbViewer extends BreadcrumbViewer implements ISelectionChangedListener { public DiagramPartitioningBreadcrumbViewer(Composite parent, int style) { super(parent, style); } @Override protected Control createDropDown(Composite parent, IBreadcrumbDropDownSite site, TreePath path) { Control result = createDropDownControl(parent, site, path); return result; } public Control createDropDownControl(Composite parent, final IBreadcrumbDropDownSite site, final TreePath paramPath) { TreeViewerDropDown dropDownTreeViewer = new TreeViewerDropDown() { protected TreeViewer createTreeViewer(Composite composite, int style, final TreePath path) { return createDropDownTreeViewer(composite, paramPath, site); } }; return dropDownTreeViewer.createDropDown(parent, site, paramPath); } protected TreeViewer createDropDownTreeViewer(final Composite composite, TreePath paramPath, final IBreadcrumbDropDownSite site) { Diagram diagram = (Diagram) paramPath.getParentPath().getLastSegment(); TreeViewer viewer = null; if (diagram != null) viewer = createDiagramViewer(composite, diagram); else viewer = createProjectStatechartViewer(composite, (Diagram) paramPath.getLastSegment()); viewer.getControl().addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { getDropDownShell().pack(true); } }); return viewer; } protected TreeViewer createProjectStatechartViewer(Composite composite, Diagram diagram) { TreeViewer viewer = new TreeViewer(composite); viewer.setLabelProvider(new StatechartLabelProvider()); viewer.setContentProvider(new StatechartContentProvider()); viewer.setInput(getProjectStatechartInput(diagram)); viewer.addSelectionChangedListener(this); return viewer; } protected Set<IFile> getProjectStatechartInput(Diagram diagram) { final IFile file = WorkspaceSynchronizer.getFile(diagram.eResource()); final IProject project = file.getProject(); final Set<IFile> result = new HashSet<IFile>(); try { project.accept(new IResourceVisitor() { public boolean visit(IResource resource) throws CoreException { // TODO check for package explorer filters here if (resource.isHidden()) { return false; } if (resource instanceof IFile) { if (file.getFileExtension().equals(resource.getFileExtension())) result.add((IFile) resource); } return true; } }); } catch (CoreException e) { e.printStackTrace(); } return result; } protected TreeViewer createDiagramViewer(final Composite composite, Diagram diagram) { TreeViewer viewer = new TreeViewer(composite); viewer.setLabelProvider(new AdapterFactoryLabelProvider(new SGraphItemProviderAdapterFactory())); viewer.setContentProvider(new AdapterFactoryContentProvider(new BreadcrumbItemProviderAdapterFactory())); EObject element = diagram.getElement(); viewer.setInput(element); viewer.addSelectionChangedListener(this); return viewer; } public void selectionChanged(SelectionChangedEvent event) { Object selection = ((IStructuredSelection) event.getSelection()).getFirstElement(); if (selection instanceof State || selection instanceof Statechart) { Diagram diagram = DiagramPartitioningUtil.getSubDiagram((CompositeElement) selection); openEditor(diagram); } else if (selection instanceof IFile) { openEditor((IFile) selection); } } public static final class StatechartContentProvider implements ITreeContentProvider { private Set<IFile> newInput; public void dispose() { } @SuppressWarnings("unchecked") public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { this.newInput = (Set<IFile>) newInput; } public Object[] getElements(Object inputElement) { return newInput.toArray(new Object[] {}); } public Object[] getChildren(Object parentElement) { return null; } public Object getParent(Object element) { return null; } public boolean hasChildren(Object element) { return false; } } public static final class StatechartLabelProvider extends BaseLabelProvider implements ILabelProvider { public Image getImage(Object element) { return StatechartImages.LOGO.image(); } public String getText(Object element) { return ((IFile) element).getFullPath().toString(); } } public static final class BreadcrumbItemProviderAdapterFactory extends SGraphItemProviderAdapterFactory { @Override public Adapter createStatechartAdapter() { if (statechartItemProvider == null) { statechartItemProvider = new StatechartItemProvider(this) { @Override public Collection<?> getChildren(Object object) { return collectSubdiagrams((CompositeElement) object); } }; } return statechartItemProvider; } @Override public Adapter createStateAdapter() { if (stateItemProvider == null) { stateItemProvider = new StateItemProvider(this) { @Override public Collection<?> getChildren(Object object) { return collectSubdiagrams((CompositeElement) object); } }; } return stateItemProvider; } private Collection<?> collectSubdiagrams(CompositeElement state) { List<Vertex> result = new ArrayList<Vertex>(); EList<Region> regions = state.getRegions(); for (Region region : regions) { EList<Vertex> vertices = region.getVertices(); for (Vertex vertex : vertices) { if (vertex instanceof State && DiagramPartitioningUtil.getSubDiagram((CompositeElement) vertex) != null) { result.add(vertex); } } } return result; } } }