Example usage for com.intellij.openapi.editor RawText fromTransferable

List of usage examples for com.intellij.openapi.editor RawText fromTransferable

Introduction

In this page you can find the example usage for com.intellij.openapi.editor RawText fromTransferable.

Prototype

@Nullable
    public static RawText fromTransferable(Transferable content) 

Source Link

Usage

From source file:com.intellij.codeInsight.editorActions.PasteHandler.java

License:Apache License

private static void doPaste(final Editor editor, final Project project, final PsiFile file,
        final Document document, final Producer<Transferable> producer) {
    Transferable content = null;//  w w w  .  j  a va  2 s.c  om

    if (producer != null) {
        content = producer.produce();
    } else {
        CopyPasteManager manager = CopyPasteManager.getInstance();
        if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) {
            content = manager.getContents();
            if (content != null) {
                manager.stopKillRings();
            }
        }
    }

    if (content != null) {
        String text = null;
        try {
            text = (String) content.getTransferData(DataFlavor.stringFlavor);
        } catch (Exception e) {
            editor.getComponent().getToolkit().beep();
        }
        if (text == null)
            return;

        final CodeInsightSettings settings = CodeInsightSettings.getInstance();

        final Map<CopyPastePostProcessor, List<? extends TextBlockTransferableData>> extraData = new HashMap<CopyPastePostProcessor, List<? extends TextBlockTransferableData>>();
        Collection<TextBlockTransferableData> allValues = new ArrayList<TextBlockTransferableData>();
        for (CopyPastePostProcessor<? extends TextBlockTransferableData> processor : Extensions
                .getExtensions(CopyPastePostProcessor.EP_NAME)) {
            List<? extends TextBlockTransferableData> data = processor.extractTransferableData(content);
            if (!data.isEmpty()) {
                extraData.put(processor, data);
                allValues.addAll(data);
            }
        }

        text = TextBlockTransferable.convertLineSeparators(text, "\n", allValues);

        final CaretModel caretModel = editor.getCaretModel();
        final SelectionModel selectionModel = editor.getSelectionModel();
        final int col = caretModel.getLogicalPosition().column;

        // There is a possible case that we want to perform paste while there is an active selection at the editor and caret is located
        // inside it (e.g. Ctrl+A is pressed while caret is not at the zero column). We want to insert the text at selection start column
        // then, hence, inserted block of text should be indented according to the selection start as well.
        final int blockIndentAnchorColumn;
        final int caretOffset = caretModel.getOffset();
        if (selectionModel.hasSelection() && caretOffset >= selectionModel.getSelectionStart()) {
            blockIndentAnchorColumn = editor.offsetToLogicalPosition(selectionModel.getSelectionStart()).column;
        } else {
            blockIndentAnchorColumn = col;
        }

        // We assume that EditorModificationUtil.insertStringAtCaret() is smart enough to remove currently selected text (if any).

        RawText rawText = RawText.fromTransferable(content);
        String newText = text;
        for (CopyPastePreProcessor preProcessor : Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) {
            newText = preProcessor.preprocessOnPaste(project, file, editor, newText, rawText);
        }
        int indentOptions = text.equals(newText) ? settings.REFORMAT_ON_PASTE
                : CodeInsightSettings.REFORMAT_BLOCK;
        text = newText;

        if (LanguageFormatting.INSTANCE.forContext(file) == null
                && indentOptions != CodeInsightSettings.NO_REFORMAT) {
            indentOptions = CodeInsightSettings.INDENT_BLOCK;
        }

        final String _text = text;
        ApplicationManager.getApplication().runWriteAction(new Runnable() {
            @Override
            public void run() {
                EditorModificationUtil.insertStringAtCaret(editor, _text, false, true);
            }
        });

        int length = text.length();
        int offset = caretModel.getOffset() - length;
        if (offset < 0) {
            length += offset;
            offset = 0;
        }
        final RangeMarker bounds = document.createRangeMarker(offset, offset + length);

        caretModel.moveToOffset(bounds.getEndOffset());
        editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
        selectionModel.removeSelection();

        final Ref<Boolean> indented = new Ref<Boolean>(Boolean.FALSE);
        for (Map.Entry<CopyPastePostProcessor, List<? extends TextBlockTransferableData>> e : extraData
                .entrySet()) {
            //noinspection unchecked
            e.getKey().processTransferableData(project, editor, bounds, caretOffset, indented, e.getValue());
        }

        boolean pastedTextContainsWhiteSpacesOnly = CharArrayUtil.shiftForward(document.getCharsSequence(),
                bounds.getStartOffset(), " \n\t") >= bounds.getEndOffset();

        VirtualFile virtualFile = file.getVirtualFile();
        if (!pastedTextContainsWhiteSpacesOnly && (virtualFile == null
                || !SingleRootFileViewProvider.isTooLargeForIntelligence(virtualFile))) {
            final int indentOptions1 = indentOptions;

            ApplicationManager.getApplication().runWriteAction(new Runnable() {
                @Override
                public void run() {
                    PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
                    switch (indentOptions1) {
                    case CodeInsightSettings.INDENT_BLOCK:
                        if (!indented.get()) {
                            indentBlock(project, editor, bounds.getStartOffset(), bounds.getEndOffset(),
                                    blockIndentAnchorColumn);
                        }
                        break;

                    case CodeInsightSettings.INDENT_EACH_LINE:
                        if (!indented.get()) {
                            indentEachLine(project, editor, bounds.getStartOffset(), bounds.getEndOffset());
                        }
                        break;

                    case CodeInsightSettings.REFORMAT_BLOCK:
                        indentEachLine(project, editor, bounds.getStartOffset(), bounds.getEndOffset()); // this is needed for example when inserting a comment before method
                        reformatBlock(project, editor, bounds.getStartOffset(), bounds.getEndOffset());
                        break;
                    }
                }
            });
        }

        if (bounds.isValid()) {
            caretModel.moveToOffset(bounds.getEndOffset());
            editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
            selectionModel.removeSelection();
            editor.putUserData(EditorEx.LAST_PASTED_REGION, TextRange.create(bounds));
        }
    }
}