summaryrefslogtreecommitdiff
path: root/platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java')
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java197
1 files changed, 197 insertions, 0 deletions
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java
new file mode 100644
index 000000000000..8a16ba6a481f
--- /dev/null
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java
@@ -0,0 +1,197 @@
+/*
+ * 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.vcs.history;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogBuilder;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ui.ChangesBrowser;
+import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public abstract class BaseDiffFromHistoryHandler<T extends VcsFileRevision> implements DiffFromHistoryHandler {
+
+ private static final Logger LOG = Logger.getInstance(BaseDiffFromHistoryHandler.class);
+
+ @NotNull protected final Project myProject;
+
+ protected BaseDiffFromHistoryHandler(@NotNull Project project) {
+ myProject = project;
+ }
+
+ @Override
+ public void showDiffForOne(@NotNull AnActionEvent e,
+ @NotNull FilePath filePath,
+ @NotNull VcsFileRevision previousRevision,
+ @NotNull VcsFileRevision revision) {
+ doShowDiff(filePath, previousRevision, revision, false);
+ }
+
+ @Override
+ public void showDiffForTwo(@NotNull FilePath filePath, @NotNull VcsFileRevision revision1, @NotNull VcsFileRevision revision2) {
+ doShowDiff(filePath, revision1, revision2, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void doShowDiff(@NotNull FilePath filePath,
+ @NotNull VcsFileRevision revision1,
+ @NotNull VcsFileRevision revision2,
+ boolean autoSort) {
+ if (!filePath.isDirectory()) {
+ VcsHistoryUtil.showDifferencesInBackground(myProject, filePath, revision1, revision2, autoSort);
+ }
+ else if (revision1.equals(VcsFileRevision.NULL)) {
+ T right = (T)revision2;
+ showAffectedChanges(filePath, right);
+ }
+ else if (revision2 instanceof CurrentRevision) {
+ T left = (T)revision1;
+ showChangesBetweenRevisions(filePath, left, null);
+ }
+ else {
+ T left = (T)revision1;
+ T right = (T)revision2;
+ if (autoSort) {
+ Couple<VcsFileRevision> pair = VcsHistoryUtil.sortRevisions(revision1, revision2);
+ left = (T)pair.first;
+ right = (T)pair.second;
+ }
+ showChangesBetweenRevisions(filePath, left, right);
+ }
+ }
+
+ protected void showChangesBetweenRevisions(@NotNull final FilePath path, @NotNull final T rev1, @Nullable final T rev2) {
+ new CollectChangesTask("Comparing revisions...") {
+
+ @NotNull
+ @Override
+ public List<Change> getChanges() throws VcsException {
+ return getChangesBetweenRevisions(path, rev1, rev2);
+ }
+
+ @NotNull
+ @Override
+ public String getDialogTitle() {
+ return getChangesBetweenRevisionsDialogTitle(path, rev1, rev2);
+ }
+ }.queue();
+ }
+
+ protected void showAffectedChanges(@NotNull final FilePath path, @NotNull final T rev) {
+ new CollectChangesTask("Collecting affected changes...") {
+
+ @NotNull
+ @Override
+ public List<Change> getChanges() throws VcsException {
+ return getAffectedChanges(path, rev);
+ }
+
+ @NotNull
+ @Override
+ public String getDialogTitle() {
+ return getAffectedChangesDialogTitle(path, rev);
+ }
+ }.queue();
+ }
+
+ // rev2 == null -> compare rev1 with local
+ // rev2 != null -> compare rev1 with rev2
+ @NotNull
+ protected abstract List<Change> getChangesBetweenRevisions(@NotNull final FilePath path, @NotNull final T rev1, @Nullable final T rev2)
+ throws VcsException;
+
+ @NotNull
+ protected abstract List<Change> getAffectedChanges(@NotNull final FilePath path, @NotNull final T rev) throws VcsException;
+
+ @NotNull
+ protected abstract String getPresentableName(@NotNull T revision);
+
+ protected void showChangesDialog(@NotNull String title, @NotNull List<Change> changes) {
+ DialogBuilder dialogBuilder = new DialogBuilder(myProject);
+
+ dialogBuilder.setTitle(title);
+ dialogBuilder.setActionDescriptors(new DialogBuilder.ActionDescriptor[]{new DialogBuilder.CloseDialogAction()});
+ final ChangesBrowser changesBrowser =
+ new ChangesBrowser(myProject, null, changes, null, false, true, null, ChangesBrowser.MyUseCase.COMMITTED_CHANGES, null);
+ changesBrowser.setChangesToDisplay(changes);
+ dialogBuilder.setCenterPanel(changesBrowser);
+ dialogBuilder.showNotModal();
+ }
+
+ protected void showError(@NotNull VcsException e, @NotNull String logMessage) {
+ LOG.info(logMessage, e);
+ VcsBalloonProblemNotifier.showOverVersionControlView(myProject, e.getMessage(), MessageType.ERROR);
+ }
+
+ @NotNull
+ protected String getChangesBetweenRevisionsDialogTitle(@NotNull final FilePath path, @NotNull final T rev1, @Nullable final T rev2) {
+ String rev1Title = getPresentableName(rev1);
+
+ return rev2 != null
+ ? String.format("Difference between %s and %s in %s", rev1Title, getPresentableName(rev2), path.getName())
+ : String.format("Difference between %s and local version in %s", rev1Title, path.getName());
+ }
+
+ @NotNull
+ protected String getAffectedChangesDialogTitle(@NotNull final FilePath path, @NotNull final T rev) {
+ return String.format("Initial commit %s in %s", getPresentableName(rev), path.getName());
+ }
+
+ protected abstract class CollectChangesTask extends Task.Backgroundable {
+
+ private List<Change> myChanges;
+
+ public CollectChangesTask(@NotNull String title) {
+ super(BaseDiffFromHistoryHandler.this.myProject, title);
+ }
+
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ try {
+ myChanges = getChanges();
+ }
+ catch (VcsException e) {
+ showError(e, "Error during task: " + getDialogTitle());
+ }
+ }
+
+ @NotNull
+ public abstract List<Change> getChanges() throws VcsException;
+
+ @NotNull
+ public abstract String getDialogTitle();
+
+ @Override
+ public void onSuccess() {
+ showChangesDialog(getDialogTitle(), ContainerUtil.notNullize(myChanges));
+ }
+ }
+}