1 package com
.intellij
.ide
;
3 import com
.intellij
.openapi
.components
.ServiceManager
;
4 import com
.intellij
.openapi
.diagnostic
.Logger
;
5 import com
.intellij
.openapi
.ide
.CopyPasteManager
;
6 import com
.intellij
.openapi
.util
.Comparing
;
7 import com
.intellij
.openapi
.util
.text
.StringUtil
;
8 import com
.intellij
.psi
.PsiElement
;
9 import com
.intellij
.psi
.PsiNamedElement
;
10 import org
.jetbrains
.annotations
.Nullable
;
12 import java
.awt
.datatransfer
.DataFlavor
;
13 import java
.awt
.datatransfer
.StringSelection
;
14 import java
.awt
.datatransfer
.Transferable
;
15 import java
.awt
.datatransfer
.UnsupportedFlavorException
;
16 import java
.io
.IOException
;
17 import java
.util
.ArrayList
;
18 import java
.util
.List
;
20 public class PsiCopyPasteManager
{
21 public static PsiCopyPasteManager
getInstance() {
22 return ServiceManager
.getService(PsiCopyPasteManager
.class);
25 private static final Logger LOG
= Logger
.getInstance("#com.intellij.ide.PsiCopyPasteManagerImpl");
27 private MyData myRecentData
;
28 private final CopyPasteManagerEx myCopyPasteManager
;
30 public PsiCopyPasteManager(CopyPasteManager copyPasteManager
) {
31 myCopyPasteManager
= (CopyPasteManagerEx
) copyPasteManager
;
35 public PsiElement
[] getElements(boolean[] isCopied
) {
37 Transferable content
= myCopyPasteManager
.getSystemClipboardContents();
40 transferData
= content
.getTransferData(ourDataFlavor
);
41 } catch (UnsupportedFlavorException e
) {
43 } catch (IOException e
) {
47 if (!(transferData
instanceof MyData
)) {
50 MyData dataProxy
= (MyData
) transferData
;
51 if (!Comparing
.equal(dataProxy
, myRecentData
)) {
54 if (isCopied
!= null) {
55 isCopied
[0] = myRecentData
.isCopied();
57 return myRecentData
.getElements();
58 } catch (Exception e
) {
59 if (LOG
.isDebugEnabled()) {
67 static PsiElement
[] getElements(final Transferable content
) {
68 if (content
== null) return null;
71 transferData
= content
.getTransferData(ourDataFlavor
);
72 } catch (UnsupportedFlavorException e
) {
74 } catch (IOException e
) {
78 return transferData
instanceof MyData ?
((MyData
)transferData
).getElements() : null;
82 Transferable old
= myCopyPasteManager
.getContents();
84 myCopyPasteManager
.setSystemClipboardContent(new StringSelection(""));
85 myCopyPasteManager
.fireContentChanged(old
);
88 public void setElements(PsiElement
[] elements
, boolean copied
) {
89 Transferable old
= myCopyPasteManager
.getContents();
90 myRecentData
= new MyData(elements
, copied
);
91 myCopyPasteManager
.setSystemClipboardContent(new MyTransferable(myRecentData
));
92 myCopyPasteManager
.fireContentChanged(old
);
95 public boolean isCutElement(Object element
) {
96 if (myRecentData
== null) return false;
97 if (myRecentData
.isCopied()) return false;
98 PsiElement
[] elements
= myRecentData
.getElements();
99 if (elements
== null) return false;
100 for (PsiElement aElement
: elements
) {
101 if (aElement
== element
) return true;
106 private static final DataFlavor ourDataFlavor
;
109 final Class
<MyData
> flavorClass
= MyData
.class;
110 final Thread currentThread
= Thread
.currentThread();
111 final ClassLoader currentLoader
= currentThread
.getContextClassLoader();
113 currentThread
.setContextClassLoader(flavorClass
.getClassLoader());
114 ourDataFlavor
= new DataFlavor(DataFlavor
.javaJVMLocalObjectMimeType
+ ";class=" + flavorClass
.getName());
117 currentThread
.setContextClassLoader(currentLoader
);
120 catch (ClassNotFoundException e
) {
121 throw new RuntimeException(e
);
126 private static class MyData
{
127 private PsiElement
[] myElements
;
128 private final boolean myIsCopied
;
130 public MyData(PsiElement
[] elements
, boolean copied
) {
131 myElements
= elements
;
135 public PsiElement
[] getElements() {
136 if (myElements
== null) return PsiElement
.EMPTY_ARRAY
;
138 int validElementsCount
= 0;
140 for (PsiElement element
: myElements
) {
141 if (element
.isValid()) {
142 validElementsCount
++;
146 if (validElementsCount
== myElements
.length
) {
150 PsiElement
[] validElements
= new PsiElement
[validElementsCount
];
152 for (PsiElement element
: myElements
) {
153 if (element
.isValid()) {
154 validElements
[j
++] = element
;
158 myElements
= validElements
;
162 public boolean isCopied() {
167 public static class MyTransferable
implements Transferable
{
168 private final MyData myDataProxy
;
169 private static final DataFlavor
[] DATA_FLAVOR_ARRAY
= new DataFlavor
[]{ourDataFlavor
, DataFlavor
.stringFlavor
};
171 public MyTransferable(MyData data
) {
175 public Object
getTransferData(DataFlavor flavor
) throws UnsupportedFlavorException
, IOException
{
176 if (ourDataFlavor
.equals(flavor
)) {
179 if (DataFlavor
.stringFlavor
.equals(flavor
)) {
180 return getDataAsText();
186 private String
getDataAsText() {
187 List
<String
> names
= new ArrayList
<String
>();
188 for (PsiElement element
: myDataProxy
.getElements()) {
189 if (element
instanceof PsiNamedElement
) {
190 String name
= ((PsiNamedElement
) element
).getName();
196 if (names
.isEmpty()) {
199 return StringUtil
.join(names
, "\n");
202 public DataFlavor
[] getTransferDataFlavors() {
203 return DATA_FLAVOR_ARRAY
;
206 public boolean isDataFlavorSupported(DataFlavor flavor
) {
207 return flavor
.equals(ourDataFlavor
) || flavor
.equals(DataFlavor
.stringFlavor
);
210 public PsiElement
[] getElements() {
211 return myDataProxy
.getElements();