Initialize
[sdk/ide/product.git] / org.eclipse.jst.pagedesigner / src / org / eclipse / jst / pagedesigner / itemcreation / ItemCreationTool.java
1 /*******************************************************************************\r
2  * Copyright (c) 2006 Sybase, Inc. and others.\r
3  *\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     Sybase, Inc. - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.eclipse.jst.pagedesigner.itemcreation;\r
13 \r
14 import org.eclipse.core.runtime.IStatus;\r
15 import org.eclipse.core.runtime.Status;\r
16 import org.eclipse.gef.Request;\r
17 import org.eclipse.gef.SharedCursors;\r
18 import org.eclipse.gef.commands.Command;\r
19 import org.eclipse.gef.tools.TargetingTool;\r
20 import org.eclipse.jst.pagedesigner.commands.CreateItemCommand;\r
21 import org.eclipse.jst.pagedesigner.editors.palette.ITagDropSourceData;\r
22 import org.eclipse.jst.pagedesigner.itemcreation.customizer.DropCustomizationController;\r
23 import org.eclipse.swt.graphics.Cursor;\r
24 \r
25 /**\r
26  * This Tool is used to create items. It is to replace the default CreationTool\r
27  * of GEF. We are not using CreationToolEntry for creating item, since the\r
28  * default GEF implementation require creating of the object before drop into\r
29  * the view. We do not want to create the XML element (and possibly its taglib\r
30  * declaration) before the drop is really performed.)\r
31  * \r
32  * @author mengbo\r
33  */\r
34 public class ItemCreationTool extends TargetingTool {\r
35     private final ITagDropSourceData _tagDropSourceData; //can we get rid of this?\r
36 \r
37         /**\r
38          * Default constructor. Sets the default and disabled cursors.\r
39          * @param tagDropSourceData \r
40          */\r
41         public ItemCreationTool(ITagDropSourceData tagDropSourceData) {\r
42                 setDefaultCursor(SharedCursors.CURSOR_TREE_ADD);\r
43                 setDisabledCursor(SharedCursors.NO);\r
44 \r
45                 this._tagDropSourceData = tagDropSourceData;  \r
46         }\r
47 \r
48         /**\r
49          * @see org.eclipse.gef.tools.AbstractTool#calculateCursor()\r
50          */\r
51         protected Cursor calculateCursor() {\r
52                 /*\r
53                  * Fix for Bug# 66010 The following two lines of code were added for the\r
54                  * case where a tool is activated via the keyboard (that code hasn't\r
55                  * been released yet). However, they were causing a problem as described\r
56                  * in 66010. Since the keyboard activation code is not being released\r
57                  * for 3.0, the following lines are being commented out.\r
58                  */\r
59                 // if (isInState(STATE_INITIAL))\r
60                 // return getDefaultCursor();\r
61                 return super.calculateCursor();\r
62         }\r
63 \r
64         /**\r
65          * Creates a {@link ItemCreationRequest}and sets this tool's factory on the\r
66          * request.\r
67          * \r
68          * @see org.eclipse.gef.tools.TargetingTool#createTargetRequest()\r
69          */\r
70         protected Request createTargetRequest() {\r
71                 ItemCreationRequest request = new ItemCreationRequest();\r
72                 request.setTagCreationProvider(_tagDropSourceData);\r
73                 return request;\r
74         }\r
75 \r
76         /**\r
77          * @see org.eclipse.gef.Tool#deactivate()\r
78          */\r
79         public void deactivate() {\r
80                 super.deactivate();\r
81                 // TODO: never read helper = null;\r
82         }\r
83 \r
84         /**\r
85          * @see org.eclipse.gef.tools.AbstractTool#getCommandName()\r
86          */\r
87         protected String getCommandName() {\r
88                 return ItemCreationRequest.REQ_ITEM_CREATION;\r
89         }\r
90 \r
91         /**\r
92          * Cast the target request to a CreateRequest and returns it.\r
93          * \r
94          * @return the target request as a CreateRequest\r
95          * @see TargetingTool#getTargetRequest()\r
96          */\r
97         protected ItemCreationRequest getCreateRequest() {\r
98                 return (ItemCreationRequest) getTargetRequest();\r
99         }\r
100 \r
101         /**\r
102          * @see org.eclipse.gef.tools.AbstractTool#getDebugName()\r
103          */\r
104         protected String getDebugName() {\r
105                 return "Item Creation Tool";//$NON-NLS-1$\r
106         }\r
107 \r
108         /**\r
109          * The creation tool only works by clicking mouse button 1 (the left mouse\r
110          * button in a right-handed world). If any other button is pressed, the tool\r
111          * goes into an invalid state. Otherwise, it goes into the drag state,\r
112          * updates the request's location and calls\r
113          * {@link TargetingTool#lockTargetEditPart(org.eclipse.gef.EditPart)}with the edit part\r
114          * that was just clicked on.\r
115          * \r
116          * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int)\r
117          */\r
118         protected boolean handleButtonDown(int button) {\r
119                 if (button != 1) {\r
120                         setState(STATE_INVALID);\r
121                         handleInvalidInput();\r
122                         return true;\r
123                 }\r
124                 if (stateTransition(STATE_INITIAL, STATE_DRAG)) {\r
125                         if (getTargetEditPart() != null) {\r
126                                 getCreateRequest().setLocation(getLocation());\r
127                                 lockTargetEditPart(getTargetEditPart());\r
128                                 // Snap only when size on drop is employed\r
129                                 // TODO: never read helper = (SnapToHelper) getTargetEditPart().getAdapter(\r
130                                 //SnapToHelper.class);\r
131                         }\r
132                 }\r
133                 return true;\r
134         }\r
135 \r
136         /**\r
137          * If the tool is currently in a drag or drag-in-progress state, it goes\r
138          * into the terminal state, performs some cleanup (erasing feedback,\r
139          * unlocking target edit part), and then calls {@link #performCreation(int)}.\r
140          * \r
141          * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)\r
142          */\r
143         protected boolean handleButtonUp(int button) \r
144         {\r
145                 if (stateTransition(STATE_DRAG | STATE_DRAG_IN_PROGRESS, STATE_TERMINAL)) \r
146                 {\r
147                         eraseTargetFeedback();\r
148                         unlockTargetEditPart();\r
149                         \r
150                         // customizer may cancel the drop\r
151                         customizeDropAndMaybeExecute(button);\r
152                 }\r
153                 \r
154                 setState(STATE_TERMINAL);\r
155                 handleFinished();\r
156 \r
157                 return true;\r
158         }\r
159 \r
160         /**\r
161      * @param button\r
162      */\r
163     protected void customizeDropAndMaybeExecute(final int button)\r
164     {\r
165         Command command = getCurrentCommand();\r
166 \r
167         IStatus status = Status.OK_STATUS;\r
168         if (command instanceof CreateItemCommand)\r
169         {\r
170             status = new DropCustomizationController((CreateItemCommand) command,\r
171                     _tagDropSourceData, \r
172                     ((CreateItemCommand)command).getDocument(),\r
173                     ((CreateItemCommand)command).getPosition()).\r
174                 performCustomization();\r
175         }\r
176 \r
177         if (status.getSeverity() == IStatus.OK)\r
178         {\r
179             performCreation(button);\r
180         }\r
181     }\r
182 \r
183 \r
184     /**\r
185          * Updates the request, sets the current command, and asks to show feedback.\r
186          * \r
187          * @see org.eclipse.gef.tools.AbstractTool#handleDragInProgress()\r
188          */\r
189         protected boolean handleDragInProgress() {\r
190                 if (isInState(STATE_DRAG_IN_PROGRESS)) {\r
191                         updateTargetRequest();\r
192                         setCurrentCommand(getCommand());\r
193                         showTargetFeedback();\r
194                 }\r
195                 return true;\r
196         }\r
197 \r
198         /**\r
199          * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted()\r
200          */\r
201         protected boolean handleDragStarted() {\r
202                 return stateTransition(STATE_DRAG, STATE_DRAG_IN_PROGRESS);\r
203         }\r
204 \r
205         /**\r
206          * If the user is in the middle of creating a new edit part, the tool erases\r
207          * feedback and goes into the invalid state when focus is lost.\r
208          * \r
209          * @see org.eclipse.gef.tools.AbstractTool#handleFocusLost()\r
210          */\r
211         protected boolean handleFocusLost() {\r
212                 if (isInState(STATE_DRAG | STATE_DRAG_IN_PROGRESS)) {\r
213                         eraseTargetFeedback();\r
214                         setState(STATE_INVALID);\r
215                         handleFinished();\r
216                         return true;\r
217                 }\r
218                 return false;\r
219         }\r
220 \r
221         /**\r
222          * @see org.eclipse.gef.tools.TargetingTool#handleHover()\r
223          */\r
224         protected boolean handleHover() {\r
225                 if (isInState(STATE_INITIAL))\r
226                         updateAutoexposeHelper();\r
227                 return true;\r
228         }\r
229 \r
230         /**\r
231          * Updates the request and mouse target, gets the current command and asks\r
232          * to show feedback.\r
233          * \r
234          * @see org.eclipse.gef.tools.AbstractTool#handleMove()\r
235          */\r
236         protected boolean handleMove() {\r
237                 updateTargetRequest();\r
238                 updateTargetUnderMouse();\r
239                 setCurrentCommand(getCommand());\r
240                 showTargetFeedback();\r
241                 return true;\r
242         }\r
243 \r
244         /**\r
245          * Executes the current command and selects the newly created object. The\r
246          * button that was released to cause this creation is passed in, but since\r
247          * {@link #handleButtonDown(int)}goes into the invalid state if the button\r
248          * pressed is not button 1, this will always be button 1.\r
249          * \r
250          * @param button\r
251          *            the button that was pressed\r
252          */\r
253         protected void performCreation(int button) {\r
254                 executeCurrentCommand();\r
255                 // selectAddedObject();\r
256         }\r
257 \r
258         // /*\r
259         // * Add the newly created object to the viewer's selected objects.\r
260         // */\r
261         // private void selectAddedObject() {\r
262         // final Object model = getCreateRequest().getNewObject();\r
263         // if (model == null)\r
264         // return;\r
265         // EditPartViewer viewer = getCurrentViewer();\r
266         // Object editpart = viewer.getEditPartRegistry().get(model);\r
267         // if (editpart instanceof EditPart) {\r
268         // viewer.flush();\r
269         // viewer.select((EditPart)editpart);\r
270         // }\r
271         // }\r
272 \r
273         /**\r
274          * Sets the location (and size if the user is performing size-on-drop) of\r
275          * the request.\r
276          * \r
277          * @see org.eclipse.gef.tools.TargetingTool#updateTargetRequest()\r
278          */\r
279         protected void updateTargetRequest() {\r
280                 ItemCreationRequest req = getCreateRequest();\r
281                 req.setLocation(getLocation());\r
282                 // if (isInState(STATE_DRAG_IN_PROGRESS)) {\r
283                 // Point loq = getStartLocation();\r
284                 // req.setLocation(bounds.getLocation());\r
285                 // req.getExtendedData().clear();\r
286                 // if (!getCurrentInput().isAltKeyDown() && helper != null) {\r
287                 // PrecisionRectangle baseRect = new PrecisionRectangle(bounds);\r
288                 // PrecisionRectangle result = baseRect.getPreciseCopy();\r
289                 // helper.snapRectangle(req, PositionConstants.NSEW,\r
290                 // baseRect, result);\r
291                 // req.setLocation(result.getLocation());\r
292                 // req.setSize(result.getSize());\r
293                 // }\r
294                 // } else {\r
295                 // req.setLocation(getLocation());\r
296                 // }\r
297         }\r
298 \r
299 }\r