/*******************************************************************************
* Copyright (c) 2004, 2005 Elias Volanakis 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:
* Elias Volanakis - initial API and implementation
�*******************************************************************************/
package com.windowtester.examples.gef.uml.editor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.EventObject;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.requests.SimpleFactory;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.palette.PaletteViewer;
import org.eclipse.gef.ui.palette.PaletteViewerProvider;
import org.eclipse.gef.ui.parts.ContentOutlinePage;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.util.TransferDropTargetListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import com.windowtester.examples.gef.uml.model.ClassDiagram;
import com.windowtester.examples.gef.uml.model.ClassElement;
import com.windowtester.examples.gef.uml.parts.ClassDiagramEditPartFactory;
/**
* A graphical editor with flyout palette that can edit .cd files. The
* binding between the .shapes file extension and this editor is done in
* plugin.xml
*
* @author Elias Volanakis
* @author Phil Quitslund
*/
public class ClassDiagramEditor extends GraphicalEditorWithFlyoutPalette {
/** This is the root of the editor's model. */
private ClassDiagram diagram;
/** Palette component, holding the tools and shapes. */
private static PaletteRoot PALETTE_MODEL;
/** the overview outline page */
private OverviewOutlinePage overviewOutlinePage;
/** Create a new ClassDiagramEditor instance. This is called by the Workspace. */
public ClassDiagramEditor() {
setEditDomain(new DefaultEditDomain(this));
}
/**
* Configure the graphical viewer before it receives contents.
* <p>
* This is the place to choose an appropriate RootEditPart and
* EditPartFactory for your editor. The RootEditPart determines the behavior
* of the editor's "work-area". For example, GEF includes zoomable and
* scrollable root edit parts. The EditPartFactory maps model elements to
* edit parts (controllers).
* </p>
*
* @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer()
*/
protected void configureGraphicalViewer() {
super.configureGraphicalViewer();
GraphicalViewer viewer = getGraphicalViewer();
viewer.setEditPartFactory(new ClassDiagramEditPartFactory());
viewer.setRootEditPart(new ScalableFreeformRootEditPart());
viewer.setKeyHandler(new GraphicalViewerKeyHandler(viewer));
// configure the context menu provider
// ContextMenuProvider cmProvider = new ShapesEditorContextMenuProvider(
// viewer, getActionRegistry());
// viewer.setContextMenu(cmProvider);
// getSite().registerContextMenu(cmProvider, viewer);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.ui.parts.GraphicalEditor#commandStackChanged(java.util.EventObject)
*/
public void commandStackChanged(EventObject event) {
firePropertyChange(IEditorPart.PROP_DIRTY);
super.commandStackChanged(event);
}
private void createOutputStream(OutputStream os) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(getModel());
oos.close();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#createPaletteViewerProvider()
*/
protected PaletteViewerProvider createPaletteViewerProvider() {
return new PaletteViewerProvider(getEditDomain()) {
protected void configurePaletteViewer(PaletteViewer viewer) {
super.configurePaletteViewer(viewer);
// create a drag source listener for this palette viewer
// together with an appropriate transfer drop target listener,
// this will enable
// model element creation by dragging a
// CombinatedTemplateCreationEntries
// from the palette into the editor
// @see ClassDiagramEditor#createTransferDropTargetListener()
viewer
.addDragSourceListener(new TemplateTransferDragSourceListener(
viewer));
}
};
}
/**
* Create a transfer drop target listener. When using a
* CombinedTemplateCreationEntry tool in the palette, this will enable model
* element creation by dragging from the palette.
*
* @see #createPaletteViewerProvider()
*/
private TransferDropTargetListener createTransferDropTargetListener() {
return new TemplateTransferDropTargetListener(getGraphicalViewer()) {
protected CreationFactory getFactory(Object template) {
if (template == ClassElement.class)
return new ClassCreationFactory();
return new SimpleFactory((Class<?>)template);
}
};
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
*/
public void doSave(IProgressMonitor monitor) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
createOutputStream(out);
IFile file = ((IFileEditorInput) getEditorInput()).getFile();
file.setContents(new ByteArrayInputStream(out.toByteArray()), true,
false, // dont keep history
monitor); // progress monitor
getCommandStack().markSaveLocation();
} catch (CoreException ce) {
ce.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.ISaveablePart#doSaveAs()
*/
public void doSaveAs() {
// Show a SaveAs dialog
Shell shell = getSite().getWorkbenchWindow().getShell();
SaveAsDialog dialog = new SaveAsDialog(shell);
dialog.setOriginalFile(((IFileEditorInput) getEditorInput()).getFile());
dialog.open();
IPath path = dialog.getResult();
if (path != null) {
// try to save the editor's contents under a different file name
final IFile file = ResourcesPlugin.getWorkspace().getRoot()
.getFile(path);
try {
new ProgressMonitorDialog(shell).run(false, // don't fork
false, // not cancelable
new WorkspaceModifyOperation() { // run this
// operation
public void execute(final IProgressMonitor monitor) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
createOutputStream(out);
file.create(new ByteArrayInputStream(out
.toByteArray()), // contents
true, // keep saving, even if
// IFile is out of sync with
// the Workspace
monitor); // progress monitor
} catch (CoreException ce) {
ce.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
// set input to the new file
setInput(new FileEditorInput(file));
getCommandStack().markSaveLocation();
} catch (InterruptedException ie) {
// should not happen, since the monitor dialog is not cancelable
ie.printStackTrace();
} catch (InvocationTargetException ite) {
ite.printStackTrace();
}
}
}
@SuppressWarnings("unchecked")
public Object getAdapter(Class type) {
// if (type == IContentOutlinePage.class)
// return new ShapesOutlinePage(new TreeViewer());
if (type == IContentOutlinePage.class)
return getOverviewOutlinePage();
return super.getAdapter(type);
}
ClassDiagram getModel() {
return diagram;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#getPaletteRoot()
*/
protected PaletteRoot getPaletteRoot() {
if (PALETTE_MODEL == null)
PALETTE_MODEL = ClassDiagramEditorPaletteFactory.createPalette();
return PALETTE_MODEL;
}
private void handleLoadException(Exception e) {
System.err.println("** Load failed. Using default model. **");
e.printStackTrace();
diagram = new ClassDiagram();
}
/**
* Set up the editor's inital content (after creation).
*
* @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#initializeGraphicalViewer()
*/
protected void initializeGraphicalViewer() {
super.initializeGraphicalViewer();
GraphicalViewer viewer = getGraphicalViewer();
viewer.setContents(getModel()); // set the contents of this editor
// listen for dropped parts
viewer.addDropTargetListener(createTransferDropTargetListener());
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
*/
public boolean isSaveAsAllowed() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
*/
protected void setInput(IEditorInput input) {
super.setInput(input);
try {
IFile file = ((IFileEditorInput) input).getFile();
ObjectInputStream in = new ObjectInputStream(file.getContents());
diagram = (ClassDiagram) in.readObject();
in.close();
setPartName(file.getName());
} catch (IOException e) {
handleLoadException(e);
} catch (CoreException e) {
handleLoadException(e);
} catch (ClassNotFoundException e) {
handleLoadException(e);
}
}
/**
* Creates an outline pagebook for this editor.
*/
public class ShapesOutlinePage extends ContentOutlinePage {
/**
* Create a new outline page for the shapes editor.
*
* @param viewer
* a viewer (TreeViewer instance) used for this outline page
* @throws IllegalArgumentException
* if editor is null
*/
public ShapesOutlinePage(EditPartViewer viewer) {
super(viewer);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
*/
public void createControl(Composite parent) {
// create outline viewer page
getViewer().createControl(parent);
// configure outline viewer
getViewer().setEditDomain(getEditDomain());
getViewer().setEditPartFactory(new ClassDiagramEditPartFactory());
// configure & add context menu to viewer
// ContextMenuProvider cmProvider = new ShapesEditorContextMenuProvider(
// getViewer(), getActionRegistry());
// getViewer().setContextMenu(cmProvider);
// getSite().registerContextMenu(
// "org.eclipse.gef.examples.shapes.outline.contextmenu",
// cmProvider, getSite().getSelectionProvider());
// hook outline viewer
getSelectionSynchronizer().addViewer(getViewer());
// initialize outline viewer with model
getViewer().setContents(getModel());
// show outline viewer
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.IPage#dispose()
*/
public void dispose() {
// unhook outline viewer
getSelectionSynchronizer().removeViewer(getViewer());
// dispose
super.dispose();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.IPage#getControl()
*/
public Control getControl() {
return getViewer().getControl();
}
/**
* @see org.eclipse.ui.part.IPageBookViewPage#init(org.eclipse.ui.part.IPageSite)
*/
public void init(IPageSite pageSite) {
super.init(pageSite);
ActionRegistry registry = getActionRegistry();
IActionBars bars = pageSite.getActionBars();
String id = ActionFactory.UNDO.getId();
bars.setGlobalActionHandler(id, registry.getAction(id));
id = ActionFactory.REDO.getId();
bars.setGlobalActionHandler(id, registry.getAction(id));
id = ActionFactory.DELETE.getId();
bars.setGlobalActionHandler(id, registry.getAction(id));
}
}
protected OverviewOutlinePage getOverviewOutlinePage()
{
if (null == overviewOutlinePage && null != getGraphicalViewer())
{
RootEditPart rootEditPart = getGraphicalViewer().getRootEditPart();
if (rootEditPart instanceof ScalableFreeformRootEditPart)
{
overviewOutlinePage = new OverviewOutlinePage((ScalableFreeformRootEditPart) rootEditPart);
}
}
return overviewOutlinePage;
}
/* $codepro.preprocessor.if version <= 3.1 $
//Necessary for Eclipse 3.1
protected org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences getPalettePreferences() {
// TODO what should be returned here?
return null;
}
$codepro.preprocessor.endif $ */
}