KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > textarea > TextAreaTransferHandler


1 /*
2  * TextAreaTransferHandler.java - Drag and drop support
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2004 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit.textarea;
24
25 //{{{ Imports
26
import javax.swing.*;
27 import java.awt.datatransfer.*;
28 import java.io.File JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.net.URI JavaDoc;
32 import org.gjt.sp.jedit.Buffer;
33 import org.gjt.sp.jedit.EditPane;
34 import org.gjt.sp.jedit.GUIUtilities;
35 import org.gjt.sp.jedit.jEdit;
36 import org.gjt.sp.util.Log;
37 //}}}
38

39 public class TextAreaTransferHandler extends TransferHandler
40 {
41     /* I assume that there can be only one drag operation at the time */
42     private static JEditTextArea dragSource;
43     private static boolean compoundEdit;
44     private static boolean sameTextArea;
45     private static int insertPos;
46     private static int insertOffset;
47     
48     // Unfortunately, this does not work, as this DataFlavor is internally changed into another DataFlavor which does not match the intented DataFlavor anymore. :-( So, below, we are iterating.
49
/*
50     protected static DataFlavor textURIlistDataFlavor = null;
51     
52     static {
53         try {
54             textURIlistDataFlavor = new DataFlavor("text/uri-list;representationclass=java.lang.String");
55         } catch (ClassNotFoundException e) {
56             throw new RuntimeException("Cannot create DataFlavor. This should not happen.",e);
57         }
58     }
59     */

60
61     //{{{ createTransferable
62
protected Transferable createTransferable(JComponent c)
63     {
64         Log.log(Log.DEBUG,this,"createTransferable()");
65         JEditTextArea textArea = (JEditTextArea)c;
66         if(textArea.getSelectionCount() == 0)
67             return null;
68         else
69         {
70             dragSource = textArea;
71             return new TextAreaSelection(textArea);
72         }
73     } //}}}
74

75     //{{{ getSourceActions
76
public int getSourceActions(JComponent c)
77     {
78         return COPY_OR_MOVE;
79     } //}}}
80

