/** * Copyright 2010 JBoss Inc * * 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.ruleflow.editor.editpart; /* * Copyright 2005 JBoss Inc * * 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. */ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; import org.drools.eclipse.DroolsEclipsePlugin; import org.drools.eclipse.DroolsPluginImages; import org.drools.eclipse.flow.common.editor.editpart.ElementEditPart; import org.drools.eclipse.flow.common.editor.editpart.figure.AbstractElementFigure; import org.drools.eclipse.flow.ruleflow.core.WorkItemWrapper; import org.drools.eclipse.flow.ruleflow.skin.SkinManager; import org.drools.eclipse.flow.ruleflow.skin.SkinProvider; import org.drools.eclipse.preferences.IDroolsConstants; import org.drools.eclipse.util.ProjectClassLoader; import org.drools.process.core.Work; import org.drools.process.core.WorkDefinition; import org.drools.process.core.WorkDefinitionExtension; import org.drools.process.core.WorkEditor; import org.eclipse.draw2d.ChopboxAnchor; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.RoundedRectangle; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CommandStack; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.views.properties.IPropertySource; import org.jbpm.workflow.core.node.WorkItemNode; /** * EditPart for a Task node. * * @author <a href="mailto:kris_verlaenen@hotmail.com">Kris Verlaenen</a> */ public class WorkItemEditPart extends ElementEditPart { private String SKIN = DroolsEclipsePlugin.getDefault().getPreferenceStore().getString(IDroolsConstants.SKIN); private static final Color color = new Color(Display.getCurrent(), 255, 250, 205); protected IFigure createFigure() { SkinProvider skinProvider = SkinManager.getInstance().getSkinProvider(SKIN); WorkItemFigureInterface figure = skinProvider.createWorkItemFigure(); Rectangle constraint = getElementWrapper().getConstraint(); if (constraint.width == -1) { constraint.width = figure.getSize().width; } if (constraint.height == -1) { constraint.height = figure.getSize().height; } getElementWrapper().setConstraint(constraint); String icon = null; WorkDefinition workDefinition = getWorkDefinition(); if (workDefinition instanceof WorkDefinitionExtension) { icon = ((WorkDefinitionExtension) workDefinition).getIcon(); } if (icon == null) { icon = "icons/action.gif"; } Image image = DroolsPluginImages.getImage(icon); if (image == null) { IJavaProject javaProject = getProject(); if (javaProject != null) { try { ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader newLoader = ProjectClassLoader.getProjectClassLoader(javaProject); try { Thread.currentThread().setContextClassLoader(newLoader); image = ImageDescriptor.createFromURL( newLoader.getResource(icon)).createImage(); DroolsPluginImages.putImage(icon, image); } finally { Thread.currentThread().setContextClassLoader(oldLoader); } } catch (Exception e) { DroolsEclipsePlugin.log(e); } } } figure.setIcon(image); return figure; } protected WorkItemWrapper getWorkItemWrapper() { return (WorkItemWrapper) getElementWrapper(); } private WorkDefinition getWorkDefinition() { return getWorkItemWrapper().getWorkDefinition(); } // public ConnectionAnchor getSourceConnectionAnchor(Request request) { // Point p = ((DropRequest) request).getLocation(); // return ((WorkItemFigure) getFigure()).getOutgoingConnectionAnchorAt(p); // } protected void doubleClicked() { super.doubleClicked(); // open custom editor pane if one exists WorkDefinition workDefinition = getWorkDefinition(); if (workDefinition instanceof WorkDefinitionExtension) { String editor = ((WorkDefinitionExtension) workDefinition).getCustomEditor(); if (editor != null) { Work work = openEditor(editor, workDefinition); if (work != null) { SetWorkCommand setCommand = new SetWorkCommand(); setCommand.setPropertyValue(work); CommandStack stack = getViewer().getEditDomain().getCommandStack(); stack.execute(setCommand); } } } } @SuppressWarnings("unchecked") private Work openEditor(String editorClassName, WorkDefinition workDefinition) { IJavaProject javaProject = getProject(); if (javaProject != null) { try { ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader newLoader = ProjectClassLoader.getProjectClassLoader(javaProject); try { Thread.currentThread().setContextClassLoader(newLoader); Class<WorkEditor> editorClass = (Class<WorkEditor>) newLoader.loadClass(editorClassName); Constructor<WorkEditor> constructor = editorClass.getConstructor(Shell.class); WorkEditor editor = constructor.newInstance(getViewer().getControl().getShell()); editor.setWorkDefinition(workDefinition); WorkItemNode workItemNode = getWorkItemWrapper().getWorkItemNode(); editor.setWork(workItemNode.getWork()); boolean result = editor.show(); return result ? editor.getWork() : null; } finally { Thread.currentThread().setContextClassLoader(oldLoader); } } catch (Exception e) { DroolsEclipsePlugin.log(e); } } return null; } public static interface WorkItemFigureInterface extends IFigure { void setIcon(Image icon); } public static class WorkItemFigure extends AbstractElementFigure implements WorkItemFigureInterface { private RoundedRectangle rectangle; private ConnectionAnchor defaultConnectionAnchor; private List<ConnectionAnchor> outgoingConnectionAnchors = new ArrayList<ConnectionAnchor>(); public WorkItemFigure() { defaultConnectionAnchor = new ChopboxAnchor(this); // FixedConnectionAnchor c = new FixedConnectionAnchor(this); // outgoingConnectionAnchors.add(c); // c = new FixedConnectionAnchor(this); // outgoingConnectionAnchors.add(c); } public void layoutConnectionAnchors() { // FixedConnectionAnchor c = (FixedConnectionAnchor) outgoingConnectionAnchors.get(0); // c.setOffsetV(getBounds().height); // c.setOffsetH(0); // c = (FixedConnectionAnchor) outgoingConnectionAnchors.get(1); // c.setOffsetV(getBounds().height); // c.setOffsetH(getBounds().width); } public ConnectionAnchor getOutgoingConnectionAnchorAt(Point p) { ConnectionAnchor closest = null; long min = Long.MAX_VALUE; for (ConnectionAnchor c: outgoingConnectionAnchors) { Point p2 = c.getLocation(null); long d = p.getDistance2(p2); if (d < min) { min = d; closest = c; } } if (min > 100) { return defaultConnectionAnchor; } return closest; } protected void customizeFigure() { rectangle = new RoundedRectangle(); rectangle.setCornerDimensions(new Dimension(25, 25)); add(rectangle, 0); rectangle.setBackgroundColor(color); rectangle.setBounds(getBounds()); setSelected(false); } public void setBounds(Rectangle rectangle) { super.setBounds(rectangle); this.rectangle.setBounds(rectangle); } public void setSelected(boolean b) { super.setSelected(b); rectangle.setLineWidth(b ? 3 : 1); repaint(); } public void validate() { if(isValid()) return; layoutConnectionAnchors(); super.validate(); } } private class SetWorkCommand extends Command { protected Work propertyValue; protected Work undoValue; protected IPropertySource target; public SetWorkCommand() { super("Set Work Value"); } public boolean canExecute() { return true; } public void execute() { undoValue = getWorkItemWrapper().getWorkItemNode().getWork(); getWorkItemWrapper().getWorkItemNode().setWork(propertyValue); } public void redo() { execute(); } public void setPropertyValue(Work val) { propertyValue = val; } public void undo() { getWorkItemWrapper().getWorkItemNode().setWork(undoValue); } } }