blob: c26c7e99ba63c6b9a11e2a93cfaea4b50087a69d [file] [log] [blame]
/*
* 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;
}
}