/******************************************************************************* * Copyright (c) 2016 BREDEX GmbH. * 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.client.ui.rcp.utils; import org.eclipse.jface.viewers.ViewerDropAdapter; import org.eclipse.jubula.client.core.model.IAbstractContainerPO; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.core.model.ISpecTestCasePO; import org.eclipse.jubula.client.core.model.ITestJobPO; import org.eclipse.jubula.client.core.model.ITestSuitePO; /** * Class used to determine whether an insertion of a new node is allowed * and to calculate exactly where to insert a node in an Editor * Used both for validating and executing drop and paste actions * The validation takes into account only the types of the nodes, * not other requirements like parameters, etc. * @author BREDEX GmbH * */ public class NodeTargetCalculator { /** hidden constructor */ private NodeTargetCalculator() { // empty } /** * Calculates exactly where to insert a new node * we assume that the insertion has been validated before * by calling canInsert * @param source the source * @param target the target * @param pos the position (BEFORE, AFTER, ON, etc) * @param expanded whether the target is expanded * @return the drop target data or null if no drop */ public static NodeTarget calcNodeTarget(INodePO source, INodePO target, int pos, boolean expanded) { INodePO top = target.getSpecAncestor(); if (top instanceof ISpecTestCasePO || top instanceof ITestSuitePO) { return calcNodeTargetTCEditor(source, target, pos, expanded); } if (top instanceof ITestJobPO) { int posi = top.indexOf(target); return new NodeTarget(posi + 1, top); } return null; } /** * Calculates the drop target in a Test Case Editor * @param source the source (null if new) * @param target the target * @param pos the position * @param expanded whether target is expanded * @return the position or null */ private static NodeTarget calcNodeTargetTCEditor(INodePO source, INodePO target, int pos, boolean expanded) { NodeTarget res = null; if (target instanceof ISpecTestCasePO || target instanceof ITestSuitePO || (target instanceof IAbstractContainerPO && pos != ViewerDropAdapter.LOCATION_BEFORE)) { if (expanded) { res = new NodeTarget(0, target); } else { res = new NodeTarget(target.getNodeListSize(), target); } } else if (target instanceof IAbstractContainerPO) { // the location must be BEFORE, so we insert to the end of the previous container int posi = target.getParentNode().indexOf(target); if (posi != 0) { INodePO newTarg = target.getParentNode(). getUnmodifiableNodeList().get(posi - 1); res = new NodeTarget(newTarg.getNodeListSize(), newTarg); } } else { int newPos = target.getParentNode().indexOf(target); if (pos != ViewerDropAdapter.LOCATION_BEFORE) { newPos++; } res = new NodeTarget(newPos, target.getParentNode()); } if (res != null && source != null && source.hasCircularDependences( res.getNode().getSpecAncestor())) { return null; } return res; } /** Class representing a drop target */ public static class NodeTarget { /** the node */ private INodePO m_node; /** the position */ private int m_position; /** * Constructor * @param pos position * @param node node */ public NodeTarget(int pos, INodePO node) { m_node = node; m_position = pos; } /** * getter * @return node */ public INodePO getNode() { return m_node; } /** * getter * @return position */ public int getPos() { return m_position; } } }