*/
protected void installTextDragAndDrop(final ISourceViewer viewer) {
if (viewer == null || fIsTextDragAndDropInstalled)
return;
final IDragAndDropService dndService = (IDragAndDropService) getSite()
.getService(IDragAndDropService.class);
if (dndService == null)
return;
final StyledText st = viewer.getTextWidget();
// Install drag source
final ISelectionProvider selectionProvider = viewer
.getSelectionProvider();
final DragSource source = new DragSource(st, DND.DROP_COPY
| DND.DROP_MOVE);
source.setTransfer(new Transfer[] { TextTransfer.getInstance() });
source.addDragListener(new DragSourceAdapter() {
String fSelectedText;
Point fSelection;
public void dragStart(DragSourceEvent event) {
fTextDragAndDropToken = null;
try {
fSelection = st.getSelection();
event.doit = isLocationSelected(new Point(event.x, event.y));
ISelection selection = selectionProvider.getSelection();
if (selection instanceof ITextSelection)
fSelectedText = ((ITextSelection) selection).getText();
else
// fallback to widget
fSelectedText = st.getSelectionText();
} catch (IllegalArgumentException ex) {
event.doit = false;
}
}
private boolean isLocationSelected(Point point) {
// FIXME: https://bugs.eclipse.org/bugs/show_bug.cgi?id=260922
if (isBlockSelectionModeEnabled())
return false;
int offset = st.getOffsetAtLocation(point);
Point p = st.getLocationAtOffset(offset);
if (p.x > point.x)
offset--;
return offset >= fSelection.x && offset < fSelection.y;
}
public void dragSetData(DragSourceEvent event) {
event.data = fSelectedText;
fTextDragAndDropToken = this; // Can be any non-null object
}
public void dragFinished(DragSourceEvent event) {
try {
if (event.detail == DND.DROP_MOVE
&& validateEditorInputState()) {
Point newSelection = st.getSelection();
int length = fSelection.y - fSelection.x;
int delta = 0;
if (newSelection.x < fSelection.x)
delta = length;
st.replaceTextRange(fSelection.x + delta, length, ""); //$NON-NLS-1$
if (fTextDragAndDropToken == null) {
// Move in same editor - end compound change
IRewriteTarget target = (IRewriteTarget) getAdapter(IRewriteTarget.class);
if (target != null)
target.endCompoundChange();
}
}
} finally {
fTextDragAndDropToken = null;
}
}
});
// Install drag target
DropTargetListener dropTargetListener = new DropTargetAdapter() {
private Point fSelection;
public void dragEnter(DropTargetEvent event) {
fTextDragAndDropToken = null;
fSelection = st.getSelection();
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_MOVE) != 0) {
event.detail = DND.DROP_MOVE;
} else if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
} else {
event.detail = DND.DROP_NONE;
}
}
}
public void dragOperationChanged(DropTargetEvent event) {
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_MOVE) != 0) {
event.detail = DND.DROP_MOVE;
} else if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
} else {
event.detail = DND.DROP_NONE;
}
}
}
public void dragOver(DropTargetEvent event) {
event.feedback |= DND.FEEDBACK_SCROLL;
}
public void drop(DropTargetEvent event) {
try {
if (fTextDragAndDropToken != null
&& event.detail == DND.DROP_MOVE) {
// Move in same editor
int caretOffset = st.getCaretOffset();
if (fSelection.x <= caretOffset
&& caretOffset <= fSelection.y) {
event.detail = DND.DROP_NONE;
return;
}
// Start compound change
IRewriteTarget target = (IRewriteTarget) getAdapter(IRewriteTarget.class);
if (target != null)
target.beginCompoundChange();
}
if (!validateEditorInputState()) {
event.detail = DND.DROP_NONE;
return;
}
String text = (String) event.data;
if (isBlockSelectionModeEnabled()) {
// FIXME fix block selection and DND
// if (fTextDNDColumnSelection != null &&
// fTextDragAndDropToken != null && event.detail ==
// DND.DROP_MOVE) {
// // DND_MOVE within same editor - remove origin before
// inserting
// Rectangle newSelection= st.getColumnSelection();
// st.replaceColumnSelection(fTextDNDColumnSelection, ""); //$NON-NLS-1$
// st.replaceColumnSelection(newSelection, text);
// st.setColumnSelection(newSelection.x, newSelection.y,
// newSelection.x + fTextDNDColumnSelection.width -
// fTextDNDColumnSelection.x, newSelection.y +
// fTextDNDColumnSelection.height -
// fTextDNDColumnSelection.y);
// } else {
// Point newSelection= st.getSelection();
// st.insert(text);
// IDocument document=
// getDocumentProvider().getDocument(getEditorInput());
// int startLine= st.getLineAtOffset(newSelection.x);
// int startColumn= newSelection.x -
// st.getOffsetAtLine(startLine);
// int endLine= startLine +
// document.computeNumberOfLines(text);
// int endColumn= startColumn +
// TextUtilities.indexOf(document.getLegalLineDelimiters(),
// text, 0)[0];
// st.setColumnSelection(startColumn, startLine,
// endColumn, endLine);
// }
} else {
Point newSelection = st.getSelection();
try {
int modelOffset = widgetOffset2ModelOffset(viewer,
newSelection.x);
viewer.getDocument().replace(modelOffset, 0, text);
} catch (BadLocationException e) {
return;
}
st.setSelectionRange(newSelection.x, text.length());
}
} finally {
fTextDragAndDropToken = null;
}
}
};
dndService.addMergedDropTarget(st, DND.DROP_MOVE | DND.DROP_COPY,
new Transfer[] { TextTransfer.getInstance() },
dropTargetListener);
fIsTextDragAndDropInstalled = true;
}