package ru.batrdmi.svnplugin.actions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.DiffManager;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.SimpleContent;
import com.intellij.openapi.diff.SimpleDiffRequest;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vcs.FilePath;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNPropertyValue;
import ru.batrdmi.svnplugin.SVNRevisionGraph;
import ru.batrdmi.svnplugin.logic.FileHistoryRetriever;
import ru.batrdmi.svnplugin.logic.Revision;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class ShowPropertiesDiffAction extends AnAction implements DumbAware {
private static final Logger log = Logger.getInstance("ru.batrdmi.svnplugin.actions.ShowPropertiesDiffAction");
public ShowPropertiesDiffAction() {
super("Compare properties with local", "Compare properties with local version",
IconLoader.getIcon("/icons/PropertiesDiff.png"));
}
@Override
public void update(@NotNull AnActionEvent e) {
List<Revision> selection = e.getData(SVNRevisionGraph.SELECTED_REVISIONS);
int selectionSize = (selection == null) ? 0 : selection.size();
Presentation p = e.getPresentation();
if (selectionSize == 1) {
p.setText("Compare properties with local");
p.setDescription("Compare properties with local version");
} else {
p.setText("Compare properties");
p.setDescription("Compare properties");
}
boolean enabled = (selectionSize == 1 && !selection.get(0).isDeleted())
|| (selectionSize == 2 && !selection.get(0).isDeleted() && !selection.get(1).isDeleted());
p.setEnabled(enabled);
if (ActionPlaces.isPopupPlace(e.getPlace())) {
p.setVisible(enabled);
}
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
final Project project = e.getData(PlatformDataKeys.PROJECT);
SvnVcs svn = SvnVcs.getInstance(project);
FilePath filePath = e.getData(SVNRevisionGraph.SRC_FILE);
if (filePath == null) {
return;
}
List<Revision> revisions = e.getData(SVNRevisionGraph.SELECTED_REVISIONS);
int selectionSize = (revisions == null) ? 0 : revisions.size();
final Revision[] revs = new Revision[2];
if (selectionSize == 2) {
revs[0] = revisions.get(0);
revs[1] = revisions.get(1);
} else if (selectionSize == 1) {
revs[0] = revisions.get(0);
revs[1] = e.getData(SVNRevisionGraph.CURRENT_REVISION);
} else {
return;
}
Arrays.sort(revs, new Revision.RevisionNumberComparator());
final FileHistoryRetriever historyRetriever = new FileHistoryRetriever(svn, filePath.getVirtualFile());
new Task.Modal(project, "Loading properties from repository", false) {
DiffRequest diffRequest;
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
indicator.setText("Loading properties for " + revs[0]);
SVNProperties p1 = historyRetriever.getFileProperties(revs[0]);
indicator.setText("Loading properties for " + revs[1]);
SVNProperties p2 = historyRetriever.getFileProperties(revs[1]);
diffRequest = createDiffRequest(project, revs[0], p1, revs[1], p2);
} catch (SVNException e) {
log.error("Error retrieving properties", e);
}
}
@Override
public void onSuccess() {
if (diffRequest == null) {
Messages.showErrorDialog(project, "Error retrieving properties from repository",
SVNRevisionGraphAction.ERROR_DIALOG_TITLE);
} else {
DiffManager.getInstance().getDiffTool().show(diffRequest);
}
}
}.queue();
}
private DiffRequest createDiffRequest(Project project, Revision r1, SVNProperties p1,
Revision r2, SVNProperties p2) {
SimpleDiffRequest request = new SimpleDiffRequest(project, "Subversion properties difference");
request.setContentTitles(r1.toString(), r2.toString());
request.setContents(new SimpleContent(propertiesToString(p1)),
new SimpleContent(propertiesToString(p2)));
return request;
}
@SuppressWarnings("unchecked")
private String propertiesToString(SVNProperties props) {
StringBuilder b = new StringBuilder();
Map<String, SVNPropertyValue> properties = new TreeMap<String, SVNPropertyValue>(props.asMap());
for (Map.Entry<String, SVNPropertyValue> e : properties.entrySet()) {
b.append(e.getKey()).append('=').append(e.getValue()).append('\n');
}
return b.toString();
}
}