blob: 8faa068fbacd0c9190443a063a4dfb28541d82f4 [file] [log] [blame]
/*
* 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;
}