blob: fd26f41d3c9e0cefabb35ce941f3ea78962e1cc4 [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 *******************************************************************************/
13package org.eclipse.wst.sse.ui.extension;
14
15
16
17import 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;
31import org.eclipse.wst.sse.ui.Logger;
32
33
34/**
35 * ExtendedEditorDropTargetAdapter
36 */
37public class ExtendedEditorDropTargetAdapter extends DropTargetAdapter {
38
39 private Point caret = null;
40 private String[] editorIds;
41 private int orgOffset = 0;
42 private IExtendedSimpleEditor targetEditor = null;
43 private ITextViewer textViewer = null;
44
45 private Transfer[] transfers = null;
46
47 public ExtendedEditorDropTargetAdapter() {
48 super();
49 }
50
51 protected boolean doDrop(Transfer transfer, DropTargetEvent event) {
52 TransferBuilder tb = new TransferBuilder();
53
54 IDropAction[] as = null;
55 if (editorIds != null && editorIds.length > 0)
56 as = tb.getDropActions(editorIds, transfer.getClass().getName());
57 else
58 as = tb.getDropActions(getTargetEditor().getClass().getName(), transfer.getClass().getName());
59
60 for (int i = 0; i < as.length; ++i) {
61 IDropAction da = as[i];
62 if (transfer instanceof FileTransfer) {
63 if (event.data == null) {
64 Logger.log(Logger.ERROR, "No data in DropTargetEvent from " + event.widget); //$NON-NLS-1$
65 return false;
66 }
67 String[] strs = (String[]) event.data;
68 boolean[] bs = new boolean[strs.length];
69 int c = 0;
70 for (int j = 0; j < strs.length; ++j) {
71 bs[j] = false;
72 if (da.isSupportedData(strs[j])) {
73 event.data = new String[]{strs[j]};
74 if (!da.run(event, targetEditor)) {
75 bs[j] = true;
76 c++;
77 }
78 } else {
79 bs[j] = true;
80 c++;
81 }
82 }
83 if (c == 0) {
84 return true;
85 }
86
87 int k = 0;
88 String[] rests = new String[c];
89 for (int j = 0; j < strs.length; ++j) {
90 if (bs[j])
91 rests[k++] = strs[j];
92 }
93 event.data = rests;
94 } else if (da.isSupportedData(event.data)) {
95 if (da.run(event, targetEditor)) {
96 return true;
97 }
98 }
99 }
100
101 return false;
102 }
103
104 /**
105 */
106 public void dragEnter(DropTargetEvent event) {
107 caret = null;
108 TransferData data = null;
109 Transfer[] ts = getTransfers();
110 for (int i = 0; i < ts.length; i++) {
111 for (int j = 0; j < event.dataTypes.length; j++) {
112 if (ts[i].isSupportedType(event.dataTypes[j])) {
113 data = event.dataTypes[j];
114 break;
115 }
116 }
117 if (data != null) {
118 event.currentDataType = data;
119 break;
120 }
121 }
122
123 if (textViewer != null) {
124 orgOffset = textViewer.getTextWidget().getCaretOffset();
125 }
126 }
127
128 public void dragLeave(DropTargetEvent event) {
129 if (textViewer != null) {
130 StyledText st = textViewer.getTextWidget();
131 st.setCaretOffset(orgOffset);
132 st.redraw();
133 st.update();
134 }
135 }
136
137 /**
138 */
139 public void dragOver(DropTargetEvent event) {
140 event.operations &= ~DND.DROP_MOVE;
141 event.detail = DND.DROP_COPY;
142
143 if (textViewer != null) {
144 Point pt = toControl(new Point(event.x, event.y));
145 StyledText st = textViewer.getTextWidget();
146
147 // auto scroll
148 Rectangle ca = st.getClientArea();
149 int margin = st.getLineHeight();
150
151 if (pt.y < margin) { // up
152 st.invokeAction(ST.LINE_UP);
153 } else if (pt.y > ca.height - margin) { // down
154 st.invokeAction(ST.LINE_DOWN);
155 }
156
157 // draw insertion point
158 int offset = getDropOffset(st, pt);
159 if (offset != st.getCaretOffset()) {
160 st.setCaretOffset(offset);
161 st.setSelection(offset);
162 }
163
164 Point newCaret = st.getLocationAtOffset(offset);
165 if (newCaret.equals(caret))
166 return;
167
168 Caret ct = st.getCaret();
169 Point size = ct.getSize();
170
171 GC gc = new GC(st);
172 gc.setXORMode(true);
173 gc.setLineWidth(size.x);
174
175 // erase old caret
176 if (caret != null) {
177 Color originalForeground = gc.getForeground();
178 gc.setForeground(st.getBackground());
179 gc.drawLine(caret.x, caret.y, caret.x, caret.y + size.y);
180 gc.setForeground(originalForeground);
181 }
182
183 st.redraw();
184 st.update();
185
186 // draw new caret
187 caret = newCaret;
188 if (ct.getImage() != null)
189 gc.drawImage(ct.getImage(), caret.x, caret.y);
190 else
191 gc.drawLine(caret.x, caret.y, caret.x, caret.y + size.y);
192
193 gc.dispose();
194 }
195 }
196
197 /**
198 */
199 public void drop(DropTargetEvent event) {
200 if (event.operations == DND.DROP_NONE)
201 return;
202
203 if (textViewer != null) {
204 Point pt = toControl(new Point(event.x, event.y));
205 StyledText st = textViewer.getTextWidget();
206
207 int offset = getDropOffset(st, pt);
208 if (offset != st.getCaretOffset()) {
209 st.setCaretOffset(offset);
210 }
211
212 // ISelectionProvider sp = textViewer.getSelectionProvider();
213 // ISelection sel = new TextSelection(offset, 0);
214 // sp.setSelection(sel);
215 textViewer.setSelectedRange(offset, 0);
216 }
217
218 Transfer[] ts = getTransfers();
219 for (int i = 0; i < ts.length; i++) {
220 if (ts[i].isSupportedType(event.currentDataType)) {
221 if (doDrop(ts[i], event)) {
222 break;
223 }
224 }
225 }
226 }
227
228 protected int getDropOffset(DropTargetEvent event) {
229 Point pt = getTextViewer().getTextWidget().toControl(new Point(event.x, event.y));
230 StyledText st = textViewer.getTextWidget();
231 return getDropOffset(st, pt);
232 }
233
234 private int getDropOffset(StyledText st, Point pt) {
235 int offset = st.getCaretOffset();
236 try {
237 offset = st.getOffsetAtLocation(pt);
238 } catch (IllegalArgumentException e) {
239 // This is normal case if mouse cursor is on outside of valid
240 // text.
241 boolean found = false;
242 Point p = new Point((pt.x > 0 ? pt.x : 0), pt.y);
243 // search nearest character
244 for (; p.x > -1; p.x--) {
245 try {
246 offset = st.getOffsetAtLocation(p) + 1; // + 1 to place
247 // cursor at an
248 // end of line
249 found = true;
250 break;
251 } catch (IllegalArgumentException ex) {
252 }
253 }
254
255 if (!found) {
256 offset = st.getCharCount();
257 }
258 }
259 return offset;
260 }
261
262 public IExtendedSimpleEditor getTargetEditor() {
263 return targetEditor;
264 }
265
266 public ITextViewer getTextViewer() {
267 return textViewer;
268 }
269
270 /**
271 * @return org.eclipse.swt.dnd.Transfer[]
272 */
273 public Transfer[] getTransfers() {
274 if (transfers == null) {
275 TransferBuilder tb = new TransferBuilder();
276 if (editorIds == null || editorIds.length == 0)
277 transfers = tb.getDropTargetTransfers(getTargetEditor().getClass().getName());
278 else
279 transfers = tb.getDropTargetTransfers(editorIds);
280 }
281 return transfers;
282 }
283
284 /**
285 */
286 public void setTargetEditor(IExtendedSimpleEditor targetEditor) {
287 this.targetEditor = targetEditor;
288 }
289
290 public void setTargetIDs(String[] ids) {
291 editorIds = ids;
292 }
293
294 public void setTextViewer(ITextViewer textViewer) {
295 this.textViewer = textViewer;
296 }
297
298 private Point toControl(Point point) {
299 return (textViewer != null ? textViewer.getTextWidget().toControl(point) : point);
300 }
301}