migrated to artifacts
[fedora-idea.git] / platform / lang-impl / src / com / intellij / ide / PsiCopyPasteManager.java
blobd3f7e58a4dc29530f9a72d96393d264b00731619
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.openapi.vfs.LocalFileSystem;
9 import com.intellij.openapi.vfs.VirtualFile;
10 import com.intellij.psi.PsiElement;
11 import com.intellij.psi.PsiFile;
12 import com.intellij.psi.PsiNamedElement;
13 import org.jetbrains.annotations.Nullable;
15 import java.awt.datatransfer.DataFlavor;
16 import java.awt.datatransfer.StringSelection;
17 import java.awt.datatransfer.Transferable;
18 import java.awt.datatransfer.UnsupportedFlavorException;
19 import java.io.File;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
24 public class PsiCopyPasteManager {
25 public static PsiCopyPasteManager getInstance() {
26 return ServiceManager.getService(PsiCopyPasteManager.class);
29 private static final Logger LOG = Logger.getInstance("#com.intellij.ide.PsiCopyPasteManagerImpl");
31 private MyData myRecentData;
32 private final CopyPasteManagerEx myCopyPasteManager;
34 public PsiCopyPasteManager(CopyPasteManager copyPasteManager) {
35 myCopyPasteManager = (CopyPasteManagerEx) copyPasteManager;
38 @Nullable
39 public PsiElement[] getElements(boolean[] isCopied) {
40 try {
41 Transferable content = myCopyPasteManager.getSystemClipboardContents();
42 Object transferData;
43 try {
44 transferData = content.getTransferData(ourDataFlavor);
45 } catch (UnsupportedFlavorException e) {
46 return null;
47 } catch (IOException e) {
48 return null;
51 if (!(transferData instanceof MyData)) {
52 return null;
54 MyData dataProxy = (MyData) transferData;
55 if (!Comparing.equal(dataProxy, myRecentData)) {
56 return null;
58 if (isCopied != null) {
59 isCopied[0] = myRecentData.isCopied();
61 return myRecentData.getElements();
62 } catch (Exception e) {
63 if (LOG.isDebugEnabled()) {
64 LOG.debug(e);
66 return null;
70 @Nullable
71 static PsiElement[] getElements(final Transferable content) {
72 if (content == null) return null;
73 Object transferData;
74 try {
75 transferData = content.getTransferData(ourDataFlavor);
76 } catch (UnsupportedFlavorException e) {
77 return null;
78 } catch (IOException e) {
79 return null;
82 return transferData instanceof MyData ? ((MyData)transferData).getElements() : null;
85 public void clear() {
86 Transferable old = myCopyPasteManager.getContents();
87 myRecentData = null;
88 myCopyPasteManager.setSystemClipboardContent(new StringSelection(""));
89 myCopyPasteManager.fireContentChanged(old);
92 public void setElements(PsiElement[] elements, boolean copied) {
93 Transferable old = myCopyPasteManager.getContents();
94 myRecentData = new MyData(elements, copied);
95 myCopyPasteManager.setSystemClipboardContent(new MyTransferable(myRecentData));
96 myCopyPasteManager.fireContentChanged(old);
99 public boolean isCutElement(Object element) {
100 if (myRecentData == null) return false;
101 if (myRecentData.isCopied()) return false;
102 PsiElement[] elements = myRecentData.getElements();
103 if (elements == null) return false;
104 for (PsiElement aElement : elements) {
105 if (aElement == element) return true;
107 return false;
110 private static final DataFlavor ourDataFlavor;
112 static {
113 try {
114 final Class<MyData> flavorClass = MyData.class;
115 final Thread currentThread = Thread.currentThread();
116 final ClassLoader currentLoader = currentThread.getContextClassLoader();
117 try {
118 currentThread.setContextClassLoader(flavorClass.getClassLoader());
119 ourDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + flavorClass.getName());
121 finally {
122 currentThread.setContextClassLoader(currentLoader);
125 catch (ClassNotFoundException e) {
126 throw new RuntimeException(e);
131 private static class MyData {
132 private PsiElement[] myElements;
133 private final boolean myIsCopied;
135 public MyData(PsiElement[] elements, boolean copied) {
136 myElements = elements;
137 myIsCopied = copied;
140 public PsiElement[] getElements() {
141 if (myElements == null) return PsiElement.EMPTY_ARRAY;
143 int validElementsCount = 0;
145 for (PsiElement element : myElements) {
146 if (element.isValid()) {
147 validElementsCount++;
151 if (validElementsCount == myElements.length) {
152 return myElements;
155 PsiElement[] validElements = new PsiElement[validElementsCount];
156 int j=0;
157 for (PsiElement element : myElements) {
158 if (element.isValid()) {
159 validElements[j++] = element;
163 myElements = validElements;
164 return myElements;
167 public boolean isCopied() {
168 return myIsCopied;
172 public static class MyTransferable implements Transferable {
173 private final MyData myDataProxy;
174 private static final DataFlavor[] DATA_FLAVOR_ARRAY = new DataFlavor[]{ourDataFlavor, DataFlavor.stringFlavor, DataFlavor.javaFileListFlavor};
176 public MyTransferable(MyData data) {
177 myDataProxy = data;
180 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
181 if (ourDataFlavor.equals(flavor)) {
182 return myDataProxy;
184 if (DataFlavor.stringFlavor.equals(flavor)) {
185 return getDataAsText();
187 if (DataFlavor.javaFileListFlavor.equals(flavor)) {
188 return asFileList(myDataProxy.getElements());
190 return null;
193 @Nullable
194 private String getDataAsText() {
195 List<String> names = new ArrayList<String>();
196 for (PsiElement element : myDataProxy.getElements()) {
197 if (element instanceof PsiNamedElement) {
198 String name = ((PsiNamedElement) element).getName();
199 if (name != null) {
200 names.add(name);
204 if (names.isEmpty()) {
205 return null;
207 return StringUtil.join(names, "\n");
211 public DataFlavor[] getTransferDataFlavors() {
212 return DATA_FLAVOR_ARRAY;
215 public boolean isDataFlavorSupported(DataFlavor flavor) {
216 return flavor.equals(ourDataFlavor) || flavor.equals(DataFlavor.stringFlavor) || flavor.equals(DataFlavor.javaFileListFlavor);
219 public PsiElement[] getElements() {
220 return myDataProxy.getElements();
224 public static List<File> asFileList(final PsiElement[] elements) {
225 List<File> result = new ArrayList<File>();
226 for (PsiElement element : elements) {
227 final PsiFile psiFile = element.getContainingFile();
228 if (psiFile != null) {
229 VirtualFile vFile = psiFile.getVirtualFile();
230 if (vFile != null && vFile.getFileSystem() instanceof LocalFileSystem) {
231 result.add(new File(vFile.getPath()));
235 if (result.isEmpty()) {
236 return null;
238 return result;