/******************************************************************************* * Copyright (c) 2013 Arapiki Solutions Inc. * 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: * psmith - initial API and * implementation and/or initial documentation *******************************************************************************/ package com.buildml.eclipse.packages.handlers; import java.util.List; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import com.buildml.eclipse.bobj.UIFileGroup; import com.buildml.eclipse.packages.PackageDiagramEditor; import com.buildml.eclipse.packages.layout.LayoutAlgorithm; import com.buildml.eclipse.utils.AlertDialog; import com.buildml.eclipse.utils.EclipsePartUtils; import com.buildml.eclipse.utils.GraphitiUtils; import com.buildml.eclipse.utils.UndoOpAdapter; import com.buildml.model.IActionMgr; import com.buildml.model.IBuildStore; import com.buildml.model.IPackageMemberMgr; import com.buildml.model.IPackageRootMgr; import com.buildml.model.IPackageMemberMgr.MemberLocation; import com.buildml.model.undo.ActionUndoOp; import com.buildml.model.undo.MultiUndoOp; import com.buildml.utils.errors.ErrorCode; /** * An Eclipse UI Handler for managing the "New Action" UI command. * * @author Peter Smith <psmith@arapiki.com> */ public class HandlerNewAction extends AbstractHandler { /*=====================================================================================* * PUBLIC METHODS *=====================================================================================*/ /* (non-Javadoc) * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { /* locate all the necessary things in our environment */ IBuildStore buildStore = EclipsePartUtils.getActiveBuildStore(); PackageDiagramEditor pde = EclipsePartUtils.getActivePackageDiagramEditor(); List<Object> selectedObjects = GraphitiUtils.getSelection(); if ((buildStore == null) || (pde == null) || (selectedObjects == null)) { return null; } IActionMgr actionMgr = buildStore.getActionMgr(); IPackageMemberMgr pkgMemberMgr = buildStore.getPackageMemberMgr(); IPackageRootMgr pkgRootMgr = buildStore.getPackageRootMgr(); /* * For now, add a single new shell command action. The action will be created * in the current diagram editor's package, with the package's source root * used as the action's "directory" */ int pkgId = pde.getPackageId(); int srcRootPathId = pkgRootMgr.getPackageRoot(pkgId, IPackageRootMgr.SOURCE_ROOT); if (srcRootPathId == ErrorCode.NOT_FOUND) { AlertDialog.displayErrorDialog("Can't add action", "Invalid package ID number."); return null; } int parentActionId = actionMgr.getRootAction("root"); int actionId = actionMgr.addShellCommandAction(parentActionId, srcRootPathId, "#empty"); if (actionId < 0) { AlertDialog.displayErrorDialog("Can't add action", "Unable to add new shell command action."); return null; } pkgMemberMgr.setPackageOfMember(IPackageMemberMgr.TYPE_ACTION, actionId, pkgId); /* add the creation of the new action to the undo/redo stack */ MultiUndoOp multiOp = new MultiUndoOp(); ActionUndoOp newActionOp = new ActionUndoOp(buildStore, actionId); newActionOp.recordNewAction(); multiOp.add(newActionOp); /* * If the user selected a UIFileGroup, attach that file group to the new action's "Input" slot. */ if (selectedObjects.size() == 1) { /* insert selected file group into action's "input" slot */ int fileGroupId = ((UIFileGroup)(selectedObjects.get(0))).getId(); /* record this slot change in our undo/redo stack */ ActionUndoOp newSlotOp = new ActionUndoOp(buildStore, actionId); newSlotOp.recordSlotChange(IActionMgr.INPUT_SLOT_ID, null, fileGroupId); multiOp.add(newSlotOp); /* * Finally, position the action to right of UIFileGroup. This doesn't need to be in * undo/redo history because the action didn't exist until now. */ MemberLocation fgLocation = pkgMemberMgr.getMemberLocation( IPackageMemberMgr.TYPE_FILE_GROUP, fileGroupId); if (fgLocation != null) { int x = fgLocation.x; int y = fgLocation.y; LayoutAlgorithm layoutAlgorithm = pde.getLayoutAlgorithm(); x += layoutAlgorithm.getSizeOfPictogram(IPackageMemberMgr.TYPE_FILE_GROUP).getWidth(); x += layoutAlgorithm.getXPadding(); pkgMemberMgr.setMemberLocation(IPackageMemberMgr.TYPE_ACTION, actionId, x, y); } } /* record this undo/redo operation, but don't invoke it - the work is already done */ new UndoOpAdapter("New Action", multiOp).record(); return null; } /*-------------------------------------------------------------------------------------*/ /* * This handler is only enabled when 0 or 1 UIActions are selected. In the case of 0 * UIActions selected, we'll actually see that the background Diagram is selected. */ @Override public boolean isEnabled() { /* fetch the list of selected business objects (actions, file groups, etc) */ List<Object> selectedObjects = GraphitiUtils.getSelection(); if (selectedObjects == null) { return false; } /* there must be exactly 0 or 1 things selected */ int size = selectedObjects.size(); if (size > 1) { return false; } /* if there's one thing, it must be a UIFileGroup */ if (size == 1) { return selectedObjects.get(0) instanceof UIFileGroup; } return true; } /*-------------------------------------------------------------------------------------*/ }