blob: fbdf6badd448b3f11ae41a5ea16a98ebe2ed5ffc [file] [log] [blame]
david_williamscfdb2cd2004-11-11 08:37:49 +00001/*******************************************************************************
2 * Copyright (c) 2001, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Jens Lukowski/Innoopract - initial renaming/restructuring
11 *
12 *******************************************************************************/
david_williamsf3680f02005-04-13 22:43:54 +000013package org.eclipse.wst.sse.ui.internal;
david_williamscfdb2cd2004-11-11 08:37:49 +000014
david_williams76ae86b2005-04-20 00:29:00 +000015import org.eclipse.jface.text.BadLocationException;
16import org.eclipse.jface.text.IRegion;
david_williamscfdb2cd2004-11-11 08:37:49 +000017import org.eclipse.jface.text.ITextViewer;
18import org.eclipse.swt.custom.ST;
19import org.eclipse.swt.custom.StyledText;
20import org.eclipse.swt.dnd.DND;
21import org.eclipse.swt.dnd.DropTargetAdapter;
22import org.eclipse.swt.dnd.DropTargetEvent;
23import org.eclipse.swt.dnd.FileTransfer;
24import org.eclipse.swt.dnd.Transfer;
25import org.eclipse.swt.dnd.TransferData;
26import org.eclipse.swt.graphics.Color;
27import org.eclipse.swt.graphics.GC;
28import org.eclipse.swt.graphics.Point;
29import org.eclipse.swt.graphics.Rectangle;
30import org.eclipse.swt.widgets.Caret;
nitind50897002005-06-03 20:33:54 +000031import org.eclipse.ui.IEditorPart;
nitind503fc092005-11-01 20:17:10 +000032import org.eclipse.wst.sse.ui.internal.TransferBuilder.TransferProxyForDelayLoading;
david_williamscfdb2cd2004-11-11 08:37:49 +000033
34/**
35 * ExtendedEditorDropTargetAdapter
36 */
37public class ExtendedEditorDropTargetAdapter extends DropTargetAdapter {
38
39 private Point caret = null;
40 private String[] editorIds;
41 private int orgOffset = 0;
nitind50897002005-06-03 20:33:54 +000042 private IEditorPart targetEditor = null;
david_williamscfdb2cd2004-11-11 08:37:49 +000043 private ITextViewer textViewer = null;
44
45 private Transfer[] transfers = null;
46
nitind503fc092005-11-01 20:17:10 +000047 private boolean useProxy;
48
49 /**
50 * @deprecated use ExtendedEditorDropTargetAdapter(boolean useProxy) for
51 * the performance
52 */
david_williamscfdb2cd2004-11-11 08:37:49 +000053 public ExtendedEditorDropTargetAdapter() {
nitind503fc092005-11-01 20:17:10 +000054 this(false);
55 }
56
57 public ExtendedEditorDropTargetAdapter(boolean useProxy) {
david_williamscfdb2cd2004-11-11 08:37:49 +000058 super();
nitind503fc092005-11-01 20:17:10 +000059 this.useProxy = useProxy;
david_williamscfdb2cd2004-11-11 08:37:49 +000060 }
61
62 protected boolean doDrop(Transfer transfer, DropTargetEvent event) {
nitind503fc092005-11-01 20:17:10 +000063 TransferBuilder tb = new TransferBuilder(useProxy);
david_williamscfdb2cd2004-11-11 08:37:49 +000064
65 IDropAction[] as = null;
66 if (editorIds != null && editorIds.length > 0)
nitind503fc092005-11-01 20:17:10 +000067 as = tb.getDropActions(editorIds, transfer);
david_williamscfdb2cd2004-11-11 08:37:49 +000068 else
nitind503fc092005-11-01 20:17:10 +000069 as = tb.getDropActions(getTargetEditor().getClass().getName(), transfer);
david_williamscfdb2cd2004-11-11 08:37:49 +000070
71 for (int i = 0; i < as.length; ++i) {
72 IDropAction da = as[i];
nitind503fc092005-11-01 20:17:10 +000073 Transfer actualTransfer;
74 if (transfer instanceof TransferProxyForDelayLoading) {
75 actualTransfer = ((TransferProxyForDelayLoading) transfer).getTransferClass();
76 }
77 else {
78 actualTransfer = transfer;
79 }
80 if (actualTransfer instanceof FileTransfer) {
david_williamscfdb2cd2004-11-11 08:37:49 +000081 if (event.data == null) {
82 Logger.log(Logger.ERROR, "No data in DropTargetEvent from " + event.widget); //$NON-NLS-1$
83 return false;
84 }
85 String[] strs = (String[]) event.data;
86 boolean[] bs = new boolean[strs.length];
87 int c = 0;
88 for (int j = 0; j < strs.length; ++j) {
89 bs[j] = false;
90 if (da.isSupportedData(strs[j])) {
91 event.data = new String[]{strs[j]};
92 if (!da.run(event, targetEditor)) {
93 bs[j] = true;
94 c++;
95 }
96 } else {
97 bs[j] = true;
98 c++;
99 }
100 }
101 if (c == 0) {
102 return true;
103 }
104
105 int k = 0;
106 String[] rests = new String[c];
107 for (int j = 0; j < strs.length; ++j) {
108 if (bs[j])
109 rests[k++] = strs[j];
110 }
111 event.data = rests;
112 } else if (da.isSupportedData(event.data)) {
113 if (da.run(event, targetEditor)) {
114 return true;
115 }
116 }
117 }
118
119 return false;
120 }
121
122 /**
123 */
124 public void dragEnter(DropTargetEvent event) {
125 caret = null;
126 TransferData data = null;
127 Transfer[] ts = getTransfers();
128 for (int i = 0; i < ts.length; i++) {
129 for (int j = 0; j < event.dataTypes.length; j++) {
130 if (ts[i].isSupportedType(event.dataTypes[j])) {
131 data = event.dataTypes[j];
132 break;
133 }
134 }
135 if (data != null) {
136 event.currentDataType = data;
137 break;
138 }
139 }
140
141 if (textViewer != null) {
142 orgOffset = textViewer.getTextWidget().getCaretOffset();
143 }
144 }
145
146 public void dragLeave(DropTargetEvent event) {
147 if (textViewer != null) {
148 StyledText st = textViewer.getTextWidget();
149 st.setCaretOffset(orgOffset);
150 st.redraw();
151 st.update();
152 }
153 }
154
155 /**
156 */
157 public void dragOver(DropTargetEvent event) {
158 event.operations &= ~DND.DROP_MOVE;
159 event.detail = DND.DROP_COPY;
160
161 if (textViewer != null) {
162 Point pt = toControl(new Point(event.x, event.y));
163 StyledText st = textViewer.getTextWidget();
164
165 // auto scroll
166 Rectangle ca = st.getClientArea();
167 int margin = st.getLineHeight();
168
169 if (pt.y < margin) { // up
170 st.invokeAction(ST.LINE_UP);
171 } else if (pt.y > ca.height - margin) { // down
172 st.invokeAction(ST.LINE_DOWN);
173 }
174
175 // draw insertion point
176 int offset = getDropOffset(st, pt);
177 if (offset != st.getCaretOffset()) {
178 st.setCaretOffset(offset);
179 st.setSelection(offset);
180 }
181
182 Point newCaret = st.getLocationAtOffset(offset);
183 if (newCaret.equals(caret))
184 return;
185
186 Caret ct = st.getCaret();
187 Point size = ct.getSize();
188
189 GC gc = new GC(st);
david_williamscfdb2cd2004-11-11 08:37:49 +0000190 gc.setLineWidth(size.x);
191
192 // erase old caret
193 if (caret != null) {
194 Color originalForeground = gc.getForeground();
195 gc.setForeground(st.getBackground());
nitind503fc092005-11-01 20:17:10 +0000196 gc.drawRectangle(caret.x, caret.y, size.x, size.y);
david_williamscfdb2cd2004-11-11 08:37:49 +0000197 gc.setForeground(originalForeground);
198 }
199
200 st.redraw();
201 st.update();
202
203 // draw new caret
204 caret = newCaret;
205 if (ct.getImage() != null)
206 gc.drawImage(ct.getImage(), caret.x, caret.y);
nitind503fc092005-11-01 20:17:10 +0000207 else {
david_williamscfdb2cd2004-11-11 08:37:49 +0000208 gc.drawLine(caret.x, caret.y, caret.x, caret.y + size.y);
nitind503fc092005-11-01 20:17:10 +0000209 }
david_williamscfdb2cd2004-11-11 08:37:49 +0000210
211 gc.dispose();
212 }
213 }
214
215 /**
216 */
217 public void drop(DropTargetEvent event) {
218 if (event.operations == DND.DROP_NONE)
219 return;
220
221 if (textViewer != null) {
222 Point pt = toControl(new Point(event.x, event.y));
223 StyledText st = textViewer.getTextWidget();
224
225 int offset = getDropOffset(st, pt);
226 if (offset != st.getCaretOffset()) {
227 st.setCaretOffset(offset);
228 }
229
david_williams76ae86b2005-04-20 00:29:00 +0000230 // ISelectionProvider sp = textViewer.getSelectionProvider();
231 // ISelection sel = new TextSelection(offset, 0);
232 // sp.setSelection(sel);
david_williamscfdb2cd2004-11-11 08:37:49 +0000233 textViewer.setSelectedRange(offset, 0);
234 }
235
236 Transfer[] ts = getTransfers();
237 for (int i = 0; i < ts.length; i++) {
238 if (ts[i].isSupportedType(event.currentDataType)) {
239 if (doDrop(ts[i], event)) {
240 break;
241 }
242 }
243 }
244 }
245
246 protected int getDropOffset(DropTargetEvent event) {
247 Point pt = getTextViewer().getTextWidget().toControl(new Point(event.x, event.y));
248 StyledText st = textViewer.getTextWidget();
249 return getDropOffset(st, pt);
250 }
251
252 private int getDropOffset(StyledText st, Point pt) {
253 int offset = st.getCaretOffset();
254 try {
255 offset = st.getOffsetAtLocation(pt);
256 } catch (IllegalArgumentException e) {
257 // This is normal case if mouse cursor is on outside of valid
258 // text.
259 boolean found = false;
260 Point p = new Point((pt.x > 0 ? pt.x : 0), pt.y);
261 // search nearest character
262 for (; p.x > -1; p.x--) {
263 try {
david_williams76ae86b2005-04-20 00:29:00 +0000264 offset = st.getOffsetAtLocation(p);
265
266 /*
267 * Now that a valid offset has been found, try to place at
268 * the end of the line
269 */
270 if (textViewer != null && textViewer.getDocument() != null) {
271 IRegion lineInfo = null;
272 try {
273 lineInfo = textViewer.getDocument().getLineInformationOfOffset(offset);
274 } catch (BadLocationException e1) {
275 }
276 if (lineInfo != null)
277 offset = lineInfo.getOffset() + lineInfo.getLength();
278 }
279
david_williamscfdb2cd2004-11-11 08:37:49 +0000280 found = true;
281 break;
282 } catch (IllegalArgumentException ex) {
283 }
284 }
285
286 if (!found) {
287 offset = st.getCharCount();
288 }
289 }
290 return offset;
291 }
292
nitind50897002005-06-03 20:33:54 +0000293 public IEditorPart getTargetEditor() {
david_williamscfdb2cd2004-11-11 08:37:49 +0000294 return targetEditor;
295 }
296
297 public ITextViewer getTextViewer() {
298 return textViewer;
299 }
300
301 /**
302 * @return org.eclipse.swt.dnd.Transfer[]
303 */
304 public Transfer[] getTransfers() {
305 if (transfers == null) {
nitind503fc092005-11-01 20:17:10 +0000306 TransferBuilder tb = new TransferBuilder(useProxy);
david_williamscfdb2cd2004-11-11 08:37:49 +0000307 if (editorIds == null || editorIds.length == 0)
308 transfers = tb.getDropTargetTransfers(getTargetEditor().getClass().getName());
309 else
310 transfers = tb.getDropTargetTransfers(editorIds);
311 }
312 return transfers;
313 }
314
315 /**
316 */
nitind50897002005-06-03 20:33:54 +0000317 public void setTargetEditor(IEditorPart targetEditor) {
david_williamscfdb2cd2004-11-11 08:37:49 +0000318 this.targetEditor = targetEditor;
319 }
320
321 public void setTargetIDs(String[] ids) {
322 editorIds = ids;
323 }
324
325 public void setTextViewer(ITextViewer textViewer) {
326 this.textViewer = textViewer;
327 }
328
329 private Point toControl(Point point) {
330 return (textViewer != null ? textViewer.getTextWidget().toControl(point) : point);
331 }
332}