/jEdit/tags/jedit-4-3-pre4/org/gjt/sp/jedit/textarea/TextAreaTransferHandler.java

# · Java · 344 lines · 259 code · 41 blank · 44 comment · 41 complexity · fa72ff5753579485a9a3aad3751fae9c MD5 · raw file

  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. package org.gjt.sp.jedit.textarea;
  23. //{{{ Imports
  24. import javax.swing.*;
  25. import java.awt.datatransfer.*;
  26. import java.io.File;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import org.gjt.sp.jedit.Buffer;
  30. import org.gjt.sp.jedit.EditPane;
  31. import org.gjt.sp.jedit.GUIUtilities;
  32. import org.gjt.sp.jedit.jEdit;
  33. import org.gjt.sp.util.Log;
  34. //}}}
  35. class TextAreaTransferHandler extends TransferHandler
  36. {
  37. /* I assume that there can be only one drag operation at the time */
  38. private static JEditTextArea dragSource;
  39. private static boolean compoundEdit;
  40. private static boolean sameTextArea;
  41. private static int insertPos;
  42. private static int insertOffset;
  43. //{{{ createTransferable
  44. protected Transferable createTransferable(JComponent c)
  45. {
  46. Log.log(Log.DEBUG,this,"createTransferable()");
  47. JEditTextArea textArea = (JEditTextArea)c;
  48. if(textArea.getSelectionCount() == 0)
  49. return null;
  50. else
  51. {
  52. dragSource = textArea;
  53. return new TextAreaSelection(textArea);
  54. }
  55. } //}}}
  56. //{{{ getSourceActions
  57. public int getSourceActions(JComponent c)
  58. {
  59. return COPY_OR_MOVE;
  60. } //}}}
  61. //{{{ importData
  62. public boolean importData(JComponent c, Transferable t)
  63. {
  64. Log.log(Log.DEBUG,this,"Import data");
  65. if(!canImport(c,t.getTransferDataFlavors()))
  66. return false;
  67. boolean returnValue;
  68. try
  69. {
  70. if(t.isDataFlavorSupported(
  71. DataFlavor.javaFileListFlavor))
  72. {
  73. returnValue = importFile(c,t);
  74. }
  75. else
  76. {
  77. returnValue = importText(c,t);
  78. }
  79. }
  80. catch(Exception e)
  81. {
  82. Log.log(Log.ERROR,this,e);
  83. returnValue = false;
  84. }
  85. GUIUtilities.getView(c).toFront();
  86. GUIUtilities.getView(c).requestFocus();
  87. c.requestFocus();
  88. return returnValue;
  89. } //}}}
  90. //{{{ importFile
  91. private boolean importFile(JComponent c, Transferable t)
  92. throws Exception
  93. {
  94. Log.log(Log.DEBUG,this,"=> File list");
  95. EditPane editPane = (EditPane)
  96. GUIUtilities.getComponentParent(
  97. c,EditPane.class);
  98. Buffer buffer = null;
  99. Object data = t.getTransferData(
  100. DataFlavor.javaFileListFlavor);
  101. Iterator iterator = ((List)data)
  102. .iterator();
  103. while(iterator.hasNext())
  104. {
  105. File file = (File)
  106. iterator.next();
  107. Buffer _buffer = jEdit.openFile(null,
  108. file.getPath());
  109. if(_buffer != null)
  110. buffer = _buffer;
  111. }
  112. if(buffer != null)
  113. editPane.setBuffer(buffer);
  114. editPane.getView().toFront();
  115. editPane.getView().requestFocus();
  116. editPane.requestFocus();
  117. return true;
  118. } //}}}
  119. //{{{ importText
  120. private boolean importText(JComponent c, Transferable t)
  121. throws Exception
  122. {
  123. Log.log(Log.DEBUG,this,"=> String");
  124. String str = (String)t.getTransferData(
  125. DataFlavor.stringFlavor);
  126. JEditTextArea textArea = (JEditTextArea)c;
  127. if (dragSource == null)
  128. {
  129. // Only examine the string for a URL if it came from
  130. // outside of jEdit.
  131. org.gjt.sp.jedit.io.VFS vfs = org.gjt.sp.jedit.io.VFSManager.getVFSForPath(str);
  132. if (!(vfs instanceof org.gjt.sp.jedit.io.FileVFS) || str.startsWith("file://"))
  133. {
  134. str = str.replace('\n',' ').replace('\r',' ').trim();
  135. if (str.startsWith("file://"))
  136. {
  137. str = str.substring(7);
  138. }
  139. org.gjt.sp.jedit.io.VFSManager.runInWorkThread(
  140. new DraggedURLLoader(textArea,str)
  141. );
  142. return true;
  143. }
  144. }
  145. if(dragSource != null
  146. && textArea.getBuffer()
  147. == dragSource.getBuffer())
  148. {
  149. compoundEdit = true;
  150. textArea.getBuffer().beginCompoundEdit();
  151. }
  152. sameTextArea = (textArea == dragSource);
  153. int caret = textArea.getCaretPosition();
  154. Selection s = textArea.getSelectionAtOffset(caret);
  155. /* if user drops into the same
  156. selection where they started, do
  157. nothing. */
  158. if(s != null)
  159. {
  160. if(sameTextArea)
  161. return false;
  162. /* if user drops into a selection,
  163. replace selection */
  164. int startPos = s.start;
  165. textArea.setSelectedText(s,str);
  166. textArea.setSelection(new Selection.Range(startPos,startPos+str.length()));
  167. }
  168. /* otherwise just insert the text */
  169. else
  170. {
  171. if (sameTextArea)
  172. {
  173. insertPos = caret;
  174. insertOffset = 0;
  175. Selection[] selections = textArea.getSelection();
  176. for (int i=0;i<selections.length;i++)
  177. {
  178. if (selections[i].end<(insertPos+insertOffset))
  179. insertOffset-=(selections[i].end-selections[i].start);
  180. }
  181. }
  182. else
  183. {
  184. textArea.getBuffer().insert(caret,str);
  185. textArea.setSelection(new Selection.Range(caret,caret+str.length()));
  186. }
  187. }
  188. textArea.scrollToCaret(true);
  189. return true;
  190. } //}}}
  191. //{{{ exportDone
  192. protected void exportDone(JComponent c, Transferable t,
  193. int action)
  194. {
  195. Log.log(Log.DEBUG,this,"Export done");
  196. JEditTextArea textArea = (JEditTextArea)c;
  197. try
  198. {
  199. // This happens if importData returns false. For example if you drop into the Selection
  200. if (action == NONE)
  201. {
  202. Log.log(Log.DEBUG,this,"Export impossible");
  203. return;
  204. }
  205. if(t == null)
  206. {
  207. Log.log(Log.DEBUG,this,"=> Null transferrable");
  208. textArea.selectNone();
  209. }
  210. else if(t.isDataFlavorSupported(
  211. DataFlavor.stringFlavor))
  212. {
  213. Log.log(Log.DEBUG,this,"=> String");
  214. if (sameTextArea)
  215. {
  216. if(action == MOVE)
  217. {
  218. textArea.setSelectedText(null,false);
  219. insertPos += insertOffset;
  220. }
  221. try
  222. {
  223. String str = (String)t.getTransferData(DataFlavor.stringFlavor);
  224. textArea.getBuffer().insert(insertPos,str);
  225. textArea.setSelection(new Selection.Range(insertPos,insertPos+str.length()));
  226. }
  227. catch(Exception e)
  228. {
  229. Log.log(Log.DEBUG,this,"exportDone in sameTextArea");
  230. Log.log(Log.DEBUG,this,e);
  231. }
  232. }
  233. else
  234. {
  235. if(action == MOVE)
  236. textArea.setSelectedText(null,false);
  237. else
  238. textArea.selectNone();
  239. }
  240. }
  241. }
  242. finally
  243. {
  244. if(compoundEdit)
  245. {
  246. compoundEdit = false;
  247. textArea.getBuffer().endCompoundEdit();
  248. }
  249. }
  250. dragSource = null;
  251. } //}}}
  252. //{{{ canImport
  253. public boolean canImport(JComponent c, DataFlavor[] flavors)
  254. {
  255. JEditTextArea textArea = (JEditTextArea)c;
  256. // correctly handle text flavor + file list flavor
  257. // + text area read only, do an or of all flags
  258. boolean returnValue = false;
  259. for(int i = 0; i < flavors.length; i++)
  260. {
  261. if(flavors[i].equals(
  262. DataFlavor.javaFileListFlavor))
  263. {
  264. returnValue = true;
  265. }
  266. else if(flavors[i].equals(
  267. DataFlavor.stringFlavor))
  268. {
  269. if(textArea.isEditable())
  270. returnValue = true;
  271. }
  272. }
  273. Log.log(Log.DEBUG,this,"canImport() returning "
  274. + returnValue);
  275. return returnValue;
  276. } //}}}
  277. //{{{ TextAreaSelection class
  278. static class TextAreaSelection extends StringSelection
  279. {
  280. JEditTextArea textArea;
  281. TextAreaSelection(JEditTextArea textArea)
  282. {
  283. super(textArea.getSelectedText());
  284. this.textArea = textArea;
  285. }
  286. } //}}}
  287. //{{{ DraggedURLLoader
  288. class DraggedURLLoader extends org.gjt.sp.util.WorkRequest
  289. {
  290. private JEditTextArea textArea;
  291. private String url;
  292. public DraggedURLLoader(JEditTextArea textArea, String url)
  293. {
  294. super();
  295. this.textArea = textArea;
  296. this.url = url;
  297. }
  298. public void run()
  299. {
  300. jEdit.openFile(textArea.getView(),url);
  301. }
  302. } //}}}
  303. }