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