81     //{{{ importData
82
public boolean importData(JComponent c, Transferable t)
83     {
84         Log.log(Log.DEBUG,this,"Import data");
85 // Log.log(Log.DEBUG,this,"Import data: t.isDataFlavorSupported("+textURIlistDataFlavor+")="+t.isDataFlavorSupported(textURIlistDataFlavor)+".");
86
if(!canImport(c,t.getTransferDataFlavors()))
87             return false;
88
89         boolean returnValue;
90
91         try
92         {
93             if(t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
94             {
95                 returnValue = importFile(c,t);
96             }
97             else {
98                 DataFlavor uriListStringDataFlavor = null;
99                 DataFlavor[] dataFlavors = t.getTransferDataFlavors();
100                 
101                 for (int i = 0;i<dataFlavors.length;i++) {
102                     DataFlavor dataFlavor = dataFlavors[i];
103                     if (dataFlavor.getPrimaryType().equals("text")&&dataFlavor.getSubType().equals("uri-list")&&(dataFlavor.getRepresentationClass()==String JavaDoc.class)) {
104                         uriListStringDataFlavor = dataFlavor;
105                         break;
106                     }
107                 }
108                 
109                 if ((uriListStringDataFlavor!=null)&&t.isDataFlavorSupported(uriListStringDataFlavor))
110                 {
111                     returnValue = importURIList(c,t,uriListStringDataFlavor);
112                 }
113                 else
114                 {
115                     returnValue = importText(c,t);
116                 }
117             }
118         }
119         catch(Exception JavaDoc e)
120         {
121             Log.log(Log.ERROR,this,e);
122             returnValue = false;
123         }
124
125         GUIUtilities.getView(c).toFront();
126         GUIUtilities.getView(c).requestFocus();
127         c.requestFocus();
128
129         return returnValue;
130     } //}}}
131

132     //{{{ importFile
133
private boolean importFile(JComponent c, Transferable t)
134         throws Exception JavaDoc
135     {
136         Log.log(Log.DEBUG,this,"=> File list");
137         EditPane editPane = (EditPane)
138             GUIUtilities.getComponentParent(
139             c,EditPane.class);
140
141         Buffer buffer = null;
142
143         Object JavaDoc data = t.getTransferData(
144             DataFlavor.javaFileListFlavor);
145
146         Iterator JavaDoc iterator = ((List JavaDoc)data)
147             .iterator();
148
149         while(iterator.hasNext())
150         {
151             File JavaDoc file = (File JavaDoc)
152                 iterator.next();
153             Buffer _buffer = jEdit.openFile(null,
154                 file.getPath());
155             if(_buffer != null)
156                 buffer = _buffer;
157         }
158
159         if(buffer != null)
160             editPane.setBuffer(buffer);
161         editPane.getView().toFront();
162         editPane.getView().requestFocus();
163         editPane.requestFocus();
164
165         return true;
166     } //}}}
167

168     //{{{ importText
169
private boolean importURIList(JComponent c, Transferable t,DataFlavor uriListStringDataFlavor)
170         throws Exception JavaDoc
171     {
172         String JavaDoc str = (String JavaDoc) t.getTransferData(uriListStringDataFlavor);
173
174         Log.log(Log.DEBUG,this,"=> URIList \""+str+"\"");
175         
176         JEditTextArea textArea = (JEditTextArea) c;
177         if (dragSource == null)
178         {
179             String JavaDoc maybeManyFileURI = str;
180             boolean found = false;
181             String JavaDoc[] components = str.split("\r\n");
182             
183             for (int i = 0;i<components.length;i++)
184             {
185                 String JavaDoc str0 = components[i];
186                 
187                 if (str0.length()>0) {
188                     URI JavaDoc uri = new URI JavaDoc(str0); // this handles the URI-decoding
189

190                     if ("file".equals(uri.getScheme()))
191                     {
192                         org.gjt.sp.jedit.io.VFSManager.runInWorkThread(new DraggedURLLoader(textArea,uri.getPath()));
193                         found = true;
194                     }
195                     else
196                     {
197                         Log.log(Log.DEBUG,this,"I do not know how to handle this URI "+uri+", ignoring.");
198                     }
199                 }
200                 else
201                 {
202                     // This should be the last component, because every URI in the list is terminated with a "\r\n", even the last one.
203
if (i!=components.length-1)
204                     {
205                         Log.log(Log.DEBUG,this,"Odd: there is an empty line in the uri list which is not the last line.");
206                     }
207                 }
208             }
209             
210             if (found)
211             {
212                 return true;
213             }
214         }
215         
216         return true;
217     }
218     
219     //{{{ importText
220
private boolean importText(JComponent c, Transferable t)
221         throws Exception JavaDoc
222     {
223         String JavaDoc str = (String JavaDoc)t.getTransferData(
224             DataFlavor.stringFlavor);
225         str = str.trim();
226         Log.log(Log.DEBUG,this,"=> String \""+str+"\"");
227         
228         JEditTextArea textArea = (JEditTextArea)c;
229         if (dragSource == null)
230         {
231             String JavaDoc maybeManyFileNames = str;
232             boolean found = false;
233             String JavaDoc[] components = str.split("\n");
234             
235             for (int i = 0;i<components.length;i++)
236             {
237                 String JavaDoc str0 = components[i];
238                 // Only examine the string for a URL if it came from
239
// outside of jEdit.
240
org.gjt.sp.jedit.io.VFS vfs = org.gjt.sp.jedit.io.VFSManager.getVFSForPath(str0);
241                 if (!(vfs instanceof org.gjt.sp.jedit.io.FileVFS) || str.startsWith("file://"))
242                 {
243                 
244 // str = str.replace('\n',' ').replace('\r',' ').trim();
245
if (str0.startsWith("file://"))
246                     {
247                         str0 = str0.substring(7);
248                     }
249                     
250                     org.gjt.sp.jedit.io.VFSManager.runInWorkThread(new DraggedURLLoader(textArea,str0));
251                 }
252                 found = true;
253                 
254             }
255             
256             if (found) {
257                 return true;
258             }
259         }
260
261         if(dragSource != null
262             && textArea.getBuffer()
263             == dragSource.getBuffer())
264         {
265             compoundEdit = true;
266             textArea.getBuffer().beginCompoundEdit();
267         }
268         
269         
270         sameTextArea = (textArea == dragSource);
271
272         int caret = textArea.getCaretPosition();
273         Selection s = textArea.getSelectionAtOffset(caret);
274
275         /* if user drops into the same
276         selection where they started, do
277         nothing. */

278         if(s != null)
279         {
280             if(sameTextArea)
281                 return false;
282             /* if user drops into a selection,
283             replace selection */

284             int startPos = s.start;
285             textArea.setSelectedText(s,str);
286             textArea.setSelection(new Selection.Range(startPos,startPos+str.length()));
287         }
288         /* otherwise just insert the text */
289         else
290         {
291             if (sameTextArea)
292             {
293                 insertPos = caret;
294                 insertOffset = 0;
295                 Selection[] selections = textArea.getSelection();
296                 for (int i=0;i<selections.length;i++)
297                 {
298                     if (selections[i].end<(insertPos+insertOffset))
299                         insertOffset-=(selections[i].end-selections[i].start);
300                 }
301             }
302             else
303             {
304                 textArea.getBuffer().insert(caret,str);
305                 textArea.setSelection(new Selection.Range(caret,caret+str.length()));
306             }
307         }
308         textArea.scrollToCaret(true);
309
310         return true;
311     } //}}}
312

313     //{{{ exportDone
314
protected void exportDone(JComponent c, Transferable t,
315         int action)
316     {
317         Log.log(Log.DEBUG,this,"Export done");
318
319         JEditTextArea textArea = (JEditTextArea)c;
320
321         try
322         {
323             // This happens if importData returns false. For example if you drop into the Selection
324
if (action == NONE)
325             {
326                 Log.log(Log.DEBUG,this,"Export impossible");
327                 return;
328             }
329
330             if(t == null)
331             {
332                 Log.log(Log.DEBUG,this,"=> Null transferrable");
333                 textArea.selectNone();
334             }
335             else if(t.isDataFlavorSupported(
336                 DataFlavor.stringFlavor))
337             {
338                 Log.log(Log.DEBUG,this,"=> String");
339                 if (sameTextArea)
340                 {
341                     if(action == MOVE)
342                     {
343                         textArea.setSelectedText(null,false);
344                         insertPos += insertOffset;
345                     }
346                     try
347                     {
348                         String JavaDoc str = (String JavaDoc)t.getTransferData(DataFlavor.stringFlavor);
349                         textArea.getBuffer().insert(insertPos,str);
350                         textArea.setSelection(new Selection.Range(insertPos,insertPos+str.length()));
351                     }
352                     catch(Exception JavaDoc e)
353                     {
354                         Log.log(Log.DEBUG,this,"exportDone in sameTextArea");
355                         Log.log(Log.DEBUG,this,e);
356                     }
357                 }
358                 else
359                 {
360                     if(action == MOVE)
361                         textArea.setSelectedText(null,false);
362                     else
363                         textArea.selectNone();
364                 }
365             }
366         }
367         finally
368         {
369             if(compoundEdit)
370             {
371                 compoundEdit = false;
372                 textArea.getBuffer().endCompoundEdit();
373             }
374         }
375
376         dragSource = null;
377     } //}}}
378

379     //{{{ canImport
380
public boolean canImport(JComponent c, DataFlavor[] flavors)
381     {
382         JEditTextArea textArea = (JEditTextArea)c;
383
384         // correctly handle text flavor + file list flavor
385
// + text area read only, do an or of all flags
386
boolean returnValue = false;
387
388         for(int i = 0; i < flavors.length; i++)
389         {
390             if(flavors[i].equals(
391                 DataFlavor.javaFileListFlavor))
392             {
393                 returnValue = true;
394             }
395             else if(flavors[i].equals(
396                 DataFlavor.stringFlavor))
397             {
398                 if(textArea.isEditable())
399                     returnValue = true;
400             }
401         }
402
403         Log.log(Log.DEBUG,this,"canImport() returning "
404             + returnValue);
405         return returnValue;
406     } //}}}
407

408     //{{{ TextAreaSelection class
409
static class TextAreaSelection extends StringSelection
410     {
411         JEditTextArea textArea;
412
413         TextAreaSelection(JEditTextArea textArea)
414         {
415             super(textArea.getSelectedText());
416             this.textArea = textArea;
417         }
418     } //}}}
419

420     //{{{ DraggedURLLoader
421
class DraggedURLLoader extends org.gjt.sp.util.WorkRequest
422     {
423         private JEditTextArea textArea;
424         private String JavaDoc url;
425         
426         public DraggedURLLoader(JEditTextArea textArea, String JavaDoc url)
427         {
428             super();
429             this.textArea = textArea;
430             this.url = url;
431         }
432         public void run()
433         {
434             jEdit.openFile(textArea.getView(),url);
435         }
436     } //}}}
437

438 }
439
Popular Tags