blob: dba3bbb38d72ab779a12d1459751c087fdebb1cb [file] [log] [blame]
/*
* Copyright 2000-2009 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.uiDesigner.designSurface;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.uiDesigner.FormEditingUtil;
import com.intellij.uiDesigner.UIDesignerBundle;
import com.intellij.uiDesigner.lw.IComponent;
import com.intellij.uiDesigner.radComponents.RadComponent;
import com.intellij.uiDesigner.radComponents.RadContainer;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
/**
* @author yole
*/
public class PasteProcessor extends EventProcessor {
private final GridInsertProcessor myGridInsertProcessor;
private final PastedComponentList myPastedComponentList;
private final GuiEditor myEditor;
private final ArrayList<RadComponent> myComponentsToPaste;
private ComponentDropLocation myLastLocation;
private final int[] myDX;
private final int[] myDY;
private final int myMinRow;
private final int myMinCol;
public PasteProcessor(GuiEditor editor, final ArrayList<RadComponent> componentsToPaste,
final TIntArrayList xs, final TIntArrayList ys) {
myEditor = editor;
myComponentsToPaste = componentsToPaste;
myGridInsertProcessor = new GridInsertProcessor(editor);
myPastedComponentList = new PastedComponentList();
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
// TIntArrayList.min() is broken
for(int i=0; i<xs.size(); i++) {
minX = Math.min(minX, xs.get(i));
}
for(int i=0; i<ys.size(); i++) {
minY = Math.min(minY, ys.get(i));
}
myDX = new int[xs.size()];
myDY = new int[ys.size()];
for(int i=0; i<xs.size(); i++) {
myDX [i] = xs.get(i) - minX;
}
for(int i=0; i<ys.size(); i++) {
myDY [i] = ys.get(i) - minY;
}
int myMinRow = Integer.MAX_VALUE;
int myMinCol = Integer.MAX_VALUE;
for(RadComponent component: myComponentsToPaste) {
myMinRow = Math.min(myMinRow, component.getConstraints().getRow());
myMinCol = Math.min(myMinCol, component.getConstraints().getColumn());
}
this.myMinRow = myMinRow;
this.myMinCol = myMinCol;
StatusBar.Info.set(UIDesignerBundle.message("paste.choose.destination.prompt"), myEditor.getProject());
}
protected void processKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
doPaste(myLastLocation);
e.consume();
}
else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
endPaste();
e.consume();
}
else {
myLastLocation = moveDropLocation(myEditor, myLastLocation, myPastedComponentList, e);
}
}
}
protected void processMouseEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_MOVED) {
myLastLocation = myGridInsertProcessor.processDragEvent(e.getPoint(), myPastedComponentList);
if (myLastLocation.canDrop(myPastedComponentList)) {
setCursor(FormEditingUtil.getCopyDropCursor());
}
else {
setCursor(FormEditingUtil.getMoveNoDropCursor());
}
}
else if (e.getID() == MouseEvent.MOUSE_PRESSED) {
processMousePressed(e);
}
}
private void processMousePressed(final MouseEvent e) {
ComponentDropLocation location = GridInsertProcessor.getDropLocation(myEditor.getRootContainer(), e.getPoint());
doPaste(location);
}
private void doPaste(final ComponentDropLocation location) {
if (location.canDrop(myPastedComponentList) && myEditor.ensureEditable()) {
final RadComponent[] componentsToPaste = myComponentsToPaste.toArray(new RadComponent[myComponentsToPaste.size()]);
CommandProcessor.getInstance().executeCommand(
myEditor.getProject(),
new Runnable() {
public void run() {
location.processDrop(myEditor, componentsToPaste, null, myPastedComponentList);
for(RadComponent c: componentsToPaste) {
FormEditingUtil.iterate(c, new FormEditingUtil.ComponentVisitor() {
public boolean visit(final IComponent component) {
if (component.getBinding() != null) {
InsertComponentProcessor.createBindingField(myEditor, (RadComponent) component);
}
return true;
}
});
}
FormEditingUtil.selectComponents(myEditor, myComponentsToPaste);
myEditor.refreshAndSave(true);
}
}, UIDesignerBundle.message("command.paste"), null);
endPaste();
}
}
private void endPaste() {
myEditor.getMainProcessor().stopCurrentProcessor();
myEditor.getActiveDecorationLayer().removeFeedback();
WindowManager.getInstance().getStatusBar(myEditor.getProject()).setInfo("");
}
protected boolean cancelOperation() {
WindowManager.getInstance().getStatusBar(myEditor.getProject()).setInfo("");
return true;
}
@Override public boolean needMousePressed() {
return true;
}
private class PastedComponentList implements ComponentDragObject {
public int getComponentCount() {
return myComponentsToPaste.size();
}
public boolean isHGrow() {
return false;
}
public boolean isVGrow() {
return false;
}
public int getRelativeRow(int componentIndex) {
return myComponentsToPaste.get(componentIndex).getConstraints().getRow() - myMinRow;
}
public int getRelativeCol(int componentIndex) {
return myComponentsToPaste.get(componentIndex).getConstraints().getColumn() - myMinCol;
}
public int getRowSpan(int componentIndex) {
return myComponentsToPaste.get(componentIndex).getConstraints().getRowSpan();
}
public int getColSpan(int componentIndex) {
return myComponentsToPaste.get(componentIndex).getConstraints().getColSpan();
}
public Point getDelta(int componentIndex) {
return new Point(myDX [componentIndex], myDY [componentIndex]);
}
@NotNull
public Dimension getInitialSize(final RadContainer targetContainer) {
if (myComponentsToPaste.size() == 1) {
return myComponentsToPaste.get(0).getSize();
}
return new Dimension(-1, -1);
}
}
}