diff: add annotate action to diff viewers
[idea/community.git] / platform / diff-impl / src / com / intellij / diff / actions / CompareClipboardWithSelectionAction.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.diff.actions;
17
18 import com.intellij.diff.DiffContentFactory;
19 import com.intellij.diff.DiffRequestFactory;
20 import com.intellij.diff.contents.DiffContent;
21 import com.intellij.diff.contents.DocumentContent;
22 import com.intellij.diff.requests.ContentDiffRequest;
23 import com.intellij.diff.requests.DiffRequest;
24 import com.intellij.diff.requests.SimpleDiffRequest;
25 import com.intellij.diff.tools.util.DiffDataKeys;
26 import com.intellij.diff.util.DiffUserDataKeys;
27 import com.intellij.openapi.actionSystem.AnActionEvent;
28 import com.intellij.openapi.actionSystem.CommonDataKeys;
29 import com.intellij.openapi.diff.DiffBundle;
30 import com.intellij.openapi.editor.Editor;
31 import com.intellij.openapi.editor.SelectionModel;
32 import com.intellij.openapi.fileEditor.FileDocumentManager;
33 import com.intellij.openapi.fileEditor.FileEditorManager;
34 import com.intellij.openapi.fileTypes.FileType;
35 import com.intellij.openapi.fileTypes.UnknownFileType;
36 import com.intellij.openapi.project.Project;
37 import com.intellij.openapi.util.TextRange;
38 import com.intellij.openapi.vfs.VirtualFile;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
41
42 public class CompareClipboardWithSelectionAction extends BaseShowDiffAction {
43   @Nullable
44   private static Editor getEditor(@NotNull AnActionEvent e) {
45     Project project = e.getProject();
46     if (project == null) return null;
47
48     Editor editor = e.getData(CommonDataKeys.EDITOR);
49     if (editor != null) return editor;
50
51     editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
52     if (editor != null) return editor;
53
54     return null;
55   }
56
57   @Nullable
58   private static FileType getEditorFileType(@NotNull AnActionEvent e) {
59     DiffContent content = e.getData(DiffDataKeys.CURRENT_CONTENT);
60     if (content != null && content.getContentType() != null) return content.getContentType();
61
62     DiffRequest request = e.getData(DiffDataKeys.DIFF_REQUEST);
63     if (request instanceof ContentDiffRequest) {
64       for (DiffContent diffContent : ((ContentDiffRequest)request).getContents()) {
65         FileType type = diffContent.getContentType();
66         if (type != null && type != UnknownFileType.INSTANCE) return type;
67       }
68     }
69
70     return null;
71   }
72
73   @Override
74   protected boolean isAvailable(@NotNull AnActionEvent e) {
75     Editor editor = getEditor(e);
76     return editor != null;
77   }
78
79   @Nullable
80   @Override
81   protected DiffRequest getDiffRequest(@NotNull AnActionEvent e) {
82     Project project = e.getRequiredData(CommonDataKeys.PROJECT);
83     Editor editor = getEditor(e);
84     FileType editorFileType = getEditorFileType(e);
85     assert editor != null;
86
87     DocumentContent content2 = createContent(project, editor, editorFileType);
88     DocumentContent content1 = DiffContentFactory.getInstance().createClipboardContent(content2);
89
90     String title1 = DiffBundle.message("diff.content.clipboard.content.title");
91     String title2 = createContentTitle(editor);
92
93     String title = DiffBundle.message("diff.clipboard.vs.editor.dialog.title");
94
95     SimpleDiffRequest request = new SimpleDiffRequest(title, content1, content2, title1, title2);
96     if (editor.isViewer()) {
97       request.putUserData(DiffUserDataKeys.FORCE_READ_ONLY_CONTENTS, new boolean[]{false, true});
98     }
99     return request;
100   }
101
102   @NotNull
103   private static DocumentContent createContent(@NotNull Project project, @NotNull Editor editor, @Nullable FileType type) {
104     DocumentContent content = DiffContentFactory.getInstance().create(project, editor.getDocument(), type);
105
106     SelectionModel selectionModel = editor.getSelectionModel();
107     if (selectionModel.hasSelection()) {
108       TextRange range = new TextRange(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
109       content = new DocumentFragmentContent(project, content, range);
110     }
111
112     return content;
113   }
114
115   @NotNull
116   private static String createContentTitle(@NotNull Editor editor) {
117     VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument());
118     String title = file != null ? DiffRequestFactory.getInstance().getContentTitle(file) : "Editor";
119
120     if (editor.getSelectionModel().hasSelection()) {
121       title = DiffBundle.message("diff.content.selection.from.file.content.title", title);
122     }
123
124     return title;
125   }
126 }