diff options
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java')
-rw-r--r-- | platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java new file mode 100644 index 000000000000..c26c7e99ba63 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java @@ -0,0 +1,150 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.editor.impl; + +import com.intellij.codeInsight.editorActions.TextBlockTransferable; +import com.intellij.codeInsight.editorActions.TextBlockTransferableData; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.LineTokenizer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +public class EditorCopyPasteHelperImpl extends EditorCopyPasteHelper { + private static final Logger LOG = Logger.getInstance(EditorCopyPasteHelperImpl.class); + + @Override + public void copySelectionToClipboard(@NotNull Editor editor) { + ApplicationManager.getApplication().assertIsDispatchThread(); + List<TextBlockTransferableData> extraData = new ArrayList<TextBlockTransferableData>(); + String s = editor.getCaretModel().supportsMultipleCarets() ? getSelectedTextForClipboard(editor, extraData) + : editor.getSelectionModel().getSelectedText(); + if (s == null) return; + + s = TextBlockTransferable.convertLineSeparators(s, "\n", extraData); + Transferable contents = editor.getCaretModel().supportsMultipleCarets() ? new TextBlockTransferable(s, extraData, null) : new StringSelection(s); + CopyPasteManager.getInstance().setContents(contents); + } + + public static String getSelectedTextForClipboard(@NotNull Editor editor, @NotNull Collection<TextBlockTransferableData> extraDataCollector) { + final StringBuilder buf = new StringBuilder(); + String separator = ""; + List<Caret> carets = editor.getCaretModel().getAllCarets(); + int[] startOffsets = new int[carets.size()]; + int[] endOffsets = new int[carets.size()]; + for (int i = 0; i < carets.size(); i++) { + buf.append(separator); + String caretSelectedText = carets.get(i).getSelectedText(); + startOffsets[i] = buf.length(); + if (caretSelectedText != null) { + buf.append(caretSelectedText); + } + endOffsets[i] = buf.length(); + separator = "\n"; + } + extraDataCollector.add(new CaretStateTransferableData(startOffsets, endOffsets)); + return buf.toString(); + } + + @Nullable + @Override + public TextRange[] pasteFromClipboard(@NotNull Editor editor) { + CopyPasteManager manager = CopyPasteManager.getInstance(); + if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) { + Transferable clipboardContents = manager.getContents(); + if (clipboardContents != null) { + return pasteTransferable(editor, clipboardContents); + } + } + return null; + } + + @Nullable + @Override + public TextRange[] pasteTransferable(final @NotNull Editor editor, @NotNull Transferable content) { + String text = getStringContent(content); + if (text == null) return null; + + if (editor.getCaretModel().supportsMultipleCarets()) { + int caretCount = editor.getCaretModel().getCaretCount(); + if (caretCount == 1 && editor.isColumnMode()) { + int pastedLineCount = LineTokenizer.calcLineCount(text, true); + EditorModificationUtil.deleteSelectedText(editor); + Caret caret = editor.getCaretModel().getPrimaryCaret(); + for (int i = 0; i < pastedLineCount - 1; i++) { + caret = caret.clone(false); + if (caret == null) { + break; + } + } + caretCount = editor.getCaretModel().getCaretCount(); + } + CaretStateTransferableData caretData = null; + try { + caretData = content.isDataFlavorSupported(CaretStateTransferableData.FLAVOR) + ? (CaretStateTransferableData)content.getTransferData(CaretStateTransferableData.FLAVOR) : null; + } + catch (Exception e) { + LOG.error(e); + } + final TextRange[] ranges = new TextRange[caretCount]; + final Iterator<String> segments = new ClipboardTextPerCaretSplitter().split(text, caretData, caretCount).iterator(); + final int[] index = {0}; + editor.getCaretModel().runForEachCaret(new CaretAction() { + @Override + public void perform(Caret caret) { + String segment = segments.next(); + int caretOffset = caret.getOffset(); + ranges[index[0]++] = new TextRange(caretOffset, caretOffset + segment.length()); + EditorModificationUtil.insertStringAtCaret(editor, segment, false, true); + } + }); + return ranges; + } + else { + int caretOffset = editor.getCaretModel().getOffset(); + EditorModificationUtil.insertStringAtCaret(editor, text, false, true); + return new TextRange[] { new TextRange(caretOffset, caretOffset + text.length())}; + } + } + + @Nullable + private static String getStringContent(@NotNull Transferable content) { + RawText raw = RawText.fromTransferable(content); + if (raw != null) return raw.rawText; + + try { + return (String)content.getTransferData(DataFlavor.stringFlavor); + } + catch (UnsupportedFlavorException ignore) { } + catch (IOException ignore) { } + + return null; + } +} |