diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 8de7b5992d80..98d16895c158 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -1516,4 +1516,8 @@ public class StringUtil { if (s2 == null) return -1; return s1.compareTo(s2); } + + public static String tail(final String s, final int idx) { + return idx >= s.length() ? "" : s.substring(idx, s.length()); + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java index 1aa93977480d..70a90cc7a7ca 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java @@ -36,7 +36,6 @@ import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.FilePathImpl; import com.intellij.openapi.vcs.ObjectsConvertor; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.ZipperUpdater; @@ -62,6 +61,7 @@ import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.tree.DefaultTreeModel; import java.awt.*; +import java.io.File; import java.io.IOException; import java.util.*; import java.util.List; @@ -703,9 +703,16 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { } private static class MyChangeNodeDecorator implements ChangeNodeDecorator { - public void decorate(Change change, SimpleColoredComponent component) { + public void decorate(Change change, SimpleColoredComponent component, boolean isShowFlatten) { if (change instanceof FilePatchInProgress.PatchChange) { final FilePatchInProgress.PatchChange patchChange = (FilePatchInProgress.PatchChange) change; + if (! isShowFlatten) { + // add change subpath + final TextFilePatch filePatch = patchChange.getPatchInProgress().getPatch(); + final String patchPath = filePatch.getAfterName() == null ? filePatch.getBeforeName() : filePatch.getAfterName(); + component.append(" "); + component.append("["+ patchPath + "]", SimpleTextAttributes.GRAY_ATTRIBUTES); + } final String text; if (FilePatchStatus.ADDED.equals(patchChange.getPatchInProgress().getStatus())) { text = "(Added)"; @@ -718,6 +725,19 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { component.append(text, SimpleTextAttributes.GRAY_ATTRIBUTES); } } + + public List> stressPartsOfFileName(final Change change, final String parentPath) { + if (change instanceof FilePatchInProgress.PatchChange) { + final FilePatchInProgress.PatchChange patchChange = (FilePatchInProgress.PatchChange) change; + final String basePath = patchChange.getPatchInProgress().getBase().getPath(); + final String basePathCorrected = basePath.trim().replace('/', File.separatorChar); + if (parentPath.startsWith(basePathCorrected)) { + return Arrays.asList(new Pair(basePathCorrected, Stress.BOLD), + new Pair(StringUtil.tail(parentPath, basePathCorrected.length()), Stress.PLAIN)); + } + } + return null; + } } public Collection getIncluded() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeNodeDecorator.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeNodeDecorator.java index 474dcd36db56..071d47914096 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeNodeDecorator.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangeNodeDecorator.java @@ -15,9 +15,38 @@ */ package com.intellij.openapi.vcs.changes.ui; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.changes.Change; import com.intellij.ui.SimpleColoredComponent; +import com.intellij.ui.SimpleTextAttributes; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.List; public interface ChangeNodeDecorator { - void decorate(final Change change, final SimpleColoredComponent component); + void decorate(final Change change, final SimpleColoredComponent component, boolean isShowFlatten); + @Nullable + List> stressPartsOfFileName(final Change change, final String parentPath); + + enum Stress { + BOLD(Font.BOLD), + ITALIC(Font.ITALIC), + BOLD_ITALIC(Font.BOLD | Font.ITALIC), + PLAIN(Font.PLAIN); + + private final int myFontStyle; + + private Stress(int fontStyle) { + myFontStyle = fontStyle; + } + + public int getFontStyle() { + return myFontStyle; + } + + public SimpleTextAttributes derive(final SimpleTextAttributes attributes) { + return attributes.derive(myFontStyle, attributes.getFgColor(), attributes.getBgColor(), attributes.getWaveColor()); + } + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java index 6ebf2419685a..e3f07ee08c4e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserChangeNode.java @@ -95,7 +95,7 @@ public class ChangesBrowserChangeNode extends ChangesBrowserNode impleme } if (myDecorator != null) { - myDecorator.decorate(change, renderer); + myDecorator.decorate(change, renderer, renderer.isShowFlatten()); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java index b1650802e7e5..369838c98818 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesTreeList.java @@ -21,6 +21,7 @@ import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.FileStatus; @@ -576,12 +577,26 @@ public abstract class ChangesTreeList extends JPanel { } } append(path.getName(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, fileStatus.getColor(), null)); + final boolean applyChangeDecorator = (value instanceof Change) && myChangeDecorator != null; final File parentFile = path.getIOFile().getParentFile(); if (parentFile != null) { - append(" (" + parentFile.getPath() + ")", SimpleTextAttributes.GRAYED_ATTRIBUTES); + final String parentPath = parentFile.getPath(); + List> parts = null; + if (applyChangeDecorator) { + parts = myChangeDecorator.stressPartsOfFileName((Change)value, parentPath); + } + if (parts == null) { + parts = Collections.singletonList(new Pair(parentPath, ChangeNodeDecorator.Stress.PLAIN)); + } + + append(" ("); + for (Pair part : parts) { + append(part.getFirst(), part.getSecond().derive(SimpleTextAttributes.GRAYED_ATTRIBUTES)); + } + append(")", SimpleTextAttributes.GRAYED_ATTRIBUTES); } - if ((value instanceof Change) && myChangeDecorator != null) { - myChangeDecorator.decorate((Change) value, this); + if (applyChangeDecorator) { + myChangeDecorator.decorate((Change) value, this, isShowFlatten()); } } }; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RemoteStatusChangeNodeDecorator.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RemoteStatusChangeNodeDecorator.java index 852c287c21c9..4f8d9313306c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RemoteStatusChangeNodeDecorator.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/RemoteStatusChangeNodeDecorator.java @@ -15,11 +15,15 @@ */ package com.intellij.openapi.vcs.changes.ui; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.RemoteRevisionsCache; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; +import org.jetbrains.annotations.Nullable; + +import java.util.List; public class RemoteStatusChangeNodeDecorator implements ChangeNodeDecorator { protected final RemoteRevisionsCache myRemoteRevisionsCache; @@ -31,7 +35,7 @@ public class RemoteStatusChangeNodeDecorator implements ChangeNodeDecorator { protected void reportState(final boolean state) { } - public void decorate(final Change change, final SimpleColoredComponent component) { + public void decorate(final Change change, final SimpleColoredComponent component, boolean isShowFlatten) { final boolean state = myRemoteRevisionsCache.isUpToDate(change); reportState(state); if (! state) { @@ -39,4 +43,9 @@ public class RemoteStatusChangeNodeDecorator implements ChangeNodeDecorator { component.append(VcsBundle.message("change.nodetitle.change.is.outdated"), SimpleTextAttributes.ERROR_ATTRIBUTES); } } + + @Nullable + public List> stressPartsOfFileName(Change change, String parentPath) { + return null; + } }