2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com
.intellij
.uiDesigner
.designSurface
;
19 import com
.intellij
.openapi
.wm
.StatusBar
;
20 import com
.intellij
.openapi
.wm
.WindowManager
;
21 import com
.intellij
.openapi
.command
.CommandProcessor
;
22 import com
.intellij
.uiDesigner
.FormEditingUtil
;
23 import com
.intellij
.uiDesigner
.UIDesignerBundle
;
24 import com
.intellij
.uiDesigner
.lw
.IComponent
;
25 import com
.intellij
.uiDesigner
.radComponents
.RadComponent
;
26 import com
.intellij
.uiDesigner
.radComponents
.RadContainer
;
27 import gnu
.trove
.TIntArrayList
;
28 import org
.jetbrains
.annotations
.NotNull
;
30 import java
.awt
.Dimension
;
31 import java
.awt
.Point
;
32 import java
.awt
.event
.KeyEvent
;
33 import java
.awt
.event
.MouseEvent
;
34 import java
.util
.ArrayList
;
39 public class PasteProcessor
extends EventProcessor
{
40 private final GridInsertProcessor myGridInsertProcessor
;
41 private final PastedComponentList myPastedComponentList
;
42 private final GuiEditor myEditor
;
43 private final ArrayList
<RadComponent
> myComponentsToPaste
;
44 private ComponentDropLocation myLastLocation
;
45 private final int[] myDX
;
46 private final int[] myDY
;
47 private final int myMinRow
;
48 private final int myMinCol
;
50 public PasteProcessor(GuiEditor editor
, final ArrayList
<RadComponent
> componentsToPaste
,
51 final TIntArrayList xs
, final TIntArrayList ys
) {
53 myComponentsToPaste
= componentsToPaste
;
54 myGridInsertProcessor
= new GridInsertProcessor(editor
);
55 myPastedComponentList
= new PastedComponentList();
57 int minX
= Integer
.MAX_VALUE
;
58 int minY
= Integer
.MAX_VALUE
;
60 // TIntArrayList.min() is broken
61 for(int i
=0; i
<xs
.size(); i
++) {
62 minX
= Math
.min(minX
, xs
.get(i
));
64 for(int i
=0; i
<ys
.size(); i
++) {
65 minY
= Math
.min(minY
, ys
.get(i
));
68 myDX
= new int[xs
.size()];
69 myDY
= new int[ys
.size()];
70 for(int i
=0; i
<xs
.size(); i
++) {
71 myDX
[i
] = xs
.get(i
) - minX
;
73 for(int i
=0; i
<ys
.size(); i
++) {
74 myDY
[i
] = ys
.get(i
) - minY
;
77 int myMinRow
= Integer
.MAX_VALUE
;
78 int myMinCol
= Integer
.MAX_VALUE
;
79 for(RadComponent component
: myComponentsToPaste
) {
80 myMinRow
= Math
.min(myMinRow
, component
.getConstraints().getRow());
81 myMinCol
= Math
.min(myMinCol
, component
.getConstraints().getColumn());
83 this.myMinRow
= myMinRow
;
84 this.myMinCol
= myMinCol
;
85 final StatusBar statusBar
= WindowManager
.getInstance().getStatusBar(myEditor
.getProject());
86 statusBar
.setInfo(UIDesignerBundle
.message("paste.choose.destination.prompt"));
89 protected void processKeyEvent(KeyEvent e
) {
90 if (e
.getID() == KeyEvent
.KEY_PRESSED
) {
91 if (e
.getKeyCode() == KeyEvent
.VK_ENTER
) {
92 doPaste(myLastLocation
);
95 else if (e
.getKeyCode() == KeyEvent
.VK_ESCAPE
) {
100 myLastLocation
= moveDropLocation(myEditor
, myLastLocation
, myPastedComponentList
, e
);
105 protected void processMouseEvent(MouseEvent e
) {
106 if (e
.getID() == MouseEvent
.MOUSE_MOVED
) {
107 myLastLocation
= myGridInsertProcessor
.processDragEvent(e
.getPoint(), myPastedComponentList
);
108 if (myLastLocation
.canDrop(myPastedComponentList
)) {
109 setCursor(FormEditingUtil
.getCopyDropCursor());
112 setCursor(FormEditingUtil
.getMoveNoDropCursor());
115 else if (e
.getID() == MouseEvent
.MOUSE_PRESSED
) {
116 processMousePressed(e
);
120 private void processMousePressed(final MouseEvent e
) {
121 ComponentDropLocation location
= GridInsertProcessor
.getDropLocation(myEditor
.getRootContainer(), e
.getPoint());
125 private void doPaste(final ComponentDropLocation location
) {
126 if (location
.canDrop(myPastedComponentList
) && myEditor
.ensureEditable()) {
127 final RadComponent
[] componentsToPaste
= myComponentsToPaste
.toArray(new RadComponent
[myComponentsToPaste
.size()]);
128 CommandProcessor
.getInstance().executeCommand(
129 myEditor
.getProject(),
132 location
.processDrop(myEditor
, componentsToPaste
, null, myPastedComponentList
);
133 for(RadComponent c
: componentsToPaste
) {
134 FormEditingUtil
.iterate(c
, new FormEditingUtil
.ComponentVisitor() {
135 public boolean visit(final IComponent component
) {
136 if (component
.getBinding() != null) {
137 InsertComponentProcessor
.createBindingField(myEditor
, (RadComponent
) component
);
143 FormEditingUtil
.selectComponents(myEditor
, myComponentsToPaste
);
144 myEditor
.refreshAndSave(true);
146 }, UIDesignerBundle
.message("command.paste"), null);
151 private void endPaste() {
152 myEditor
.getMainProcessor().stopCurrentProcessor();
153 myEditor
.getActiveDecorationLayer().removeFeedback();
154 WindowManager
.getInstance().getStatusBar(myEditor
.getProject()).setInfo("");
157 protected boolean cancelOperation() {
158 WindowManager
.getInstance().getStatusBar(myEditor
.getProject()).setInfo("");
162 @Override public boolean needMousePressed() {
166 private class PastedComponentList
implements ComponentDragObject
{
167 public int getComponentCount() {
168 return myComponentsToPaste
.size();
171 public boolean isHGrow() {
175 public boolean isVGrow() {
179 public int getRelativeRow(int componentIndex
) {
180 return myComponentsToPaste
.get(componentIndex
).getConstraints().getRow() - myMinRow
;
183 public int getRelativeCol(int componentIndex
) {
184 return myComponentsToPaste
.get(componentIndex
).getConstraints().getColumn() - myMinCol
;
187 public int getRowSpan(int componentIndex
) {
188 return myComponentsToPaste
.get(componentIndex
).getConstraints().getRowSpan();
191 public int getColSpan(int componentIndex
) {
192 return myComponentsToPaste
.get(componentIndex
).getConstraints().getColSpan();
195 public Point
getDelta(int componentIndex
) {
196 return new Point(myDX
[componentIndex
], myDY
[componentIndex
]);
200 public Dimension
getInitialSize(final RadContainer targetContainer
) {
201 if (myComponentsToPaste
.size() == 1) {
202 return myComponentsToPaste
.get(0).getSize();
204 return new Dimension(-1, -1);