e981eb9375da9d412ca64efa05d01c43e1dd1a87
[idea/community.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / difftool / SvnTreeConflictDiffRequestProvider.java
1 package org.jetbrains.idea.svn.difftool;
2
3 import com.intellij.openapi.progress.BackgroundTaskQueue;
4 import com.intellij.openapi.progress.ProcessCanceledException;
5 import com.intellij.openapi.progress.ProgressIndicator;
6 import com.intellij.openapi.project.Project;
7 import com.intellij.openapi.util.UserDataHolder;
8 import com.intellij.diff.DiffContext;
9 import com.intellij.diff.FrameDiffTool;
10 import com.intellij.diff.chains.DiffRequestProducerException;
11 import com.intellij.diff.requests.DiffRequest;
12 import com.intellij.openapi.vcs.changes.Change;
13 import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
14 import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProvider;
15 import com.intellij.ui.components.panels.Wrapper;
16 import com.intellij.util.ThreeState;
17 import org.jetbrains.annotations.NotNull;
18 import org.jetbrains.annotations.Nullable;
19 import org.jetbrains.idea.svn.ConflictedSvnChange;
20 import org.jetbrains.idea.svn.conflict.TreeConflictDescription;
21 import org.jetbrains.idea.svn.treeConflict.TreeConflictRefreshablePanel;
22
23 import javax.swing.*;
24
25 public class SvnTreeConflictDiffRequestProvider implements ChangeDiffRequestProvider {
26   @NotNull
27   @Override
28   public ThreeState isEquals(@NotNull Change change1, @NotNull Change change2) {
29     if (change1 instanceof ConflictedSvnChange && change2 instanceof ConflictedSvnChange) {
30       if (!change1.isTreeConflict() && !change2.isTreeConflict()) return ThreeState.UNSURE;
31       if (!change1.isTreeConflict() || !change2.isTreeConflict()) return ThreeState.NO;
32
33       TreeConflictDescription description1 = ((ConflictedSvnChange)change1).getBeforeDescription();
34       TreeConflictDescription description2 = ((ConflictedSvnChange)change2).getBeforeDescription();
35       return TreeConflictRefreshablePanel.descriptionsEqual(description1, description2) ? ThreeState.YES : ThreeState.NO;
36     }
37     return ThreeState.UNSURE;
38   }
39
40   @Override
41   public boolean canCreate(@Nullable Project project, @NotNull Change change) {
42     return change instanceof ConflictedSvnChange && ((ConflictedSvnChange)change).getConflictState().isTree();
43   }
44
45   @NotNull
46   @Override
47   public DiffRequest process(@NotNull ChangeDiffRequestProducer presentable,
48                              @NotNull UserDataHolder context,
49                              @NotNull ProgressIndicator indicator) throws DiffRequestProducerException, ProcessCanceledException {
50     return new SvnTreeConflictDiffRequest(((ConflictedSvnChange)presentable.getChange()));
51   }
52
53   public static class SvnTreeConflictDiffRequest extends DiffRequest {
54     @NotNull private final ConflictedSvnChange myChange;
55
56     public SvnTreeConflictDiffRequest(@NotNull ConflictedSvnChange change) {
57       myChange = change;
58     }
59
60     @NotNull
61     public ConflictedSvnChange getChange() {
62       return myChange;
63     }
64
65     @Nullable
66     @Override
67     public String getTitle() {
68       return ChangeDiffRequestProducer.getRequestTitle(myChange);
69     }
70   }
71
72   public static class SvnTreeConflictDiffTool implements FrameDiffTool {
73     @NotNull
74     @Override
75     public String getName() {
76       return "SVN tree conflict viewer";
77     }
78
79     @Override
80     public boolean canShow(@NotNull DiffContext context, @NotNull DiffRequest request) {
81       return request instanceof SvnTreeConflictDiffRequest;
82     }
83
84     @NotNull
85     @Override
86     public DiffViewer createComponent(@NotNull DiffContext context, @NotNull DiffRequest request) {
87       return new SvnTreeConflictDiffViewer(context, (SvnTreeConflictDiffRequest)request);
88     }
89   }
90
91   private static class SvnTreeConflictDiffViewer implements FrameDiffTool.DiffViewer {
92     @NotNull private final DiffContext myContext;
93     @NotNull private final SvnTreeConflictDiffRequest myRequest;
94     @NotNull private final Wrapper myPanel = new Wrapper();
95
96     @NotNull private final BackgroundTaskQueue myQueue;
97     @NotNull private final TreeConflictRefreshablePanel myDelegate;
98
99     public SvnTreeConflictDiffViewer(@NotNull DiffContext context, @NotNull SvnTreeConflictDiffRequest request) {
100       myContext = context;
101       myRequest = request;
102
103       myQueue = new BackgroundTaskQueue(myContext.getProject(), "Loading change details");
104
105       // We don't need to listen on File/Document, because panel always will be the same for a single change.
106       // And if Change will change - we'll create new DiffRequest and DiffViewer
107       myDelegate =
108         new TreeConflictRefreshablePanel(myContext.getProject(), "Loading tree conflict details", myQueue, myRequest.getChange());
109       myDelegate.refresh();
110       myPanel.setContent(myDelegate.getPanel());
111     }
112
113     @NotNull
114     @Override
115     public JComponent getComponent() {
116       return myPanel;
117     }
118
119     @Nullable
120     @Override
121     public JComponent getPreferredFocusedComponent() {
122       return myPanel;
123     }
124
125     @NotNull
126     @Override
127     public FrameDiffTool.ToolbarComponents init() {
128       return new FrameDiffTool.ToolbarComponents();
129     }
130
131     @Override
132     public void dispose() {
133       myQueue.clear();
134     }
135   }
136 }