/** * Copyright (c) 2006, 2007 Borland Software Corporation * * 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: * bblajer - initial API and implementation */ package org.eclipse.gmf.runtime.lite.parts; import java.util.Collections; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.IFigure; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.workspace.WorkspaceEditingDomainFactory; import org.eclipse.gef.EditDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.GraphicalViewer; import org.eclipse.gef.commands.CommandStack; import org.eclipse.gef.commands.CommandStackEvent; import org.eclipse.gef.commands.CommandStackEventListener; import org.eclipse.gef.editparts.ZoomManager; import org.eclipse.gef.palette.PaletteRoot; import org.eclipse.gef.ui.actions.ActionRegistry; import org.eclipse.gef.ui.actions.SelectionAction; import org.eclipse.gef.ui.actions.StackAction; import org.eclipse.gef.ui.actions.WorkbenchPartAction; import org.eclipse.gef.ui.views.palette.PalettePage; import org.eclipse.gmf.internal.runtime.lite.Activator; import org.eclipse.gmf.runtime.lite.services.DefaultDiagramLayouter; import org.eclipse.gmf.runtime.lite.services.IDiagramLayouter; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.PageBook; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.eclipse.ui.views.properties.IPropertySheetPage; /** * This class serves as the base class for the generated diagram view parts. * @author bblajer */ public abstract class DiagramViewPart extends ViewPart implements IDiagramManager { private DiagramDisplayer myDiagramDisplayer; private PageBook myBook; private Control myUninitializedControl; private CommandStackEventListener mySaveListener = new CommandStackEventListener() { public void stackChanged(CommandStackEvent event) { assert event.getSource() == myDiagramDisplayer.getCommandStack(); if (event.isPostChangeEvent()) { try { myDiagramDisplayer.save(getSaveOptions(), new NullProgressMonitor()); myDiagramDisplayer.getCommandStack().markSaveLocation(); } catch (CoreException e) { Activator.getDefault().getLog().log(e.getStatus()); } } } }; @Override public void init(IViewSite site) throws PartInitException { super.init(site); } /** * Returns the options with which the resources will be saved. Subclasses should override. */ protected Map<?, ?> getSaveOptions() { return Collections.emptyMap(); } @Override public void dispose() { if (myDiagramDisplayer != null) { disposeDisplayer(myDiagramDisplayer); } myDiagramDisplayer = null; super.dispose(); } @Override public void createPartControl(Composite parent) { myBook = new PageBook(parent, SWT.NONE); myUninitializedControl = createUninitializedControl(myBook); myBook.showPage(myUninitializedControl); } @Override public void setFocus() { if (myDiagramDisplayer != null) { myDiagramDisplayer.setFocus(); return; } myBook.setFocus(); } /** * Returns the editing domain to be used for the new diagram if no editing domain was specified in {@link #showDiagram(TransactionalEditingDomain, URI)}. * Subclasses may reimplement or extend. */ protected TransactionalEditingDomain createEditingDomain() { TransactionalEditingDomain editingDomain = WorkspaceEditingDomainFactory.INSTANCE.createEditingDomain(); editingDomain.getResourceSet().eAdapters().add(new AdapterFactoryEditingDomain.EditingDomainProvider(editingDomain)); return editingDomain; } protected abstract void createActions(); /** * Shows the given diagram in the viewer. * @param editingDomain the editing domain that should be used for loading the diagram or <code>null</code> if the viewer should create {@link #createEditingDomain() a default instance}. * @param diagramURI the URI to load the diagram from. */ public final boolean showDiagram(TransactionalEditingDomain editingDomain, URI diagramURI) { DiagramDisplayer oldDiagramDisplayer = myDiagramDisplayer; boolean result = false; if (diagramURI == null) { if (oldDiagramDisplayer == null) { return true; } myBook.showPage(myUninitializedControl); } else { if (editingDomain == null) { editingDomain = createEditingDomain(); } myDiagramDisplayer = new DiagramDisplayer(this, createEditDomain(), editingDomain); initDisplayer(myDiagramDisplayer); try { setInput(diagramURI); myDiagramDisplayer.createViewer(myBook); createActions(); myBook.showPage(myDiagramDisplayer.getTopLevelControl()); result = true; } catch (CoreException e) { Activator.getDefault().getLog().log(e.getStatus()); ErrorDialog.openError(getSite().getShell(), "Error", "Failed to open diagram", e.getStatus()); if (myDiagramDisplayer.getTopLevelControl() != null && !myDiagramDisplayer.getTopLevelControl().isDisposed()) { disposeDisplayer(myDiagramDisplayer); myDiagramDisplayer = oldDiagramDisplayer; //prevent navigation from the old diagram. oldDiagramDisplayer = null; } } } if (oldDiagramDisplayer != null) { disposeDisplayer(oldDiagramDisplayer); } updateActionBars(); return result; } protected void initDisplayer(DiagramDisplayer diagramDisplayer) { diagramDisplayer.getCommandStack().addCommandStackEventListener(mySaveListener); } protected void disposeDisplayer(DiagramDisplayer diagramDisplayer) { if (diagramDisplayer.getTopLevelControl() != null) { diagramDisplayer.getTopLevelControl().dispose(); } diagramDisplayer.getCommandStack().removeCommandStackEventListener(mySaveListener); diagramDisplayer.dispose(); } protected abstract void updateActionBars(); public void configureGraphicalViewer() { getGraphicalViewer().getControl().setBackground(ColorConstants.listBackground); } protected double[] getZoomLevels() { double[] result = {.05, .1, .25, .5, .75, 1, 1.25, 1.5, 1.75, 2, 4}; return result; } public abstract void configurePalette(PaletteRoot paletteRoot); /** * Sets the input for the diagram. Implementors should load the contents from the given URI and initialize the diagram. * @throws CoreException if the diagram with the specified URI cannot be loaded for any reason. */ protected abstract void setInput(URI diagramURI) throws CoreException; /** * Creates edit domain that will be used for this viewer. This method is called once for each diagram being displayed in the editor. * Subclasses may extend. */ protected EditDomain createEditDomain() { EditDomain domain = new EditDomain(); return domain; } public final TransactionalEditingDomain getEditingDomain() { if (myDiagramDisplayer == null) { return null; } return myDiagramDisplayer.getEditingDomain(); } protected final EditDomain getEditDomain() { if (myDiagramDisplayer == null) { return null; } return myDiagramDisplayer.getEditDomain(); } protected final CommandStack getCommandStack() { if (myDiagramDisplayer == null) { return null; } return getEditDomain().getCommandStack(); } protected final ZoomManager getZoomManager() { if (myDiagramDisplayer == null) { return null; } return myDiagramDisplayer.getZoomManager(); } protected final ActionRegistry getActionRegistry() { if (myDiagramDisplayer == null) { return null; } return myDiagramDisplayer.getActionRegistry(); } protected final GraphicalViewer getGraphicalViewer() { if (myDiagramDisplayer == null) { return null; } return myDiagramDisplayer.getGraphicalViewer(); } protected IPropertySheetPage getPropertySheetPage() { if (myDiagramDisplayer == null) { return null; } return myDiagramDisplayer.getPropertySheetPage(); } protected IDiagramLayouter getDiagramLayouter() { if (myDiagramDisplayer == null) { return null; } return new DefaultDiagramLayouter(); } @Override public Object getAdapter(Class type) { if (type == IPropertySheetPage.class) { return getPropertySheetPage(); } else if (type == IContentOutlinePage.class) { // return getOutlinePage(); return null; } else if (type == ZoomManager.class) { return getZoomManager(); } else if (type == IDiagramLayouter.class) { return getDiagramLayouter(); } else if (type == PalettePage.class) { return myDiagramDisplayer.getPalettePage(); } else if (type == GraphicalViewer.class) { return getGraphicalViewer(); } else if (type == CommandStack.class) { return getCommandStack(); } else if (type == ActionRegistry.class) { return getActionRegistry(); } else if (type == EditPart.class && getGraphicalViewer() != null) { return getGraphicalViewer().getRootEditPart(); } else if (type == IFigure.class && getGraphicalViewer() != null) { return ((GraphicalEditPart)getGraphicalViewer().getRootEditPart()).getFigure(); } return super.getAdapter(type); } /** * Adds an action to this editor's <code>ActionRegistry</code>. * * @param action * the action to add. */ protected void addAction(IAction action) { myDiagramDisplayer.addAction(action); } /** * Adds an editor action to this editor. * * <p> * Editor actions are actions that depend and work on the editor. * * @param action * the editor action */ protected void addEditorAction(WorkbenchPartAction action) { myDiagramDisplayer.addEditorAction(action); } /** * Adds an <code>EditPart</code> action to this editor. * * <p> * <code>EditPart</code> actions are actions that depend and work on the * selected <code>EditPart</code>s. * * @param action * the <code>EditPart</code> action */ protected void addEditPartAction(SelectionAction action) { myDiagramDisplayer.addEditPartAction(action); } /** * Adds an <code>CommandStack</code> action to this editor. * * <p> * <code>CommandStack</code> actions are actions that depend and work on * the <code>CommandStack</code>. * * @param action * the <code>CommandStack</code> action */ protected void addStackAction(StackAction action) { myDiagramDisplayer.addStackAction(action); } /** * Returns the control this viewer displays when no input has been set. * Subclasses may reimplement. */ protected Control createUninitializedControl(Composite parent) { Label result = new Label(parent, SWT.NONE); result.setText("There is no diagram to display or the diagram failed to load"); return result; } public abstract AdapterFactory getDomainAdapterFactory(); public abstract void initializeGraphicalViewer(); public abstract boolean isFlyoutPalette(); }