KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > Dispatcher


1 /*
2  * Dispatcher.java
3  *
4  * Copyright (C) 1998-2004 Peter Graves
5  * $Id: Dispatcher.java,v 1.13 2004/09/13 13:48:31 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import java.awt.AWTEvent JavaDoc;
25 import java.awt.Cursor JavaDoc;
26 import java.awt.Image JavaDoc;
27 import java.awt.Point JavaDoc;
28 import java.awt.Toolkit JavaDoc;
29 import java.awt.datatransfer.DataFlavor JavaDoc;
30 import java.awt.datatransfer.StringSelection JavaDoc;
31 import java.awt.datatransfer.Transferable JavaDoc;
32 import java.awt.dnd.DnDConstants JavaDoc;
33 import java.awt.dnd.DragGestureEvent JavaDoc;
34 import java.awt.dnd.DragGestureListener JavaDoc;
35 import java.awt.dnd.DragGestureRecognizer JavaDoc;
36 import java.awt.dnd.DragSource JavaDoc;
37 import java.awt.dnd.DragSourceContext JavaDoc;
38 import java.awt.dnd.DragSourceDragEvent JavaDoc;
39 import java.awt.dnd.DragSourceDropEvent JavaDoc;
40 import java.awt.dnd.DragSourceEvent JavaDoc;
41 import java.awt.dnd.DragSourceListener JavaDoc;
42 import java.awt.dnd.DropTargetContext JavaDoc;
43 import java.awt.dnd.DropTargetDragEvent JavaDoc;
44 import java.awt.dnd.DropTargetDropEvent JavaDoc;
45 import java.awt.dnd.DropTargetEvent JavaDoc;
46 import java.awt.dnd.DropTargetListener JavaDoc;
47 import java.awt.event.ActionEvent JavaDoc;
48 import java.awt.event.ActionListener JavaDoc;
49 import java.awt.event.InputEvent JavaDoc;
50 import java.awt.event.KeyEvent JavaDoc;
51 import java.awt.event.KeyListener JavaDoc;
52 import java.awt.event.MouseEvent JavaDoc;
53 import java.awt.event.MouseListener JavaDoc;
54 import java.awt.event.MouseMotionListener JavaDoc;
55 import java.net.URL JavaDoc;
56 import java.util.List JavaDoc;
57 import javax.swing.JPopupMenu JavaDoc;
58 import javax.swing.SwingUtilities JavaDoc;
59 import javax.swing.ToolTipManager JavaDoc;
60 import javax.swing.undo.CompoundEdit JavaDoc;
61
62 public final class Dispatcher implements Constants, KeyListener JavaDoc, MouseListener JavaDoc,
63     MouseMotionListener JavaDoc, ActionListener JavaDoc, DragGestureListener JavaDoc, DragSourceListener JavaDoc,
64     DropTargetListener JavaDoc
65 {
66     // For IdleThread.run.
67
private static long lastEventMillis = System.currentTimeMillis();
68
69     // Needed by dropBookmark, gotoBookmark.
70
private AWTEvent JavaDoc lastEvent;
71
72     private static final boolean DEBUG_KEY_PRESSED = false;
73
74     private final Editor editor;
75     private final Display display;
76
77     private Thread JavaDoc eventQueueThread;
78
79     private boolean ignoreKeyTyped;
80
81     private int lastKeyEvent;
82
83     private char charToBeIgnored = '\0';
84
85     private boolean enabled = true;
86
87     // Drag/drop.
88
private DragSource JavaDoc dragSource;
89     private static DragSourceContext JavaDoc dragSourceContext;
90     private boolean inDragText;
91     private Region dragTextRegion;
92     private static boolean isLineRegion;
93
94     // Cursors for drag/drop.
95
private static final int CURSOR_NO = 0;
96     private static final int CURSOR_MOVE = 1;
97     private static final int CURSOR_COPY = 2;
98     private static final Cursor JavaDoc[] cursors = new Cursor JavaDoc[3];
99
100     public Dispatcher(Editor editor)
101     {
102         this.editor = editor;
103         display = editor.getDisplay();
104
105
106         dragSource = DragSource.getDefaultDragSource() ;
107         DragGestureRecognizer JavaDoc dgr =
108             dragSource.createDefaultDragGestureRecognizer(display,
109                 DnDConstants.ACTION_COPY_OR_MOVE, this);
110         dgr.setSourceActions(dgr.getSourceActions() & ~InputEvent.BUTTON3_MASK);
111     }
112
113     public final AWTEvent JavaDoc getLastEvent()
114     {
115         return lastEvent;
116     }
117
118     public static synchronized final long getLastEventMillis()
119     {
120         return lastEventMillis;
121     }
122
123     private static synchronized final void setLastEventMillis(long when)
124     {
125         lastEventMillis = when;
126     }
127
128     public void setEnabled(boolean enabled)
129     {
130         this.enabled = enabled;
131     }
132
133     private void dispatch(AWTEvent JavaDoc e)
134     {
135         // Ignore events that don't come from the normal event queue thread.
136
if (eventQueueThread == null)
137             eventQueueThread = Thread.currentThread();
138         else if (Thread.currentThread() != eventQueueThread) {
139             setLastEventMillis(System.currentTimeMillis());
140             return;
141         }
142
143         lastEvent = e;
144
145         boolean handled = false;
146
147         switch (e.getID()) {
148             case KeyEvent.KEY_PRESSED:
149                 handled = dispatchKeyPressed((KeyEvent JavaDoc)e);
150                 break;
151             case KeyEvent.KEY_TYPED:
152                 handled = dispatchKeyTyped((KeyEvent JavaDoc)e);
153                 break;
154             case KeyEvent.KEY_RELEASED:
155                 break;
156             case MouseEvent.MOUSE_PRESSED:
157                 handled = dispatchMousePressed((MouseEvent JavaDoc)e);
158                 break;
159             case MouseEvent.MOUSE_DRAGGED:
160                 handled = dispatchMouseDragged((MouseEvent JavaDoc)e);
161                 break;
162             case ActionEvent.ACTION_PERFORMED:
163                 handled = dispatchActionPerformed((ActionEvent JavaDoc)e);
164                 break;
165         }
166
167         if (handled)
168             eventHandled();
169         else
170             setLastEventMillis(System.currentTimeMillis());
171     }
172
173     public void eventHandled()
174     {
175         final Buffer buffer = editor.getBuffer();
176         if (buffer.needsRenumbering())
177             buffer.renumber();
178
179         // Update all editors displaying buffer.
180
for (EditorIterator it = new EditorIterator(); it.hasNext();) {
181             Editor ed = it.nextEditor();
182             if (ed == editor) {
183                 ed.getDisplay().setCaretVisible(true);
184                 ed.updateDisplay();
185             } else if (ed.getBuffer() == buffer) {
186                 if (buffer.getModeId() != IMAGE_MODE) {
187                     ed.getDisplay().repaintChangedLines();
188                     ed.updateScrollBars();
189                 }
190                 ed.getFrame().repaintStatusBar();
191             }
192         }
193
194         final int currentCommand = editor.getCurrentCommand();
195         if (editor.getLastCommand() == COMMAND_PASTE)
196             if (currentCommand != COMMAND_PASTE)
197                 if (currentCommand != COMMAND_UNDO)
198                     Editor.promoteLastPaste();
199
200         editor.setLastCommand(currentCommand);
201         editor.setCurrentCommand(COMMAND_NOTHING);
202
203         if (Editor.isLispInitialized())
204             LispAPI.eventHandled();
205
206         SystemSelection.updateSystemSelection(editor);
207
208         setLastEventMillis(System.currentTimeMillis());
209     }
210
211     private boolean dispatchKeyPressed(KeyEvent JavaDoc e)
212     {
213         if (editor.getStatusBar() != null)
214             editor.getStatusBar().setText(null);
215
216         if (Editor.isMenuSelected) {
217             charToBeIgnored = e.getKeyChar();
218             ignoreKeyTyped = true;
219             return false;
220         }
221
222         int keycode = e.getKeyCode();
223
224         // Ignore modifier keystrokes.
225
if (keycode == KeyEvent.VK_SHIFT || keycode == KeyEvent.VK_CONTROL ||
226             keycode == KeyEvent.VK_ALT || keycode == KeyEvent.VK_META)
227             return false;
228
229         int modifiers = e.getModifiers();
230
231         char c = e.getKeyChar();
232
233         if (DEBUG_KEY_PRESSED) {
234             Log.debug("keyPressed, keycode = 0x" + Integer.toString(keycode, 16));
235             Log.debug("modifiers = 0x" + Integer.toString(modifiers, 16));
236             Log.debug("character = " + String.valueOf(c));
237             Log.debug("character = 0x" + Integer.toString((int) c, 16));
238         }
239
240         // Mask off the bits we don't care about (Java 1.4).
241
modifiers &= 0x0f;
242
243         if (DEBUG_KEY_PRESSED)
244             Log.debug("modifiers = 0x" + Integer.toString(modifiers, 16));
245
246         boolean handled = editor.handleKeyEvent(c, keycode, modifiers);
247
248         if (handled) {
249             ignoreKeyTyped = true;
250             e.consume();
251         } else {
252             // If we consume indiscriminately here, Alt F no longer works to
253
// drop the File menu (for example). So we only consume keystrokes
254
// with no modifiers.
255
if (modifiers == 0)
256                 e.consume();
257         }
258
259         return handled;
260     }
261
262     private boolean dispatchKeyTyped(KeyEvent JavaDoc e)
263     {
264         if (Editor.isMenuSelected)
265             return false;
266
267         if (ignoreKeyTyped)
268             return false;
269
270         int modifiers = e.getModifiers();
271
272         // Mask off the bits we don't care about (Java 1.4).
273
modifiers &= 0x0f;
274
275         if (modifiers != 0 && modifiers != InputEvent.SHIFT_MASK && modifiers != InputEvent.ALT_GRAPH_MASK)
276             return false;
277
278         char c = e.getKeyChar();
279
280         boolean handled = editor.handleKeyEvent(c, 0, 0);
281
282         Buffer buffer = editor.getBuffer();
283
284         if (!handled && !buffer.isBusy() && c != 0x1b && c != 0x08 && c != charToBeIgnored) {
285             if (c == '\t') {
286                 if (Editor.isRecordingMacro())
287                     Macro.record(editor, "insertTab");
288                 editor.insertTab();
289             } else if (!Character.isISOControl(c)) {
290                 if (Editor.isRecordingMacro())
291                     Macro.record(editor, c);
292                 editor.insertNormalChar(c);
293             }
294             handled = true;
295         }
296
297         charToBeIgnored = '\0';
298
299         if (handled)
300             e.consume();
301
302         // Jun 12 2000 3:06 PM
303
// With IBM 1.3 on Linux, if the user brings up a menu and then
304
// immediately cancels by hitting Escape, the cursor keys don't work
305
// in the edit window. Work around this problem by requesting focus
306
// and making sure the dispatcher is enabled if we see 0x1b here.
307
if (c == 0x1b) {
308             editor.setFocusToDisplay();
309             enabled = true;
310         }
311
312         return handled;
313     }
314
315     public void keyPressed(KeyEvent JavaDoc e)
316     {
317         // Force tool tip to be hidden.
318
ToolTipManager.sharedInstance().setEnabled(false);
319         ToolTipManager.sharedInstance().setEnabled(true);
320
321         if (editor.getFrame().getFocusedComponent() != display)
322             return;
323
324         editor.ensureActive();
325         Editor.setCurrentEditor(editor);
326
327         if (enabled) {
328             lastKeyEvent = KeyEvent.KEY_PRESSED;
329             ignoreKeyTyped = false;
330             dispatch(e);
331         }
332     }
333
334     public void keyReleased(KeyEvent JavaDoc e)
335     {
336         e.consume();
337         if (editor.getFrame().getFocusedComponent() != display)
338             return;
339
340         if (lastKeyEvent == KeyEvent.KEY_RELEASED) {
341             // Work around bug in Windows VMs that causes a subsequent
342
// KEY_TYPED event after the Alt key is released when the original
343
// keystroke generates an ActionEvent.
344

345             // If we get two (or more) KEY_RELEASED events in a row, wait
346
// until we see KEY_PRESSED again before paying attention to
347
// KEY_TYPED.
348
if (e.getKeyCode() == KeyEvent.VK_ALT)
349                 ignoreKeyTyped = true;
350         } else
351             ignoreKeyTyped = false;
352
353         lastKeyEvent = KeyEvent.KEY_RELEASED;
354     }
355
356     public void keyTyped(KeyEvent JavaDoc e)
357     {
358         if (editor.getFrame().getFocusedComponent() != display)
359             return;
360
361         lastKeyEvent = KeyEvent.KEY_TYPED;
362         dispatch(e);
363     }
364
365     public void mouseClicked(MouseEvent JavaDoc e)
366     {
367         // Mask off the bits we don't care about (Java 1.4).
368
int modifiers = e.getModifiers() & 0x1f;
369         if (modifiers != InputEvent.BUTTON1_MASK)
370             return;
371         if (editor.getMark() != null && e.getClickCount() == 1) {
372             final Buffer buffer = editor.getBuffer();
373             if (buffer.getBooleanProperty(Property.ENABLE_DRAG_TEXT)) {
374                 Region r = new Region(editor);
375                 Position pos = display.positionFromPoint(e.getPoint());
376                 if (pos.isAfter(r.getBegin()) && pos.isBefore(r.getEnd())) {
377                     editor.addUndo(SimpleEdit.MOVE);
378                     editor.unmark();
379                     display.moveCaretToPoint(e.getPoint());
380                     if (buffer.getBooleanProperty(Property.RESTRICT_CARET))
381                         editor.moveCaretToDotCol();
382                     editor.updateDisplay();
383                 }
384             }
385         }
386     }
387
388     private boolean dragTextStarting;
389
390     public void mousePressed(MouseEvent JavaDoc e)
391     {
392         if (editor.getFocusedComponent() == editor.getLocationBarTextField()) {
393             TextFieldHandler handler = editor.getLocationBarTextField().getHandler();
394             if (handler instanceof IncrementalFindTextFieldHandler) {
395                 handler.enter();
396             } else
397                 handler.escape();
398         } else
399             LocationBar.cancelInput();
400         editor.ensureActive();
401         if (editor != Editor.currentEditor()) {
402             Editor oldEditor = Editor.currentEditor();
403             Editor.setCurrentEditor(editor);
404             if (oldEditor.getDot() != null)
405                 oldEditor.update(oldEditor.getDotLine());
406             oldEditor.updateDisplay();
407             Frame frame = editor.getFrame();
408             frame.setMenu();
409             frame.setToolbar();
410             Sidebar sidebar = frame.getSidebar();
411             if (sidebar != null)
412                 sidebar.setUpdateFlag(SIDEBAR_SET_BUFFER);
413         }
414         int modifiers = e.getModifiers() & 0x1f;
415         JPopupMenu JavaDoc popup = editor.getPopup();
416         if (popup != null) {
417             if (popup.isVisible()) {
418                 editor.killPopup();
419                 if (modifiers != InputEvent.BUTTON1_MASK)
420                     return;
421             }
422             editor.setPopup(null);
423         }
424         if (modifiers == InputEvent.BUTTON1_MASK && editor.getMark() != null) {
425             if (editor.getBuffer().getBooleanProperty(Property.ENABLE_DRAG_TEXT)) {
426                 Region r = new Region(editor);
427                 if (!r.isColumnRegion()) {
428                     Position pos = display.positionFromPoint(e.getPoint());
429                     if (pos.isAfter(r.getBegin()) && pos.isBefore(r.getEnd())) {
430                         dragTextStarting = true;
431                         return;
432                     }
433                 }
434             }
435         }
436         dragTextStarting = false;
437         dispatch(e);
438     }
439
440     public void mouseReleased(MouseEvent JavaDoc e)
441     {
442     }
443
444     public void mouseEntered(MouseEvent JavaDoc e) {}
445
446     public void mouseExited(MouseEvent JavaDoc e) {}
447
448     private boolean dispatchMousePressed(MouseEvent JavaDoc e)
449     {
450         editor.setFocusToDisplay();
451
452         enabled = true;
453
454         if (editor.getStatusBar() != null)
455             editor.getStatusBar().setText(null);
456
457         if (editor.getModeId() == IMAGE_MODE)
458             return false;
459
460         final int x = e.getX();
461         final int y = e.getY();
462
463         // Mask off the bits we don't care about (Java 1.4).
464
int modifiers = e.getModifiers() & 0x1f;
465
466         final Mode mode = editor.getMode();
467         final Buffer buffer = editor.getBuffer();
468
469         // Folding.
470
if (x < display.getGutterWidth(buffer)) {
471             Position pos = display.positionFromPoint(x, y);
472             Line next = pos.getLine().next();
473             if (next != null && next.isHidden()) {
474                 editor.unfold(next);
475                 return true;
476             } else if (modifiers == InputEvent.BUTTON2_MASK) {
477                 // Middle button.
478
editor.foldNearLine(pos.getLine());
479                 return true;
480             }
481             // else fall through...
482
} else if (modifiers == InputEvent.BUTTON2_MASK) {
483             Position pos = display.positionFromPoint(x, y);
484             if (pos != null && pos.getOffset() < pos.getLine().getIndentation()) {
485                 Line next = pos.getLine().next();
486                 if (next != null) {
487                     if (next.isHidden()) {
488                         editor.unfold(next);
489                         return true;
490                     } else if (next.trim().endsWith("{")) {
491                         next = next.next();
492                         if (next != null && next.isHidden()) {
493                             editor.unfold(next);
494                             return true;
495                         }
496                     }
497                 }
498                 // Couldn't find a fold to expand.
499
editor.foldNearLine(pos.getLine());
500                 return true;
501             }
502             // else fall through...
503
}
504
505         int keycode = 0;
506         final int clickCount = e.getClickCount();
507         if ((modifiers & InputEvent.BUTTON1_MASK) != 0) {
508             modifiers &= ~InputEvent.BUTTON1_MASK;
509             switch (clickCount) {
510                 case 1:
511                     keycode = VK_MOUSE_1;
512                     break;
513                 case 2:
514                     keycode = VK_DOUBLE_MOUSE_1;
515                     break;
516             }
517         } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0) {
518             modifiers &= ~InputEvent.BUTTON2_MASK;
519             switch (clickCount) {
520                 case 1:
521                     keycode = VK_MOUSE_2;
522                     break;
523                 case 2:
524                     keycode = VK_DOUBLE_MOUSE_2;
525                     break;
526             }
527         } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {
528             modifiers &= ~InputEvent.BUTTON3_MASK;
529             switch (clickCount) {
530                 case 1:
531                     keycode = VK_MOUSE_3;
532                     break;
533                 case 2:
534                     keycode = VK_DOUBLE_MOUSE_3;
535                     break;
536             }
537         }
538         if (keycode == 0)
539             return false;
540         return editor.handleKeyEvent('\0', keycode, modifiers);
541     }
542
543     public void mouseDragged(MouseEvent JavaDoc e)
544     {
545         dispatch(e);
546     }
547
548     public void mouseMoved(MouseEvent JavaDoc e)
549     {
550         final Buffer buffer = editor.getBuffer();
551         final Position pos = display.positionFromPoint(e.getPoint());
552         final String JavaDoc contextString = buffer.getMode().getMouseMovedContextString(editor, pos);
553         if (contextString != null) {
554             // Context string will be "" rather than null if we should clear
555
// the status text (e.g. web mode).
556
editor.status(contextString);
557         }
558         if (buffer.isBusy())
559             editor.setWaitCursor();
560         else if (e.getX() < Display.getGutterWidth(buffer))
561             editor.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
562         else
563             editor.setCursor(buffer.getDefaultCursor(pos));
564     }
565
566     private boolean dispatchMouseDragged(MouseEvent JavaDoc e)
567     {
568         if (editor.getModeId() == IMAGE_MODE)
569             return false;
570         final Position dot = editor.getDot();
571         if (dot == null)
572             return false;
573
574         // Mask off the bits we don't care about (Java 1.4).
575
final int modifiers = e.getModifiers() & 0x1f;
576
577         // IBM Windows VM reports modifiers are 0 even when the left button is
578
// down. So instead of looking for button 1 to be down, we verify that
579
// buttons 2 and 3 are NOT down.
580
if ((modifiers & InputEvent.BUTTON2_MASK) != 0)
581             return false;
582         if ((modifiers & InputEvent.BUTTON3_MASK) != 0)
583             return false;
584
585         if ((modifiers & InputEvent.CTRL_MASK) != 0)
586             return false;
587         if ((modifiers & InputEvent.SHIFT_MASK) != 0)
588             return false;
589
590         // No drag select with column selections.
591
if (editor.isColumnSelection())
592             return false;
593
594         // Reaching here, button 1 must be down, or we wouldn't have a mouse
595
// dragged event.
596
if (inDragText)
597             return false;
598
599         Point JavaDoc point = e.getPoint();
600         if (point.y < 0) {
601             display.windowUp();
602             point.y = 1;
603         } else {
604             int limit = display.getRows() * display.getCharHeight();
605             if (point.y >= limit) {
606                 display.windowDown();
607                 point.y = limit - 1;
608             }
609         }
610
611         Position pos = display.positionFromPoint(point);
612         if (pos == null || pos.equals(dot))
613             return false;
614
615         if (editor.getMark() != null) {
616             if (editor.getBuffer().getBooleanProperty(Property.ENABLE_DRAG_TEXT)) {
617                 if (dragTextStarting)
618                     return false;
619             }
620         }
621
622         if (editor.getMark() == null) {
623             editor.addUndo(SimpleEdit.MOVE);
624             editor.setMarkAtDot();
625         }
626
627         final Position oldDot = new Position(editor.getDot());
628
629         final Line newLine = pos.getLine();
630         if (newLine != dot.getLine()) {
631             editor.updateDotLine();
632             dot.setLine(newLine);
633         }
634         editor.moveDotToCol(display.getColumn(newLine, point.x) + display.getShift());
635
636         // Don't let caret go beyond end of text on line.
637
editor.moveCaretToDotCol();
638
639         Region r = new Region(editor.getBuffer(), editor.getDot(), oldDot);
640         for (Line line = r.getBeginLine(); line != r.getEndLine(); line = line.next())
641             editor.update(line);
642
643         return true;
644     }
645
646     private boolean dispatchActionPerformed(ActionEvent JavaDoc event)
647     {
648         editor.executeCommand(event.getActionCommand());
649         return true;
650     }
651
652     public void actionPerformed(final ActionEvent JavaDoc e)
653     {
654         Runnable JavaDoc r = new Runnable JavaDoc() {
655             public void run()
656             {
657                 dispatch(e);
658             }
659         };
660         SwingUtilities.invokeLater(r);
661     }
662
663     public void dragEnter(DropTargetDragEvent JavaDoc event)
664     {
665         if (editor.getBuffer().isReadOnly()) {
666             event.rejectDrag();
667         } else {
668             if (Platform.isPlatformUnix() && dragSourceContext != null)
669                 dragSourceContext.setCursor(getCursorForAction(event.getDropAction()));
670             editor.getFrame().toFront();
671         }
672     }
673
674     public void dragExit(DropTargetEvent JavaDoc e)
675     {
676         display.setDragCaretPos(null);
677         if (Platform.isPlatformUnix() && dragSourceContext != null)
678             dragSourceContext.setCursor(getDragCursor(CURSOR_NO));
679     }
680
681     public void dragOver(DropTargetDragEvent JavaDoc event)
682     {
683         if (event.isDataFlavorSupported(DataFlavor.stringFlavor)) {
684             Point JavaDoc pt = event.getLocation();
685
686             Line line = display.lineFromY(pt.y);
687             if (line == null)
688                 return;
689             Position pos = new Position(line, 0);
690             int absCol = 0;
691
692             if (isLineRegion) {
693                 // Leave drag caret in column 0.
694
;
695             } else {
696                 int col = Math.max(display.getColumn(line, pt.x), 0);
697                 absCol = col + display.getShift();
698                 pos.moveToCol(absCol, editor.getBuffer().getTabWidth());
699             }
700
701             boolean ok = false;
702             if (dragTextRegion == null)
703                 ok = true;
704             else if (pos.isBefore(dragTextRegion.getBegin()))
705                 ok = true;
706             else if (pos.isAfter(dragTextRegion.getEnd()))
707                 ok = true;
708             else if (pos.equals(dragTextRegion.getEnd())) {
709                 if (absCol > editor.getBuffer().getCol(dragTextRegion.getEnd()))
710                     ok = true;
711             }
712
713             if (ok) {
714                 display.setDragCaretPos(pos);
715                 // The point in question might be beyond the end of the line.
716
display.setDragCaretCol(absCol);
717             } else
718                 display.setDragCaretPos(null);
719             display.repaintChangedLines();
720         }
721     }
722
723     public void drop(DropTargetDropEvent JavaDoc event)
724     {
725         Transferable JavaDoc t = event.getTransferable();
726         if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
727             acceptFileDrop(event, t);
728         else if (t.isDataFlavorSupported(DataFlavor.stringFlavor))
729             acceptTextDrop(event, t);
730         else
731             event.rejectDrop();
732     }
733
734     private void acceptFileDrop(DropTargetDropEvent JavaDoc event, Transferable JavaDoc t)
735     {
736         event.acceptDrop(DnDConstants.ACTION_LINK);
737         try {
738             List JavaDoc files =
739                 (List JavaDoc) t.getTransferData(DataFlavor.javaFileListFlavor);
740             for (int i = 0; i < files.size(); i++) {
741                 String JavaDoc path = ((java.io.File JavaDoc)files.get(i)).getPath();
742                 Buffer buffer = editor.openFile(File.getInstance(path));
743                 if (buffer != null) {
744                     editor.makeNext(buffer);
745                     editor.activate(buffer);
746                 } else
747                     event.rejectDrop();
748             }
749             event.getDropTargetContext().dropComplete(true);
750         }
751         catch (Exception JavaDoc e) {
752             Log.error(e);
753             event.rejectDrop();
754         }
755         editor.updateDisplay();
756     }
757
758     private void acceptTextDrop(DropTargetDropEvent JavaDoc event, Transferable JavaDoc t)
759     {
760         final int dropAction = event.getDropAction(); // copy = 1, move = 2
761
if (dropAction != DnDConstants.ACTION_COPY &&
762             dropAction != DnDConstants.ACTION_MOVE) {
763              // Not copy or move.
764
event.rejectDrop();
765             return;
766         }
767         if (!editor.checkReadOnly()) {
768             event.rejectDrop();
769             return;
770         }
771         // Copy or move.
772
try {
773             event.acceptDrop(dropAction);
774             final String JavaDoc s =
775                 (String JavaDoc) t.getTransferData(DataFlavor.stringFlavor);
776             final Point JavaDoc point = event.getLocation();
777             Position posDrop = display.positionFromPoint(point);
778             boolean ok = false;
779             if (dragTextRegion == null)
780                 ok = true;
781             else if (posDrop.isBefore(dragTextRegion.getBegin()))
782                 ok = true;
783             else if (posDrop.isAfter(dragTextRegion.getEnd()))
784                 ok = true;
785             else if (posDrop.equals(dragTextRegion.getEnd())) {
786                 int col = Math.max(display.getColumn(posDrop.getLine(), point.x), 0);
787                 int absCol = col + display.getShift();
788                 if (absCol > editor.getBuffer().getCol(dragTextRegion.getEnd()))
789                     ok = true;
790             }
791             if (ok) {
792                 if (dropAction == DnDConstants.ACTION_COPY) {
793                     // Copy.
794
CompoundEdit JavaDoc compoundEdit = editor.beginCompoundEdit();
795                     moveCaretToDropPoint(point);
796                     editor.paste(s, true);
797                     editor.endCompoundEdit(compoundEdit);
798                 } else if (dropAction == DnDConstants.ACTION_MOVE) {
799                     // Move.
800
CompoundEdit JavaDoc compoundEdit = editor.beginCompoundEdit();
801                     if (dragTextRegion != null && posDrop.isBefore(dragTextRegion.getBegin())) {
802                         editor.deleteRegion();
803                         dragTextRegion = null;
804                     }
805                     moveCaretToDropPoint(point);
806                     editor.paste(s, true); // Leave paste selected.
807
Region r = new Region(editor);
808                     posDrop = r.getBegin(); // Where the drop actually occurred.
809
if (dragTextRegion != null && posDrop.isAfter(dragTextRegion.getEnd())) {
810                         Position savedDot = editor.getDotCopy();
811                         Position savedMark = editor.getMark().copy();
812                         dragTextRegion.adjustMarker(savedDot);
813                         dragTextRegion.adjustMarker(savedMark);
814                         editor.addUndo(SimpleEdit.MOVE);
815                         editor.setMark(dragTextRegion.getBegin());
816                         editor.setDot(dragTextRegion.getEnd());
817                         editor.deleteRegion();
818                         dragTextRegion = null;
819                         editor.addUndo(SimpleEdit.MOVE);
820                         editor.setMark(savedMark);
821                         editor.setDot(savedDot);
822                     }
823                     editor.endCompoundEdit(compoundEdit);
824                 }
825                 editor.updateDisplay();
826             }
827             event.getDropTargetContext().dropComplete(true);
828             // Make sure destination is current editor after drop.
829
editor.ensureActive();
830             Editor.setCurrentEditor(editor);
831             editor.setFocusToDisplay();
832         }
833         catch (Exception JavaDoc e) {
834             Log.error(e);
835             event.rejectDrop();
836         }
837         inDragText = false;
838         dragTextRegion = null;
839         display.setDragCaretPos(null);
840         editor.setDefaultCursor();
841         editor.repaint();
842     }
843
844     private void moveCaretToDropPoint(Point JavaDoc point)
845     {
846         editor.addUndo(SimpleEdit.MOVE);
847         editor.setMark(null);
848         display.moveCaretToPoint(point);
849         if (editor.getBuffer().getBooleanProperty(Property.RESTRICT_CARET))
850             display.moveCaretToDotCol();
851     }
852
853     public void dropActionChanged(DropTargetDragEvent JavaDoc event)
854     {
855         if (Platform.isPlatformUnix() && dragSourceContext != null)
856             dragSourceContext.setCursor(getCursorForAction(event.getDropAction()));
857     }
858
859     public void dragGestureRecognized(DragGestureEvent JavaDoc event)
860     {
861         if (!Editor.preferences().getBooleanProperty(Property.ENABLE_DRAG_TEXT))
862             return;
863         if (editor.getMark() != null) {
864             Region r = new Region(editor);
865             Position pos = display.positionFromPoint(event.getDragOrigin());
866             if (!pos.isAfter(r.getBegin()))
867                 return;
868             if (!pos.isBefore(r.getEnd()))
869                 return;
870             dragTextRegion = r;
871             Transferable JavaDoc transferable =
872                 new StringSelection JavaDoc(dragTextRegion.toString());
873             isLineRegion = dragTextRegion.isLineRegion();
874             inDragText = true;
875             int action = event.getDragAction();
876             Cursor JavaDoc cursor = Platform.isPlatformUnix() ? getCursorForAction(action) : null;
877             dragSource.startDrag(event, cursor, transferable, this);
878             dragSourceContext = null;
879         }
880     }
881
882     public void dragDropEnd(DragSourceDropEvent JavaDoc event)
883     {
884         if (dragTextRegion != null && !editor.getBuffer().isReadOnly())
885             if (event.getDropAction() == DnDConstants.ACTION_MOVE)
886                 editor.deleteRegion();
887         inDragText = false;
888         dragTextRegion = null;
889         isLineRegion = false;
890         display.setDragCaretPos(null);
891         display.repaintChangedLines();
892     }
893
894     public void dragEnter(DragSourceDragEvent JavaDoc event)
895     {
896         if (Platform.isPlatformUnix()) {
897             DragSourceContext JavaDoc dsc = event.getDragSourceContext();
898             dsc.setCursor(getCursorForAction(event.getDropAction()));
899         }
900     }
901
902     public void dragOver(DragSourceDragEvent JavaDoc event)
903     {
904     }
905
906     public void dropActionChanged(DragSourceDragEvent JavaDoc event)
907     {
908         if (Platform.isPlatformUnix()) {
909             DragSourceContext JavaDoc dsc = event.getDragSourceContext();
910             int dropAction = event.getDropAction();
911             if (dropAction == DnDConstants.ACTION_COPY)
912                 dsc.setCursor(getDragCursor(CURSOR_COPY));
913             else if (dropAction == DnDConstants.ACTION_MOVE)
914                 dsc.setCursor(getDragCursor(CURSOR_MOVE));
915         }
916     }
917
918     public void dragExit(DragSourceEvent JavaDoc event)
919     {
920         DragSourceContext JavaDoc dsc = event.getDragSourceContext();
921         if (Platform.isPlatformUnix())
922             dsc.setCursor(getDragCursor(CURSOR_NO));
923         dragSourceContext = dsc;
924     }
925
926     // Only used on Unix.
927
public static Cursor JavaDoc getCursorForAction(int action)
928     {
929         int index;
930         if (action == DnDConstants.ACTION_COPY)
931             index = CURSOR_COPY;
932         else if (action == DnDConstants.ACTION_MOVE)
933             index = CURSOR_MOVE;
934         else
935             index = CURSOR_NO;
936         return getDragCursor(index);
937     }
938
939     // Only used on Unix.
940
private static Cursor JavaDoc getDragCursor(int index)
941     {
942         if (cursors[index] != null)
943             return cursors[index];
944         // Need to create cursor.
945
String JavaDoc name, filename;
946         switch (index) {
947             case CURSOR_NO:
948             default:
949                 name = "NoDrop";
950                 filename = "nodrop.png";
951                 break;
952             case CURSOR_MOVE:
953                 name = "MoveDrop";
954                 filename = "movedrop.png";
955                 break;
956             case CURSOR_COPY:
957                 name = "CopyDrop";
958                 filename = "copydrop.png";
959                 break;
960         }
961         Cursor JavaDoc cursor = null;
962         URL JavaDoc url = Editor.class.getResource("images/".concat(filename));
963         if (url != null) {
964             Toolkit JavaDoc toolkit = java.awt.Toolkit.getDefaultToolkit();
965             Image JavaDoc image = toolkit.createImage(url);
966             if (image != null)
967                 cursor = toolkit.createCustomCursor(image, new Point JavaDoc(1, 1),
968                     name);
969         }
970         if (cursor == null)
971             cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
972         // Cache the result.
973
cursors[index] = cursor;
974         return cursor;
975     }
976 }
977
Popular Tags