/* * Copyright 2000-2012 JetBrains s.r.o. * * 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 com.intellij.designer.componentTree; import com.intellij.designer.designSurface.AbstractEditOperation; import com.intellij.designer.designSurface.FeedbackTreeLayer; import com.intellij.designer.designSurface.OperationContext; import com.intellij.designer.model.RadComponent; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; import java.awt.*; /** * @author Alexander Lobas */ public abstract class TreeEditOperation extends AbstractEditOperation { protected RadComponent myTarget; protected boolean myInsertBefore; public TreeEditOperation(RadComponent container, OperationContext context) { super(container, context); } public static boolean isTarget(RadComponent container, OperationContext context) { Point location = context.getLocation(); RadComponent target = context.getArea().findTarget(location.x, location.y, null); if (target == container) { FeedbackTreeLayer layer = context.getArea().getFeedbackTreeLayer(); return !layer.isBeforeLocation(target, location.x, location.y) && !layer.isAfterLocation(target, location.x, location.y); } return true; } protected Object[] getChildren() { return myContainer.getTreeChildren(); } @Override public void showFeedback() { Point location = myContext.getLocation(); FeedbackTreeLayer layer = myContext.getArea().getFeedbackTreeLayer(); myTarget = myContext.getArea().findTarget(location.x, location.y, null); if (myContainer == myTarget) { layer.mark(myTarget, FeedbackTreeLayer.INSERT_SELECTION); } else if (myTarget != null && isChildren(myTarget)) { myInsertBefore = layer.isBeforeLocation(myTarget, location.x, location.y); layer.mark(myTarget, myInsertBefore ? FeedbackTreeLayer.INSERT_BEFORE : FeedbackTreeLayer.INSERT_AFTER); } else { myTarget = null; eraseFeedback(); } } protected final boolean isChildren(RadComponent component) { return ArrayUtil.indexOf(getChildren(), component) != -1; } @Override public void eraseFeedback() { myContext.getArea().getFeedbackTreeLayer().unmark(); } @Override public boolean canExecute() { if (myTarget == null) { return false; } if (myContext.isMove() && myTarget != myContainer) { if (myComponents.contains(myTarget)) { return false; } Object[] children = getChildren(); int index = ArrayUtil.indexOf(children, myTarget) + (myInsertBefore ? -1 : 1); if (0 <= index && index < children.length) { return !myComponents.contains(children[index]); } } return true; } @Override public void execute() throws Exception { if (myTarget == myContainer) { execute(null); } else if (myInsertBefore) { execute(myTarget); } else { Object[] children = getChildren(); int index = ArrayUtil.indexOf(children, myTarget) + 1; if (index < children.length) { execute((RadComponent)children[index]); } else { execute(null); } } } protected abstract void execute(@Nullable RadComponent insertBefore) throws Exception; }