made all fields final. Could not resist, sorry
[fedora-idea.git] / lang-impl / src / com / intellij / ide / PsiCopyPasteManager.java
blob2b906aedc87ef7bf6aefdac55266348741566c98
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;
34 @Nullable
35 public PsiElement[] getElements(boolean[] isCopied) {
36 try {
37 Transferable content = myCopyPasteManager.getSystemClipboardContents();
38 Object transferData;
39 try {
40 transferData = content.getTransferData(ourDataFlavor);
41 } catch (UnsupportedFlavorException e) {
42 return null;
43 } catch (IOException e) {
44 return null;
47 if (!(transferData instanceof MyData)) {
48 return null;
50 MyData dataProxy = (MyData) transferData;
51 if (!Comparing.equal(dataProxy, myRecentData)) {
52 return null;
54 if (isCopied != null) {
55 isCopied[0] = myRecentData.isCopied();
57 return myRecentData.getElements();
58 } catch (Exception e) {
59 if (LOG.isDebugEnabled()) {
60 LOG.debug(e);
62 return null;
66 @Nullable
67 static PsiElement[] getElements(final Transferable content) {
68 if (content == null) return null;
69 Object transferData;
70 try {
71 transferData = content.getTransferData(ourDataFlavor);
72 } catch (UnsupportedFlavorException e) {
73 return null;
74 } catch (IOException e) {
75 return null;
78 return transferData instanceof MyData ? ((MyData)transferData).getElements() : null;
81 public void clear() {
82 Transferable old = myCopyPasteManager.getContents();
83 myRecentData = null;
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;
103 return false;
106 private static final DataFlavor ourDataFlavor;
107 static {
108 try {
109 final Class<MyData> flavorClass = MyData.class;
110 final Thread currentThread = Thread.currentThread();
111 final ClassLoader currentLoader = currentThread.getContextClassLoader();
112 try {
113 currentThread.setContextClassLoader(flavorClass.getClassLoader());
114 ourDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + flavorClass.getName());
116 finally {
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;
132 myIsCopied = copied;
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) {
147 return myElements;
150 PsiElement[] validElements = new PsiElement[validElementsCount];
151 int j=0;
152 for (PsiElement element : myElements) {
153 if (element.isValid()) {
154 validElements[j++] = element;
158 myElements = validElements;
159 return myElements;
162 public boolean isCopied() {
163 return myIsCopied;
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) {
172 myDataProxy = data;
175 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
176 if (ourDataFlavor.equals(flavor)) {
177 return myDataProxy;
179 if (DataFlavor.stringFlavor.equals(flavor)) {
180 return getDataAsText();
182 return null;
185 @Nullable
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();
191 if (name != null) {
192 names.add(name);
196 if (names.isEmpty()) {
197 return null;
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();