mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diff: svn: implement diff with properties
This commit is contained in:
@@ -32,14 +32,16 @@
|
||||
</group>
|
||||
|
||||
|
||||
<action id="IntegrateChangeSetAction" class="org.jetbrains.idea.svn.actions.IntegrateChangeSetAction" popup="true" icon="SvnIcons.IntegrateToBranch">
|
||||
<action id="IntegrateChangeSetAction" class="org.jetbrains.idea.svn.actions.IntegrateChangeSetAction" popup="true"
|
||||
icon="SvnIcons.IntegrateToBranch">
|
||||
<add-to-group group-id="RepositoryChangesBrowserToolbar" anchor="last"/>
|
||||
</action>
|
||||
|
||||
<action id="PropertiesDiff" class="org.jetbrains.idea.svn.actions.ShowPropertiesDiffAction" popup="true" icon="SvnIcons.PropertiesDiff">
|
||||
<add-to-group group-id="RepositoryChangesBrowserToolbar" anchor="last"/>
|
||||
</action>
|
||||
<action id="EditCommitMessage" class="org.jetbrains.idea.svn.history.SvnEditCommitMessageAction" popup="true" icon="AllIcons.Actions.Edit"
|
||||
<action id="EditCommitMessage" class="org.jetbrains.idea.svn.history.SvnEditCommitMessageAction" popup="true"
|
||||
icon="AllIcons.Actions.Edit"
|
||||
text="Edit Revision Comment" description="Edit revision comment. Previous message is rewritten.">
|
||||
<add-to-group group-id="CommittedChangesToolbar" anchor="last"/>
|
||||
</action>
|
||||
@@ -60,7 +62,8 @@
|
||||
<separator/>
|
||||
<action id="Subversion.ShowProperties" class="org.jetbrains.idea.svn.actions.ShowPropertiesAction"/>
|
||||
<action id="Subversion.SetProperty" class="org.jetbrains.idea.svn.actions.SetPropertyAction"/>
|
||||
<action id="ShowPropertiesDiffVsLocal" class="org.jetbrains.idea.svn.actions.ShowPropertiesDiffWithLocalAction" icon="SvnIcons.PropertiesDiffWithLocal">
|
||||
<action id="ShowPropertiesDiffVsLocal" class="org.jetbrains.idea.svn.actions.ShowPropertiesDiffWithLocalAction"
|
||||
icon="SvnIcons.PropertiesDiffWithLocal">
|
||||
</action>
|
||||
<reference id="ChangesView.Revert"/>
|
||||
<action id="Subversion.Resolve" class="org.jetbrains.idea.svn.actions.ResolveAction"/>
|
||||
@@ -86,7 +89,8 @@
|
||||
<separator/>
|
||||
<add-to-group group-id="SubversionFilePopupGroup" anchor="last"/>
|
||||
</group>
|
||||
<action id="Subversion.MarkLocallyDeletedTreeResolved" class="org.jetbrains.idea.svn.actions.MarkLocallyDeletedTreeConflictResolvedAction">
|
||||
<action id="Subversion.MarkLocallyDeletedTreeResolved"
|
||||
class="org.jetbrains.idea.svn.actions.MarkLocallyDeletedTreeConflictResolvedAction">
|
||||
<add-to-group group-id="ChangesViewPopupMenu" anchor="after" relative-to-action="ChangesView.Diff"/>
|
||||
</action>
|
||||
<reference id="Subversion.MarkTreeResolved">
|
||||
@@ -131,16 +135,24 @@
|
||||
<projectService serviceInterface="org.jetbrains.idea.svn.branchConfig.SvnLoadedBranchesStorage"
|
||||
serviceImplementation="org.jetbrains.idea.svn.branchConfig.SvnLoadedBranchesStorage"/>
|
||||
<applicationService serviceInterface="org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager"
|
||||
serviceImplementation="org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager"/>
|
||||
serviceImplementation="org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager"/>
|
||||
<applicationService serviceInterface="org.jetbrains.idea.svn.dialogs.browserCache.SvnRepositoryCache"
|
||||
serviceImplementation="org.jetbrains.idea.svn.dialogs.browserCache.SvnRepositoryCache"/>
|
||||
serviceImplementation="org.jetbrains.idea.svn.dialogs.browserCache.SvnRepositoryCache"/>
|
||||
<applicationService serviceInterface="org.jetbrains.idea.svn.dialogs.browserCache.Loader"
|
||||
serviceImplementation="org.jetbrains.idea.svn.dialogs.browserCache.CacheLoader"/>
|
||||
serviceImplementation="org.jetbrains.idea.svn.dialogs.browserCache.CacheLoader"/>
|
||||
|
||||
<search.topHitProvider implementation="org.jetbrains.idea.svn.SvnOptionsTopHitProvider"/>
|
||||
<vcs name="svn" vcsClass="org.jetbrains.idea.svn.SvnVcs" displayName="Subversion" administrativeAreaName=".svn, _svn" crawlUpToCheckUnderVcs="true"/>
|
||||
<vcs name="svn" vcsClass="org.jetbrains.idea.svn.SvnVcs" displayName="Subversion" administrativeAreaName=".svn, _svn"
|
||||
crawlUpToCheckUnderVcs="true"/>
|
||||
<vcsPopupProvider implementation="org.jetbrains.idea.svn.actions.SvnQuickListContentProvider"/>
|
||||
|
||||
<statistics.usagesCollector implementation="org.jetbrains.idea.svn.statistics.SvnWorkingCopyFormatUsagesCollector"/>
|
||||
|
||||
<openapi.vcs.changes.actions.diff.ChangeDiffRequestProvider
|
||||
implementation="org.jetbrains.idea.svn.difftool.SvnChangeDiffRequestProvider"/>
|
||||
|
||||
<openapi.util.diff.api.DiffTool implementation="org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffTool"/>
|
||||
<applicationService serviceInterface="org.jetbrains.idea.svn.difftool.SvnDiffSettingsHolder"
|
||||
serviceImplementation="org.jetbrains.idea.svn.difftool.SvnDiffSettingsHolder"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -496,6 +496,7 @@ diff.options.title=Compare With Branch or Tag
|
||||
diff.options.no.url.error=Please select an URL to compare with
|
||||
diff.options.same.url.error=Please select different URLs to compare
|
||||
diff.options.no.patch.file.error=Please specify the path to save the patch file
|
||||
diff.cant.get.properties.changes=Can't show SVN properties
|
||||
repository.browser.browse.changes.action=_Browse Changes...
|
||||
repository.browser.browse.changes.description=View history of changes in the selected node
|
||||
repository.browser.compare.title=Compare of ''{0} and ''{1}''
|
||||
|
||||
@@ -33,7 +33,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.actions.AbstractShowPropertiesDiffAction;
|
||||
import org.jetbrains.idea.svn.api.NodeKind;
|
||||
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationManager;
|
||||
import org.jetbrains.idea.svn.history.SimplePropertyRevision;
|
||||
import org.jetbrains.idea.svn.info.Info;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
import org.jetbrains.idea.svn.status.Status;
|
||||
import org.jetbrains.idea.svn.status.StatusType;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
@@ -377,7 +379,7 @@ class SvnChangeProviderContext implements StatusReceiver {
|
||||
ContentRevision contentRevision = isBeforeRevision ? change.getBeforeRevision() : change.getAfterRevision();
|
||||
SVNRevision revision = isBeforeRevision ? SVNRevision.BASE : SVNRevision.WORKING;
|
||||
|
||||
return new SimpleContentRevision(getProperties(file, revision), path, getRevisionNumber(contentRevision));
|
||||
return new SimplePropertyRevision(getProperties(file, revision), path, getRevisionNumber(contentRevision));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -386,7 +388,7 @@ class SvnChangeProviderContext implements StatusReceiver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getProperties(@NotNull File file, @NotNull SVNRevision revision) throws SVNException {
|
||||
private List<PropertyData> getProperties(@NotNull File file, @NotNull SVNRevision revision) throws SVNException {
|
||||
return AbstractShowPropertiesDiffAction.getPropertyList(myVcs, file, revision);
|
||||
}
|
||||
|
||||
|
||||
+23
-21
@@ -16,9 +16,6 @@
|
||||
package org.jetbrains.idea.svn.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diff.DiffManager;
|
||||
import com.intellij.openapi.diff.SimpleContent;
|
||||
import com.intellij.openapi.diff.SimpleDiffRequest;
|
||||
import com.intellij.openapi.progress.PerformInBackgroundOption;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
@@ -27,6 +24,8 @@ import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.diff.DiffDialogHints;
|
||||
import com.intellij.openapi.util.diff.DiffManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
@@ -43,6 +42,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.api.Depth;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffRequest;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffRequest.PropertyContent;
|
||||
import org.jetbrains.idea.svn.history.SvnRepositoryContentRevision;
|
||||
import org.jetbrains.idea.svn.properties.PropertyConsumer;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
@@ -127,8 +128,8 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
|
||||
|
||||
private class CalculateAndShow extends Task.Backgroundable {
|
||||
private final Change myChange;
|
||||
private String myBeforeContent;
|
||||
private String myAfterContent;
|
||||
private List<PropertyData> myBeforeContent;
|
||||
private List<PropertyData> myAfterContent;
|
||||
private SVNRevision myBeforeRevisionValue;
|
||||
private SVNRevision myAfterRevision;
|
||||
private Exception myException;
|
||||
@@ -167,16 +168,17 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
|
||||
return;
|
||||
}
|
||||
if (myBeforeContent != null && myAfterContent != null && myBeforeRevisionValue != null && myAfterRevision != null) {
|
||||
final SimpleDiffRequest diffRequest = new SimpleDiffRequest(myProject, getDiffWindowTitle(myChange));
|
||||
SvnPropertiesDiffRequest diffRequest;
|
||||
if (compareRevisions(myBeforeRevisionValue, myAfterRevision) > 0) {
|
||||
// before ahead
|
||||
diffRequest.setContents(new SimpleContent(myAfterContent), new SimpleContent(myBeforeContent));
|
||||
diffRequest.setContentTitles(revisionToString(myAfterRevision), revisionToString(myBeforeRevisionValue));
|
||||
diffRequest = new SvnPropertiesDiffRequest(getDiffWindowTitle(myChange),
|
||||
new PropertyContent(myAfterContent), new PropertyContent(myBeforeContent),
|
||||
revisionToString(myAfterRevision), revisionToString(myBeforeRevisionValue));
|
||||
} else {
|
||||
diffRequest.setContents(new SimpleContent(myBeforeContent), new SimpleContent(myAfterContent));
|
||||
diffRequest.setContentTitles(revisionToString(myBeforeRevisionValue), revisionToString(myAfterRevision));
|
||||
diffRequest = new SvnPropertiesDiffRequest(getDiffWindowTitle(myChange),
|
||||
new PropertyContent(myBeforeContent), new PropertyContent(myAfterContent),
|
||||
revisionToString(myBeforeRevisionValue), revisionToString(myAfterRevision));
|
||||
}
|
||||
DiffManager.getInstance().getDiffTool().show(diffRequest);
|
||||
DiffManager.getInstance().showDiff(myProject, diffRequest, DiffDialogHints.DEFAULT);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -225,12 +227,12 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
|
||||
private final static String ourPropertiesDelimiter = "\n";
|
||||
|
||||
@NotNull
|
||||
private static String getPropertyList(@NotNull SvnVcs vcs,
|
||||
@Nullable final ContentRevision contentRevision,
|
||||
@Nullable final SVNRevision revision)
|
||||
private static List<PropertyData> getPropertyList(@NotNull SvnVcs vcs,
|
||||
@Nullable final ContentRevision contentRevision,
|
||||
@Nullable final SVNRevision revision)
|
||||
throws SVNException, VcsException {
|
||||
if (contentRevision == null) {
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
|
||||
SvnTarget target;
|
||||
@@ -246,13 +248,13 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getPropertyList(@NotNull SvnVcs vcs, @NotNull final SVNURL url, @Nullable final SVNRevision revision)
|
||||
public static List<PropertyData> getPropertyList(@NotNull SvnVcs vcs, @NotNull final SVNURL url, @Nullable final SVNRevision revision)
|
||||
throws VcsException {
|
||||
return getPropertyList(vcs, SvnTarget.fromURL(url, revision), revision);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getPropertyList(@NotNull SvnVcs vcs, @NotNull final File ioFile, @Nullable final SVNRevision revision)
|
||||
public static List<PropertyData> getPropertyList(@NotNull SvnVcs vcs, @NotNull final File ioFile, @Nullable final SVNRevision revision)
|
||||
throws SVNException {
|
||||
try {
|
||||
return getPropertyList(vcs, SvnTarget.fromFile(ioFile, revision), revision);
|
||||
@@ -263,14 +265,14 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getPropertyList(@NotNull SvnVcs vcs, @NotNull SvnTarget target, @Nullable SVNRevision revision)
|
||||
private static List<PropertyData> getPropertyList(@NotNull SvnVcs vcs, @NotNull SvnTarget target, @Nullable SVNRevision revision)
|
||||
throws VcsException {
|
||||
final List<PropertyData> lines = new ArrayList<PropertyData>();
|
||||
final PropertyConsumer propertyHandler = createHandler(revision, lines);
|
||||
|
||||
vcs.getFactory(target).createPropertyClient().list(target, revision, Depth.EMPTY, propertyHandler);
|
||||
|
||||
return toSortedStringPresentation(lines);
|
||||
return lines;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -305,7 +307,7 @@ public abstract class AbstractShowPropertiesDiffAction extends AnAction implemen
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String toSortedStringPresentation(@NotNull List<PropertyData> lines) {
|
||||
public static String toSortedStringPresentation(@NotNull List<PropertyData> lines) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
Collections.sort(lines, new Comparator<PropertyData>() {
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package org.jetbrains.idea.svn.difftool;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.UserDataHolder;
|
||||
import com.intellij.openapi.util.diff.chains.DiffRequestPresentableException;
|
||||
import com.intellij.openapi.util.diff.impl.DiffViewerWrapper;
|
||||
import com.intellij.openapi.util.diff.requests.DiffRequest;
|
||||
import com.intellij.openapi.util.diff.requests.ErrorDiffRequest;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestPresentable;
|
||||
import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnChangeProvider;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffRequest;
|
||||
import org.jetbrains.idea.svn.history.PropertyRevision;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SvnChangeDiffRequestProvider implements ChangeDiffRequestProvider {
|
||||
private static final Logger LOG = Logger.getInstance(SvnChangeDiffRequestProvider.class);
|
||||
|
||||
@Override
|
||||
public boolean canCreate(@NotNull Project project, @NotNull Change change) {
|
||||
return getSvnChangeLayer(change) != null; // TODO: do not show, if no properties are set in both revisions ?
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DiffRequest process(@NotNull ChangeDiffRequestPresentable presentable,
|
||||
@NotNull UserDataHolder context,
|
||||
@NotNull ProgressIndicator indicator) throws DiffRequestPresentableException, ProcessCanceledException {
|
||||
DiffRequestPresentableException e1 = null;
|
||||
DiffRequestPresentableException e2 = null;
|
||||
|
||||
DiffRequest propertyRequest;
|
||||
try {
|
||||
propertyRequest = createPropertyRequest(presentable.getChange(), indicator);
|
||||
}
|
||||
catch (DiffRequestPresentableException e) {
|
||||
e1 = e;
|
||||
propertyRequest = new ErrorDiffRequest(presentable, e);
|
||||
}
|
||||
|
||||
DiffRequest contentRequest;
|
||||
try {
|
||||
contentRequest = ChangeDiffRequestPresentable.createRequest(presentable.getProject(), presentable.getChange(), context, indicator);
|
||||
}
|
||||
catch (DiffRequestPresentableException e) {
|
||||
e2 = e;
|
||||
contentRequest = new ErrorDiffRequest(presentable, e);
|
||||
}
|
||||
|
||||
if (e1 != null && e2 != null) {
|
||||
LOG.info(e1);
|
||||
LOG.info(e2);
|
||||
throw new DiffRequestPresentableException(e1.getMessage() + "\n\n" + e2.getMessage());
|
||||
}
|
||||
|
||||
contentRequest.putUserData(DiffViewerWrapper.KEY, new SvnDiffViewerWrapper(propertyRequest));
|
||||
|
||||
return contentRequest;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SvnPropertiesDiffRequest createPropertyRequest(@NotNull Change change, @NotNull ProgressIndicator indicator)
|
||||
throws DiffRequestPresentableException {
|
||||
try {
|
||||
Change propertiesChange = getSvnChangeLayer(change);
|
||||
if (propertiesChange == null) throw new DiffRequestPresentableException(SvnBundle.getString("diff.cant.get.properties.changes"));
|
||||
|
||||
ContentRevision bRevRaw = propertiesChange.getBeforeRevision();
|
||||
ContentRevision aRevRaw = propertiesChange.getAfterRevision();
|
||||
|
||||
if (bRevRaw != null && !(bRevRaw instanceof PropertyRevision)) {
|
||||
LOG.warn("Before change is not PropertyRevision");
|
||||
throw new DiffRequestPresentableException(SvnBundle.getString("diff.cant.get.properties.changes"));
|
||||
}
|
||||
if (aRevRaw != null && !(aRevRaw instanceof PropertyRevision)) {
|
||||
LOG.warn("After change is not PropertyRevision");
|
||||
throw new DiffRequestPresentableException(SvnBundle.getString("diff.cant.get.properties.changes"));
|
||||
}
|
||||
|
||||
PropertyRevision bRev = (PropertyRevision)bRevRaw;
|
||||
PropertyRevision aRev = (PropertyRevision)aRevRaw;
|
||||
|
||||
indicator.checkCanceled();
|
||||
List<PropertyData> bContent = bRev != null ? bRev.getProperties() : null;
|
||||
|
||||
indicator.checkCanceled();
|
||||
List<PropertyData> aContent = aRev != null ? aRev.getProperties() : null;
|
||||
|
||||
if (aRev == null && bRev == null) throw new DiffRequestPresentableException(SvnBundle.getString("diff.cant.get.properties.changes"));
|
||||
|
||||
ContentRevision bRevMain = change.getBeforeRevision();
|
||||
ContentRevision aRevMain = change.getAfterRevision();
|
||||
String title1 = bRevMain != null ? StringUtil.nullize(bRevMain.getRevisionNumber().asString()) : null;
|
||||
String title2 = aRevMain != null ? StringUtil.nullize(aRevMain.getRevisionNumber().asString()) : null;
|
||||
|
||||
return new SvnPropertiesDiffRequest(bContent, aContent, title1, title2);
|
||||
}
|
||||
catch (VcsException e) {
|
||||
throw new DiffRequestPresentableException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Change getSvnChangeLayer(@NotNull Change change) {
|
||||
for (Map.Entry<String, Change> entry : change.getOtherLayers().entrySet()) {
|
||||
if (SvnChangeProvider.PROPERTY_LAYER.equals(entry.getKey())) {
|
||||
if (change.getOtherLayers().size() != 1) LOG.warn("Some of change layers ignored");
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.jetbrains.idea.svn.difftool;
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.diff.util.DiffUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@State(
|
||||
name = "SvnDiffSettings",
|
||||
storages = {@Storage(
|
||||
file = DiffUtil.DIFF_CONFIG)})
|
||||
public class SvnDiffSettingsHolder implements PersistentStateComponent<SvnDiffSettingsHolder.SvnDiffSettings> {
|
||||
public static class SvnDiffSettings {
|
||||
public static final Key<SvnDiffSettings> KEY = Key.create("SvnDiffSettings");
|
||||
|
||||
float SPITTER_PROPORTION = 0.9f;
|
||||
boolean HIDE_PROPERTIES = false;
|
||||
|
||||
public SvnDiffSettings() {
|
||||
}
|
||||
|
||||
public SvnDiffSettings(float SPITTER_PROPORTION, boolean HIDE_PROPERTIES) {
|
||||
this.SPITTER_PROPORTION = SPITTER_PROPORTION;
|
||||
this.HIDE_PROPERTIES = HIDE_PROPERTIES;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SvnDiffSettings copy() {
|
||||
return new SvnDiffSettings(SPITTER_PROPORTION, HIDE_PROPERTIES);
|
||||
}
|
||||
|
||||
public boolean isHideProperties() {
|
||||
return HIDE_PROPERTIES;
|
||||
}
|
||||
|
||||
public void setHideProperties(boolean value) {
|
||||
HIDE_PROPERTIES = value;
|
||||
}
|
||||
|
||||
public float getSplitterProportion() {
|
||||
return SPITTER_PROPORTION;
|
||||
}
|
||||
|
||||
public void setSplitterProportion(float value) {
|
||||
SPITTER_PROPORTION = value;
|
||||
}
|
||||
|
||||
//
|
||||
// Impl
|
||||
//
|
||||
|
||||
@NotNull
|
||||
public static SvnDiffSettings getSettings() {
|
||||
return getInstance().getState().copy();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SvnDiffSettings getSettingsDefaults() {
|
||||
return getInstance().getState();
|
||||
}
|
||||
}
|
||||
|
||||
private SvnDiffSettings myState = new SvnDiffSettings();
|
||||
|
||||
@NotNull
|
||||
public SvnDiffSettings getState() {
|
||||
return myState;
|
||||
}
|
||||
|
||||
public void loadState(SvnDiffSettings state) {
|
||||
myState = state;
|
||||
}
|
||||
|
||||
public static SvnDiffSettingsHolder getInstance() {
|
||||
return ServiceManager.getService(SvnDiffSettingsHolder.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
package org.jetbrains.idea.svn.difftool;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.DiffContext;
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.DiffViewer;
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.ToolbarComponents;
|
||||
import com.intellij.openapi.util.diff.contents.DiffContent;
|
||||
import com.intellij.openapi.util.diff.contents.EmptyContent;
|
||||
import com.intellij.openapi.util.diff.impl.ModifiablePanel;
|
||||
import com.intellij.openapi.util.diff.requests.DiffRequest;
|
||||
import com.intellij.openapi.util.diff.requests.ErrorDiffRequest;
|
||||
import com.intellij.openapi.util.diff.tools.ErrorDiffTool;
|
||||
import com.intellij.openapi.util.diff.util.DiffUtil;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import com.intellij.ui.OnePixelSplitter;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.difftool.SvnDiffSettingsHolder.SvnDiffSettings;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffRequest;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffViewer;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
import org.jetbrains.idea.svn.properties.PropertyValue;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SvnDiffViewer implements DiffViewer {
|
||||
private static final Logger LOG = Logger.getInstance(SvnDiffViewer.class);
|
||||
|
||||
public static final Key<MyPropertyContext> PROPERTY_CONTEXT_KEY = Key.create("MyPropertyContext");
|
||||
public static final Key<Boolean> FOCUSED_VIEWER_KEY = Key.create("SvnFocusedViewer");
|
||||
|
||||
@Nullable private final Project myProject;
|
||||
|
||||
@NotNull private final DiffContext myContext;
|
||||
@NotNull private final DiffRequest myPropertyRequest;
|
||||
|
||||
@NotNull private final SvnDiffSettings mySettings;
|
||||
|
||||
@NotNull private final JPanel myPanel;
|
||||
@NotNull private final Splitter mySplitter;
|
||||
@NotNull private final ModifiablePanel myNotificationPanel;
|
||||
|
||||
@NotNull private final DiffViewer myContentViewer;
|
||||
@NotNull private final DiffViewer myPropertiesViewer;
|
||||
|
||||
@NotNull private final FocusListener myContentFocusListener = new MyFocusListener(false);
|
||||
@NotNull private final FocusListener myPropertiesFocusListener = new MyFocusListener(true);
|
||||
|
||||
private boolean myPropertiesViewerFocused; // False - content viewer, True - properties
|
||||
private boolean myDumbContentViewer;
|
||||
|
||||
public SvnDiffViewer(@NotNull DiffContext context, @NotNull DiffRequest propertyRequest, @NotNull DiffViewer wrappingViewer) {
|
||||
myProject = context.getProject();
|
||||
myContext = context;
|
||||
myPropertyRequest = propertyRequest;
|
||||
myContentViewer = wrappingViewer;
|
||||
|
||||
myPropertyRequest.onAssigned(true);
|
||||
|
||||
mySettings = initSettings(context);
|
||||
|
||||
mySplitter = new OnePixelSplitter(true);
|
||||
mySplitter.setProportion(mySettings.getSplitterProportion());
|
||||
mySplitter.setFirstComponent(myContentViewer.getComponent());
|
||||
|
||||
myNotificationPanel = new ModifiablePanel();
|
||||
|
||||
MyPropertyContext propertyContext = initPropertyContext(context);
|
||||
myPropertiesViewer = createPropertiesViewer(propertyRequest, propertyContext);
|
||||
|
||||
myPanel = new JPanel(new BorderLayout());
|
||||
myPanel.add(mySplitter, BorderLayout.CENTER);
|
||||
myPanel.add(myNotificationPanel, BorderLayout.SOUTH);
|
||||
|
||||
updatePropertiesPanel();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DiffViewer createPropertiesViewer(@NotNull DiffRequest propertyRequest, @NotNull MyPropertyContext propertyContext) {
|
||||
if (propertyRequest instanceof SvnPropertiesDiffRequest) {
|
||||
return new SvnPropertiesDiffViewer(propertyContext, ((SvnPropertiesDiffRequest)propertyRequest));
|
||||
}
|
||||
else {
|
||||
return ErrorDiffTool.INSTANCE.createComponent(propertyContext, propertyRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ToolbarComponents init() {
|
||||
installListeners();
|
||||
|
||||
processContextHints();
|
||||
|
||||
ToolbarComponents properties = myPropertiesViewer.init();
|
||||
ToolbarComponents components = new ToolbarComponents();
|
||||
components.toolbarActions = createToolbar(properties.toolbarActions);
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
destroyListeners();
|
||||
|
||||
updateContextHints();
|
||||
|
||||
Disposer.dispose(myPropertiesViewer);
|
||||
|
||||
myPropertyRequest.onAssigned(false);
|
||||
}
|
||||
|
||||
private void processContextHints() {
|
||||
if (myContext.getUserData(FOCUSED_VIEWER_KEY) == Boolean.TRUE) myPropertiesViewerFocused = true;
|
||||
myDumbContentViewer = myContentViewer.getPreferredFocusedComponent() == null;
|
||||
}
|
||||
|
||||
private void updateContextHints() {
|
||||
if (!myDumbContentViewer) myContext.putUserData(FOCUSED_VIEWER_KEY, myPropertiesViewerFocused);
|
||||
mySettings.setSplitterProportion(mySplitter.getProportion());
|
||||
}
|
||||
|
||||
//
|
||||
// Diff
|
||||
//
|
||||
|
||||
@NotNull
|
||||
private JComponent createNotification() {
|
||||
if (myPropertyRequest instanceof ErrorDiffRequest) {
|
||||
return createNotification(((ErrorDiffRequest)myPropertyRequest).getErrorMessage());
|
||||
}
|
||||
|
||||
DiffContent[] contents = ((SvnPropertiesDiffRequest)myPropertyRequest).getContents();
|
||||
|
||||
Map<String, PropertyValue> before = getProperties(contents[0]);
|
||||
Map<String, PropertyValue> after = getProperties(contents[1]);
|
||||
|
||||
if (before.isEmpty() && after.isEmpty()) return createNotification("No SVN properties set");
|
||||
|
||||
if (!before.keySet().equals(after.keySet())) {
|
||||
return createNotification("SVN Properties changed");
|
||||
}
|
||||
|
||||
for (String key : before.keySet()) {
|
||||
if (!Comparing.equal(before.get(key), after.get(key))) return createNotification("SVN Properties changed");
|
||||
}
|
||||
|
||||
return createNotification("SVN Properties unchanged");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, PropertyValue> getProperties(@NotNull DiffContent content) {
|
||||
if (content instanceof EmptyContent) return Collections.emptyMap();
|
||||
|
||||
List<PropertyData> properties = ((SvnPropertiesDiffRequest.PropertyContent)content).getProperties();
|
||||
|
||||
Map<String, PropertyValue> map = new HashMap<String, PropertyValue>();
|
||||
|
||||
for (PropertyData data : properties) {
|
||||
if (map.containsKey(data.getName())) LOG.warn("Duplicated property: " + data.getName());
|
||||
map.put(data.getName(), data.getValue());
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JPanel createNotification(@NotNull String text) {
|
||||
return new EditorNotificationPanel().text(text);
|
||||
}
|
||||
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
|
||||
private void updatePropertiesPanel() {
|
||||
if (!mySettings.isHideProperties()) {
|
||||
mySplitter.setSecondComponent(myPropertiesViewer.getComponent());
|
||||
myNotificationPanel.setContent(null);
|
||||
}
|
||||
else {
|
||||
mySplitter.setSecondComponent(null);
|
||||
myNotificationPanel.setContent(createNotification());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<AnAction> createToolbar(@Nullable List<AnAction> propertiesActions) {
|
||||
List<AnAction> result = new ArrayList<AnAction>();
|
||||
|
||||
if (propertiesActions != null) result.addAll(propertiesActions);
|
||||
|
||||
result.add(new ToggleHidePropertiesAction());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SvnDiffSettings initSettings(@NotNull DiffContext context) {
|
||||
SvnDiffSettings settings = context.getUserData(SvnDiffSettings.KEY);
|
||||
if (settings == null) {
|
||||
settings = SvnDiffSettings.getSettingsDefaults(); // TODO: do not use defaults ?
|
||||
context.putUserData(SvnDiffSettings.KEY, settings);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private MyPropertyContext initPropertyContext(@NotNull DiffContext context) {
|
||||
MyPropertyContext propertyContext = context.getUserData(PROPERTY_CONTEXT_KEY);
|
||||
if (propertyContext == null) {
|
||||
propertyContext = new MyPropertyContext();
|
||||
context.putUserData(PROPERTY_CONTEXT_KEY, propertyContext);
|
||||
}
|
||||
return propertyContext;
|
||||
}
|
||||
|
||||
private void installListeners() {
|
||||
myContentViewer.getComponent().addFocusListener(myContentFocusListener);
|
||||
myPropertiesViewer.getComponent().addFocusListener(myPropertiesFocusListener);
|
||||
}
|
||||
|
||||
private void destroyListeners() {
|
||||
myContentViewer.getComponent().removeFocusListener(myContentFocusListener);
|
||||
myPropertiesViewer.getComponent().removeFocusListener(myPropertiesFocusListener);
|
||||
}
|
||||
|
||||
//
|
||||
// Getters
|
||||
//
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
if (myPropertiesViewerFocused) {
|
||||
JComponent component = myPropertiesViewer.getPreferredFocusedComponent();
|
||||
if (component != null) return component;
|
||||
return myContentViewer.getPreferredFocusedComponent();
|
||||
}
|
||||
else {
|
||||
JComponent component = myContentViewer.getPreferredFocusedComponent();
|
||||
if (component != null) return component;
|
||||
return myPropertiesViewer.getPreferredFocusedComponent();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Actions
|
||||
//
|
||||
|
||||
private class ToggleHidePropertiesAction extends ToggleAction implements DumbAware { // TODO: shortcut
|
||||
public ToggleHidePropertiesAction() {
|
||||
super("Show SVN properties", null, AllIcons.Actions.Preview);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return !mySettings.isHideProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
mySettings.setHideProperties(!state);
|
||||
updatePropertiesPanel();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
private class MyPropertyContext extends UserDataHolderBase implements DiffContext {
|
||||
private final DiffWindow myWindow = new DiffWindow() {
|
||||
@Override
|
||||
public boolean isFocused() {
|
||||
return DiffUtil.isFocusedComponent(getProject(), myPropertiesViewer.getComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
DiffUtil.requestFocus(getProject(), myPropertiesViewer.getPreferredFocusedComponent());
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return myContext.getProject();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DiffWindow getDiffWindow() {
|
||||
return myWindow;
|
||||
}
|
||||
}
|
||||
|
||||
private class MyFocusListener extends FocusAdapter {
|
||||
private final boolean myValue;
|
||||
|
||||
public MyFocusListener(boolean value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
myPropertiesViewerFocused = myValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.jetbrains.idea.svn.difftool;
|
||||
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.DiffContext;
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.DiffViewer;
|
||||
import com.intellij.openapi.util.diff.impl.DiffViewerWrapper;
|
||||
import com.intellij.openapi.util.diff.requests.DiffRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SvnDiffViewerWrapper implements DiffViewerWrapper {
|
||||
@NotNull private final DiffRequest myPropertyRequest;
|
||||
|
||||
public SvnDiffViewerWrapper(@NotNull DiffRequest propertyRequest) {
|
||||
myPropertyRequest = propertyRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiffViewer createComponent(@NotNull DiffContext context, @NotNull DiffRequest request, @NotNull DiffViewer wrappedViewer) {
|
||||
return new SvnDiffViewer(context, myPropertyRequest, wrappedViewer);
|
||||
}
|
||||
}
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
package org.jetbrains.idea.svn.difftool.properties;
|
||||
|
||||
import com.intellij.openapi.util.diff.util.Side;
|
||||
import com.intellij.openapi.util.diff.util.TextDiffType;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.ui.ColumnInfo;
|
||||
import com.intellij.util.ui.ListTableModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffViewer.PropertyDiffRecord;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffViewer.PropertyDiffRecord.ColoredChunk;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
// FIXME: colors on selection
|
||||
public class PropertiesTableModel extends ListTableModel<PropertyDiffRecord> {
|
||||
@NotNull private final MultiLineTableRenderer myRenderer = new MultiLineTableRenderer();
|
||||
|
||||
public static int NAME_COL = 0;
|
||||
|
||||
public PropertiesTableModel(boolean showLeft, boolean showRight, @Nullable String title1, @Nullable String title2) {
|
||||
if (showLeft && showRight) {
|
||||
setColumnInfos(new ColumnInfo[]{
|
||||
new NameColumnInfo(myRenderer),
|
||||
new ValueColumnInfo(Side.LEFT, title1, myRenderer),
|
||||
new ValueColumnInfo(Side.RIGHT, title2, myRenderer)});
|
||||
}
|
||||
else if (showLeft) {
|
||||
setColumnInfos(new ColumnInfo[]{
|
||||
new NameColumnInfo(myRenderer),
|
||||
new ValueColumnInfo(Side.LEFT, title1, myRenderer)});
|
||||
}
|
||||
else if (showRight) {
|
||||
setColumnInfos(new ColumnInfo[]{
|
||||
new NameColumnInfo(myRenderer),
|
||||
new ValueColumnInfo(Side.RIGHT, title2, myRenderer)});
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RowSorter.SortKey getDefaultSortKey() {
|
||||
return new RowSorter.SortKey(NAME_COL, SortOrder.DESCENDING);
|
||||
}
|
||||
|
||||
private static TextDiffType getDiffType(PropertyDiffRecord record) {
|
||||
if (record.isChanged()) {
|
||||
if (record.getBefore() == null) {
|
||||
return TextDiffType.INSERTED;
|
||||
}
|
||||
else if (record.getAfter() == null) {
|
||||
return TextDiffType.DELETED;
|
||||
}
|
||||
else {
|
||||
return TextDiffType.MODIFIED;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getValueTitle(@NotNull Side side, @Nullable String title) {
|
||||
if (title != null) return "Value in " + title;
|
||||
return side.isLeft() ? "Value Before" : "Value After";
|
||||
}
|
||||
|
||||
private static class NameColumnInfo extends ColumnInfo<PropertyDiffRecord, String> {
|
||||
@NotNull private final MultiLineTableRenderer myRenderer;
|
||||
|
||||
public NameColumnInfo(@NotNull MultiLineTableRenderer renderer) {
|
||||
super("SVN Property Name");
|
||||
myRenderer = renderer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TableCellRenderer getRenderer(final PropertyDiffRecord record) {
|
||||
TextDiffType type = getDiffType(record);
|
||||
final Color bgColor = type != null ? type.getIgnoredColor(null) : null;
|
||||
myRenderer.setCustomizer(new MultiLineTableRenderer.Customizer() {
|
||||
@Override
|
||||
public void customize(JTable table, JLabel label, boolean isSelected, Object value) {
|
||||
label.setText(record.getName());
|
||||
if (bgColor != null) {
|
||||
label.setForeground(table.getForeground());
|
||||
label.setBackground(bgColor);
|
||||
}
|
||||
}
|
||||
});
|
||||
return myRenderer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String valueOf(PropertyDiffRecord data) {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getPreferredStringValue() {
|
||||
return "svn:some_property_name";
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getMaxStringValue() {
|
||||
return "svn:some_really_big_cool_property_name";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Comparator<PropertyDiffRecord> getComparator() {
|
||||
return new Comparator<PropertyDiffRecord>() {
|
||||
@Override
|
||||
public int compare(PropertyDiffRecord o1, PropertyDiffRecord o2) {
|
||||
return StringUtil.naturalCompare(o1.getName(), o2.getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static class ValueColumnInfo extends ColumnInfo<PropertyDiffRecord, String> {
|
||||
@NotNull private final MultiLineTableRenderer myRenderer;
|
||||
@NotNull private final Side mySide;
|
||||
|
||||
public ValueColumnInfo(@NotNull Side side, @Nullable String title, @NotNull MultiLineTableRenderer renderer) {
|
||||
super(getValueTitle(side, title));
|
||||
mySide = side;
|
||||
myRenderer = renderer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<ColoredChunk> getChunks(@NotNull PropertyDiffRecord record) {
|
||||
return mySide.isLeft() ? record.getBefore() : record.getAfter();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TableCellRenderer getRenderer(final PropertyDiffRecord record) {
|
||||
TextDiffType type = getDiffType(record);
|
||||
final Color bgColor = type != null ? type.getIgnoredColor(null) : null;
|
||||
myRenderer.setCustomizer(new MultiLineTableRenderer.Customizer() {
|
||||
@Override
|
||||
public void customize(JTable table, JLabel label, boolean isSelected, Object value) {
|
||||
List<ColoredChunk> chunks = getChunks(record);
|
||||
if (chunks == null) {
|
||||
label.setText("");
|
||||
label.setBackground(JBColor.border()); // TODO: better color
|
||||
}
|
||||
else {
|
||||
StringBuilder text = new StringBuilder();
|
||||
text.append("<html><body style=\"white-space:nowrap\">");
|
||||
for (ColoredChunk chunk : chunks) {
|
||||
text.append("<span");
|
||||
if (chunk.getType() != null) {
|
||||
text.append(" style=\"");
|
||||
text.append("background-color:#").append(Integer.toString(chunk.getType().getColor(null).getRGB() & 0xFFFFFF, 16));
|
||||
text.append("\"");
|
||||
}
|
||||
text.append('>');
|
||||
text.append(StringUtil.escapeXml(chunk.getText()).replaceAll("\n", "<br>"));
|
||||
text.append("</span>");
|
||||
}
|
||||
text.append("</body></html>");
|
||||
label.setText(text.toString());
|
||||
if (bgColor != null) {
|
||||
label.setForeground(table.getForeground());
|
||||
label.setBackground(bgColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return myRenderer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String valueOf(@NotNull PropertyDiffRecord record) {
|
||||
List<ColoredChunk> chunks = getChunks(record);
|
||||
if (chunks == null) return null;
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (ColoredChunk chunk : chunks) {
|
||||
builder.append(chunk.getText());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MultiLineTableRenderer extends DefaultTableCellRenderer {
|
||||
@NotNull private final List<List<Integer>> rowColHeight = new ArrayList<List<Integer>>();
|
||||
@Nullable private Customizer myCustomizer;
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
|
||||
int row, int column) {
|
||||
setBackground(null);
|
||||
final JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
|
||||
if (myCustomizer != null) myCustomizer.customize(table, label, isSelected, value);
|
||||
|
||||
adjustRowHeight(table, row, column);
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the new preferred height for a given row, and sets the height on the table.
|
||||
*/
|
||||
private void adjustRowHeight(JTable table, int row, int column) {
|
||||
//The trick to get this to work properly is to set the width of the column to the
|
||||
//textarea. The reason for this is that getPreferredSize(), without a width tries
|
||||
//to place all the text in one line. By setting the size with the with of the column,
|
||||
//getPreferredSize() returnes the proper height which the row should have in
|
||||
//order to make room for the text.
|
||||
int prefH = getPreferredSize().height;
|
||||
while (rowColHeight.size() <= row) {
|
||||
rowColHeight.add(new ArrayList<Integer>(column));
|
||||
}
|
||||
List<Integer> colHeights = rowColHeight.get(row);
|
||||
while (colHeights.size() <= column) {
|
||||
colHeights.add(0);
|
||||
}
|
||||
colHeights.set(column, prefH);
|
||||
int maxH = prefH;
|
||||
for (Integer colHeight : colHeights) {
|
||||
if (colHeight > maxH) {
|
||||
maxH = colHeight;
|
||||
}
|
||||
}
|
||||
if (table.getRowHeight(row) != maxH) {
|
||||
table.setRowHeight(row, maxH);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCustomizer(@Nullable Customizer customizer) {
|
||||
myCustomizer = customizer;
|
||||
}
|
||||
|
||||
public interface Customizer {
|
||||
void customize(JTable table, JLabel textArea, boolean isSelected, Object value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package org.jetbrains.idea.svn.difftool.properties;
|
||||
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.util.diff.contents.DiffContent;
|
||||
import com.intellij.openapi.util.diff.contents.EmptyContent;
|
||||
import com.intellij.openapi.util.diff.requests.ContentDiffRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SvnPropertiesDiffRequest extends UserDataHolderBase implements ContentDiffRequest {
|
||||
@NotNull private final DiffContent[] myContents;
|
||||
@NotNull private final String[] myContentTitles;
|
||||
@NotNull private final String myWindowTitle;
|
||||
|
||||
public SvnPropertiesDiffRequest(@NotNull String windowTitle,
|
||||
@NotNull DiffContent content1,
|
||||
@NotNull DiffContent content2,
|
||||
@NotNull String title1,
|
||||
@NotNull String title2) {
|
||||
myWindowTitle = windowTitle;
|
||||
myContents = new DiffContent[]{content1, content2};
|
||||
myContentTitles = new String[]{title1, title2};
|
||||
|
||||
assert content1 instanceof PropertyContent || content1 instanceof EmptyContent;
|
||||
assert content2 instanceof PropertyContent || content2 instanceof EmptyContent;
|
||||
assert content1 instanceof PropertyContent || content2 instanceof PropertyContent;
|
||||
}
|
||||
|
||||
public SvnPropertiesDiffRequest(@Nullable List<PropertyData> before, @Nullable List<PropertyData> after,
|
||||
@Nullable String title1, @Nullable String title2) {
|
||||
assert before != null || after != null;
|
||||
|
||||
myContents = new DiffContent[]{createContent(before), createContent(after)};
|
||||
myWindowTitle = "Svn Properties Diff";
|
||||
myContentTitles = new String[]{title1, title2};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DiffContent createContent(@Nullable List<PropertyData> content) {
|
||||
if (content == null) return new EmptyContent();
|
||||
|
||||
return new PropertyContent(content);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getWindowTitle() {
|
||||
return myWindowTitle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getContentTitles() {
|
||||
return myContentTitles;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DiffContent[] getContents() {
|
||||
return myContents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAssigned(boolean isAssigned) {
|
||||
}
|
||||
|
||||
public static class PropertyContent implements DiffContent {
|
||||
@NotNull private final List<PropertyData> myProperties;
|
||||
|
||||
public PropertyContent(@NotNull List<PropertyData> properties) {
|
||||
myProperties = properties;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PropertyData> getProperties() {
|
||||
return myProperties;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FileType getContentType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public OpenFileDescriptor getOpenFileDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAssigned(boolean isAssigned) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.idea.svn.difftool.properties;
|
||||
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool;
|
||||
import com.intellij.openapi.util.diff.requests.DiffRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SvnPropertiesDiffTool implements FrameDiffTool {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Svn Properties Viewer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canShow(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
return request instanceof SvnPropertiesDiffRequest;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DiffViewer createComponent(@NotNull DiffContext context, @NotNull DiffRequest request) {
|
||||
return new SvnPropertiesDiffViewer(context, (SvnPropertiesDiffRequest)request);
|
||||
}
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
package org.jetbrains.idea.svn.difftool.properties;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.DiffContext;
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.DiffViewer;
|
||||
import com.intellij.openapi.util.diff.api.FrameDiffTool.ToolbarComponents;
|
||||
import com.intellij.openapi.util.diff.comparison.iterables.DiffIterable;
|
||||
import com.intellij.openapi.util.diff.comparison.iterables.DiffIterableUtil;
|
||||
import com.intellij.openapi.util.diff.contents.DiffContent;
|
||||
import com.intellij.openapi.util.diff.fragments.DiffFragment;
|
||||
import com.intellij.openapi.util.diff.util.DiffUtil;
|
||||
import com.intellij.openapi.util.diff.util.TextDiffType;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.table.TableView;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffViewer.PropertyDiffRecord.ColoredChunk;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
import org.jetbrains.idea.svn.properties.PropertyValue;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class SvnPropertiesDiffViewer implements DiffViewer {
|
||||
private static final Logger LOG = Logger.getInstance(SvnPropertiesDiffViewer.class);
|
||||
|
||||
@Nullable private final Project myProject;
|
||||
|
||||
@NotNull private final DiffContext myContext;
|
||||
@NotNull private final SvnPropertiesDiffRequest myRequest;
|
||||
|
||||
@Nullable private final List<PropertyData> myProperties1;
|
||||
@Nullable private final List<PropertyData> myProperties2;
|
||||
|
||||
@NotNull private final JPanel myPanel;
|
||||
@NotNull private final TableView<PropertyDiffRecord> myTable;
|
||||
|
||||
public SvnPropertiesDiffViewer(@NotNull DiffContext context, @NotNull SvnPropertiesDiffRequest request) {
|
||||
myProject = context.getProject();
|
||||
|
||||
myContext = context;
|
||||
myRequest = request;
|
||||
|
||||
String[] titles = request.getContentTitles();
|
||||
|
||||
DiffContent[] contents = request.getContents();
|
||||
myProperties1 = getProperties(contents[0]);
|
||||
myProperties2 = getProperties(contents[1]);
|
||||
assert myProperties1 != null || myProperties2 != null;
|
||||
|
||||
PropertiesTableModel model = new PropertiesTableModel(myProperties1 != null, myProperties2 != null, titles[0], titles[1]);
|
||||
myTable = new TableView<PropertyDiffRecord>(model);
|
||||
myTable.getTableHeader().setReorderingAllowed(false);
|
||||
|
||||
myPanel = new JPanel(new BorderLayout());
|
||||
myPanel.add(ScrollPaneFactory.createScrollPane(myTable), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ToolbarComponents init() {
|
||||
rediff();
|
||||
|
||||
ToolbarComponents components = new ToolbarComponents();
|
||||
components.toolbarActions = createToolbar();
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
//
|
||||
// Diff
|
||||
//
|
||||
|
||||
public void rediff() {
|
||||
assert myProperties1 != null || myProperties2 != null;
|
||||
|
||||
Map<String, PropertyValue> before = new HashMap<String, PropertyValue>();
|
||||
Map<String, PropertyValue> after = new HashMap<String, PropertyValue>();
|
||||
if (myProperties1 != null) {
|
||||
for (PropertyData data : myProperties1) {
|
||||
before.put(data.getName(), data.getValue());
|
||||
}
|
||||
}
|
||||
if (myProperties2 != null) {
|
||||
for (PropertyData data : myProperties2) {
|
||||
after.put(data.getName(), data.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
List<PropertyDiffRecord> records = new ArrayList<PropertyDiffRecord>();
|
||||
for (String name : ContainerUtil.union(before.keySet(), after.keySet())) {
|
||||
records.add(createRecord(name, before.get(name), after.get(name)));
|
||||
}
|
||||
ContainerUtil.sort(records, new Comparator<PropertyDiffRecord>() {
|
||||
@Override
|
||||
public int compare(PropertyDiffRecord o1, PropertyDiffRecord o2) {
|
||||
return StringUtil.naturalCompare(o1.getName(), o2.getName());
|
||||
}
|
||||
});
|
||||
((PropertiesTableModel)myTable.getModel()).setItems(records);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PropertyDiffRecord createRecord(@NotNull String name, @Nullable PropertyValue value1, @Nullable PropertyValue value2) {
|
||||
assert value1 != null || value2 != null;
|
||||
if (value1 == null) {
|
||||
return new PropertyDiffRecord(name, null, Collections.singletonList(new ColoredChunk(value2.toString(), null)), true);
|
||||
}
|
||||
if (value2 == null) {
|
||||
return new PropertyDiffRecord(name, Collections.singletonList(new ColoredChunk(value1.toString(), null)), null, true);
|
||||
}
|
||||
|
||||
String text1 = value1.toString();
|
||||
String text2 = value2.toString();
|
||||
|
||||
List<DiffFragment> fragments = DiffUtil.compareWords(text1, text2, 1000);
|
||||
|
||||
List<ColoredChunk> chunks1 = new ArrayList<ColoredChunk>();
|
||||
List<ColoredChunk> chunks2 = new ArrayList<ColoredChunk>();
|
||||
|
||||
DiffIterable iterable = DiffIterableUtil.createFragments(fragments, text1.length(), text2.length());
|
||||
for (Pair<DiffIterableUtil.Range, Boolean> pair : DiffIterableUtil.iterateAll(iterable)) {
|
||||
DiffIterableUtil.Range range = pair.first;
|
||||
Boolean equals = pair.second;
|
||||
|
||||
if (range.start1 == range.end1) {
|
||||
chunks2.add(new ColoredChunk(text2.substring(range.start2, range.end2), equals ? null : TextDiffType.INSERTED));
|
||||
}
|
||||
else if (range.start2 == range.end2) {
|
||||
chunks1.add(new ColoredChunk(text1.substring(range.start1, range.end1), equals ? null : TextDiffType.DELETED));
|
||||
}
|
||||
else {
|
||||
chunks1.add(new ColoredChunk(text1.substring(range.start1, range.end1), equals ? null : TextDiffType.MODIFIED));
|
||||
chunks2.add(new ColoredChunk(text2.substring(range.start2, range.end2), equals ? null : TextDiffType.MODIFIED));
|
||||
}
|
||||
}
|
||||
|
||||
return new PropertyDiffRecord(name, chunks1, chunks2, !fragments.isEmpty());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<PropertyData> getProperties(@NotNull DiffContent content) {
|
||||
if (content instanceof SvnPropertiesDiffRequest.PropertyContent) {
|
||||
return ((SvnPropertiesDiffRequest.PropertyContent)content).getProperties();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<AnAction> createToolbar() {
|
||||
List<AnAction> result = new ArrayList<AnAction>();
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Getters
|
||||
//
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myTable;
|
||||
}
|
||||
|
||||
public static class PropertyDiffRecord {
|
||||
@NotNull private final String myName;
|
||||
@Nullable private final List<ColoredChunk> myBefore;
|
||||
@Nullable private final List<ColoredChunk> myAfter;
|
||||
private final boolean myIsChanged;
|
||||
|
||||
public PropertyDiffRecord(@NotNull String name,
|
||||
@Nullable List<ColoredChunk> before,
|
||||
@Nullable List<ColoredChunk> after,
|
||||
boolean isChanged) {
|
||||
myName = name;
|
||||
myBefore = before;
|
||||
myAfter = after;
|
||||
myIsChanged = isChanged;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<ColoredChunk> getBefore() {
|
||||
return myBefore;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<ColoredChunk> getAfter() {
|
||||
return myAfter;
|
||||
}
|
||||
|
||||
public boolean isChanged() {
|
||||
return myIsChanged;
|
||||
}
|
||||
|
||||
public static class ColoredChunk {
|
||||
@NotNull private final String myText;
|
||||
@Nullable private final TextDiffType myType;
|
||||
|
||||
public ColoredChunk(@NotNull String text, @Nullable TextDiffType type) {
|
||||
myText = text;
|
||||
myType = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return myText;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TextDiffType getType() {
|
||||
return myType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PropertyRevision extends ContentRevision {
|
||||
@Nullable
|
||||
List<PropertyData> getProperties() throws VcsException;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.jetbrains.idea.svn.history;
|
||||
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.actions.AbstractShowPropertiesDiffAction;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SimplePropertyRevision implements ContentRevision, PropertyRevision {
|
||||
private final List<PropertyData> myProperty;
|
||||
private final FilePath myNewFilePath;
|
||||
private final String myRevision;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<PropertyData> getProperties() throws VcsException {
|
||||
return myProperty;
|
||||
}
|
||||
|
||||
public SimplePropertyRevision(final List<PropertyData> property, final FilePath newFilePath, final String revision) {
|
||||
myProperty = property;
|
||||
myNewFilePath = newFilePath;
|
||||
myRevision = revision;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getContent() {
|
||||
return AbstractShowPropertiesDiffAction.toSortedStringPresentation(myProperty);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FilePath getFile() {
|
||||
return myNewFilePath;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VcsRevisionNumber getRevisionNumber() {
|
||||
return new VcsRevisionNumber() {
|
||||
public String asString() {
|
||||
return myRevision;
|
||||
}
|
||||
|
||||
public int compareTo(final VcsRevisionNumber o) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+20
-12
@@ -26,24 +26,28 @@ import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.MarkerVcsContentRevision;
|
||||
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnBundle;
|
||||
import org.jetbrains.idea.svn.SvnRevisionNumber;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.actions.AbstractShowPropertiesDiffAction;
|
||||
import org.jetbrains.idea.svn.properties.PropertyData;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 2/22/12
|
||||
* Time: 10:28 AM
|
||||
*/
|
||||
public class SvnLazyPropertyContentRevision implements ContentRevision, MarkerVcsContentRevision {
|
||||
public class SvnLazyPropertyContentRevision implements ContentRevision, MarkerVcsContentRevision, PropertyRevision {
|
||||
private final FilePath myPath;
|
||||
private final VcsRevisionNumber myNumber;
|
||||
private final Project myProject;
|
||||
private final SVNURL myUrl;
|
||||
private String myContent;
|
||||
private List<PropertyData> myContent;
|
||||
|
||||
public SvnLazyPropertyContentRevision(FilePath path, VcsRevisionNumber number, Project project, SVNURL url) {
|
||||
myPath = path;
|
||||
@@ -52,17 +56,24 @@ public class SvnLazyPropertyContentRevision implements ContentRevision, MarkerVc
|
||||
myUrl = url;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getContent() throws VcsException {
|
||||
public List<PropertyData> getProperties() throws VcsException {
|
||||
if (myContent == null) {
|
||||
myContent = loadContent();
|
||||
}
|
||||
return myContent;
|
||||
}
|
||||
|
||||
private String loadContent() {
|
||||
@Override
|
||||
public String getContent() throws VcsException {
|
||||
return AbstractShowPropertiesDiffAction.toSortedStringPresentation(getProperties());
|
||||
}
|
||||
|
||||
private List<PropertyData> loadContent() throws VcsException {
|
||||
final SvnVcs vcs = SvnVcs.getInstance(myProject);
|
||||
final Ref<String> ref = new Ref<String>();
|
||||
final Ref<List<PropertyData>> ref = new Ref<List<PropertyData>>();
|
||||
final Ref<VcsException> exceptionRef = new Ref<VcsException>();
|
||||
final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -70,24 +81,21 @@ public class SvnLazyPropertyContentRevision implements ContentRevision, MarkerVc
|
||||
ref.set(AbstractShowPropertiesDiffAction.getPropertyList(vcs, myUrl, ((SvnRevisionNumber)myNumber).getRevision()));
|
||||
}
|
||||
catch (VcsException e) {
|
||||
// unknown node kind (node deleted)
|
||||
/*if (e.getErrorMessage().getErrorCode().getCode() == 145000) {
|
||||
return "";
|
||||
}*/
|
||||
ref.set("Can not get properties: " + e.getMessage());
|
||||
exceptionRef.set(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
final boolean completed = ProgressManager.getInstance()
|
||||
.runProcessWithProgressSynchronously(runnable, SvnBundle.message("progress.title.loading.file.properties"), true, myProject);
|
||||
if (! completed) {
|
||||
return "Properties load for revision " + getRevisionNumber().asString() + " was canceled.";
|
||||
if (!completed) {
|
||||
throw new VcsException("Properties load for revision " + getRevisionNumber().asString() + " was canceled.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
runnable.run();
|
||||
}
|
||||
if (!exceptionRef.isNull()) throw exceptionRef.get();
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,4 +52,21 @@ public class PropertyValue {
|
||||
public String toString() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
PropertyValue value = (PropertyValue)o;
|
||||
|
||||
if (!myValue.equals(value.myValue)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myValue.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,6 @@
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="http-client" level="project" />
|
||||
<orderEntry type="module" module-name="diff-impl" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
Reference in New Issue
Block a user