/*
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.eclipse.flow.common.editor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.EventObject;
import org.drools.eclipse.DroolsEclipsePlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspace;
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.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.ContextMenuProvider;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.KeyStroke;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.editparts.ScalableRootEditPart;
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.AlignmentAction;
import org.eclipse.gef.ui.actions.DirectEditAction;
import org.eclipse.gef.ui.actions.GEFActionConstants;
import org.eclipse.gef.ui.actions.ToggleGridAction;
import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchPart;
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.views.contentoutline.IContentOutlinePage;
/**
* Abstract implementation of a graphical editor.
*/
public abstract class GenericModelEditor extends GraphicalEditorWithPalette { // implements ITabbedPropertySheetPageContributor {
private Object model;
private boolean savePreviouslyNeeded = false;
private KeyHandler sharedKeyHandler;
private PaletteRoot root;
private OverviewOutlinePage overviewOutlinePage;
public GenericModelEditor() {
setEditDomain(new DefaultEditDomain(this));
}
protected void setModel(Object model) {
this.model = model;
}
public Object getModel() {
return model;
}
@SuppressWarnings("unchecked")
protected void createActions() {
super.createActions();
ActionRegistry registry = getActionRegistry();
IAction action = new DirectEditAction((IWorkbenchPart) this);
registry.registerAction(action);
getSelectionActions().add(action.getId());
action = new AlignmentAction((IWorkbenchPart) this,
PositionConstants.LEFT);
registry.registerAction(action);
getSelectionActions().add(action.getId());
action = new AlignmentAction((IWorkbenchPart) this,
PositionConstants.CENTER);
registry.registerAction(action);
getSelectionActions().add(action.getId());
action = new AlignmentAction((IWorkbenchPart) this,
PositionConstants.RIGHT);
registry.registerAction(action);
getSelectionActions().add(action.getId());
action = new AlignmentAction((IWorkbenchPart) this,
PositionConstants.TOP);
registry.registerAction(action);
getSelectionActions().add(action.getId());
action = new AlignmentAction((IWorkbenchPart) this,
PositionConstants.MIDDLE);
registry.registerAction(action);
getSelectionActions().add(action.getId());
action = new AlignmentAction((IWorkbenchPart) this,
PositionConstants.BOTTOM);
registry.registerAction(action);
getSelectionActions().add(action.getId());
}
public void commandStackChanged(EventObject event) {
if (isDirty()) {
if (!savePreviouslyNeeded()) {
setSavePreviouslyNeeded(true);
firePropertyChange(IEditorPart.PROP_DIRTY);
}
} else {
setSavePreviouslyNeeded(false);
firePropertyChange(IEditorPart.PROP_DIRTY);
}
super.commandStackChanged(event);
}
protected abstract void writeModel(OutputStream os) throws IOException;
protected void configureGraphicalViewer() {
super.configureGraphicalViewer();
getGraphicalViewer().setRootEditPart(new ScalableRootEditPart());
getGraphicalViewer().setEditPartFactory(createEditPartFactory());
getGraphicalViewer().setKeyHandler(
new GraphicalViewerKeyHandler(getGraphicalViewer())
.setParent(getCommonKeyHandler()));
IAction showGrid = new ToggleGridAction(getGraphicalViewer());
getActionRegistry().registerAction(showGrid);
ContextMenuProvider provider = new GenericContextMenuProvider(
getGraphicalViewer(), getActionRegistry());
getGraphicalViewer().setContextMenu(provider);
getSite().registerContextMenu("org.drools.eclipse.flow.editor.contextmenu",
provider, getGraphicalViewer());
}
protected abstract EditPartFactory createEditPartFactory();
protected void initializeGraphicalViewer() {
getGraphicalViewer().setContents(model);
}
public void doSave(IProgressMonitor monitor) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeModel(out);
IFile file = ((IFileEditorInput) getEditorInput()).getFile();
file.setContents(new ByteArrayInputStream(out.toByteArray()), true,
false, monitor);
out.close();
getCommandStack().markSaveLocation();
} catch (Exception e) {
e.printStackTrace();
}
}
public void doSaveAs() {
SaveAsDialog dialog = new SaveAsDialog(getSite().getWorkbenchWindow()
.getShell());
dialog.setOriginalFile(((IFileEditorInput) getEditorInput()).getFile());
dialog.open();
IPath path = dialog.getResult();
if (path == null) {
return;
}
IWorkspace workspace = ResourcesPlugin.getWorkspace();
final IFile file = workspace.getRoot().getFile(path);
WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
public void execute(final IProgressMonitor monitor)
throws CoreException {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
writeModel(out);
file.create(new ByteArrayInputStream(out.toByteArray()),
true, monitor);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
};
try {
new ProgressMonitorDialog(getSite().getWorkbenchWindow().getShell())
.run(false, true, op);
setInput(new FileEditorInput(file));
getCommandStack().markSaveLocation();
} catch (Exception e) {
e.printStackTrace();
}
}
protected KeyHandler getCommonKeyHandler() {
if (sharedKeyHandler == null) {
sharedKeyHandler = new KeyHandler();
sharedKeyHandler
.put(KeyStroke.getPressed(SWT.DEL, 127, 0),
getActionRegistry().getAction(
ActionFactory.DELETE.getId()));
sharedKeyHandler.put(KeyStroke.getPressed(SWT.F2, 0),
getActionRegistry().getAction(
GEFActionConstants.DIRECT_EDIT));
}
return sharedKeyHandler;
}
public boolean isDirty() {
return isSaveOnCloseNeeded();
}
public boolean isSaveAsAllowed() {
return true;
}
public boolean isSaveOnCloseNeeded() {
return getCommandStack().isDirty();
}
private boolean savePreviouslyNeeded() {
return savePreviouslyNeeded;
}
private void setSavePreviouslyNeeded(boolean value) {
savePreviouslyNeeded = value;
}
protected PaletteRoot getPaletteRoot() {
if (root == null) {
root = createPalette();
}
return root;
}
protected abstract PaletteRoot createPalette();
protected void setInput(IEditorInput input) {
super.setInput(input);
if (input instanceof IFileEditorInput) {
IFile file = getFile();
if (file != null) {
setPartName(file.getName());
}
try {
InputStream is = file.getContents(false);
createModel(is);
} catch (Throwable t) {
DroolsEclipsePlugin.log(t);
}
} else if (input instanceof IStorageEditorInput) {
try {
IStorage storage = ((IStorageEditorInput) input).getStorage();
setPartName(storage.getName());
InputStream is = storage.getContents();
createModel(is);
} catch (Throwable t) {
DroolsEclipsePlugin.log(t);
}
}
if (getGraphicalViewer() != null) {
initializeGraphicalViewer();
}
}
public IFile getFile() {
IEditorInput input = getEditorInput();
if (!(input instanceof IFileEditorInput)) {
return null;
}
return ((IFileEditorInput) getEditorInput()).getFile();
}
public IProject getProject() {
IFile file = getFile();
if (file != null) {
return file.getProject();
}
return null;
}
public IJavaProject getJavaProject() {
IProject project = getProject();
if (project != null) {
try {
if (project.getNature("org.eclipse.jdt.core.javanature") != null) {
IJavaProject javaProject = JavaCore.create(project);
if (javaProject.exists()){
return javaProject;
}
}
} catch (CoreException e) {
DroolsEclipsePlugin.log(e);
}
}
return null;
}
protected abstract void createModel(InputStream is);
public Object getAdapter(@SuppressWarnings("rawtypes") Class type) {
if (type == IContentOutlinePage.class) {
return getOverviewOutlinePage();
}
if (type == ZoomManager.class) {
return ((ScalableRootEditPart) getGraphicalViewer()
.getRootEditPart()).getZoomManager();
}
// if (type == IPropertySheetPage.class) {
// return new TabbedPropertySheetPage(this);
// }
return super.getAdapter(type);
}
protected OverviewOutlinePage getOverviewOutlinePage() {
if (null == overviewOutlinePage && null != getGraphicalViewer()) {
ScalableRootEditPart rootEditPart = (ScalableRootEditPart) getGraphicalViewer()
.getRootEditPart();
overviewOutlinePage = new OverviewOutlinePage(rootEditPart);
}
return overviewOutlinePage;
}
public String getContributorId() {
return getSite().getId();
}
/**
* Writes the content of this editor to the given stream.
* Possible formats are for example SWT.IMAGE_BMP, IMAGE_GIF,
* IMAGE_JPEG, IMAGE_PNG.
* @param stream
* @param format
*/
public void createImage(OutputStream stream, int format) {
SWTGraphics g = null;
GC gc = null;
Image image = null;
LayerManager layerManager = (LayerManager)
getGraphicalViewer().getEditPartRegistry().get(LayerManager.ID);
IFigure figure = layerManager.getLayer(LayerConstants.PRINTABLE_LAYERS);
Rectangle r = figure.getBounds();
try {
image = new Image(Display.getDefault(), r.width, r.height);
gc = new GC(image);
g = new SWTGraphics(gc);
g.translate(r.x * -1, r.y * -1);
figure.paint(g);
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] { image.getImageData() };
imageLoader.save(stream, format);
} catch (Throwable t) {
DroolsEclipsePlugin.log(t);
} finally {
if (g != null) {
g.dispose();
}
if (gc != null) {
gc.dispose();
}
if (image != null) {
image.dispose();
}
}
}
}