diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java new file mode 100644 index 000000000000..06e25a95fe57 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java @@ -0,0 +1,103 @@ +/* + * 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.diff.actions; + +import com.intellij.CommonBundle; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.ComboBoxAction; +import com.intellij.openapi.diff.DiffBundle; +import com.intellij.openapi.diff.ex.DiffPanelEx; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.diff.impl.processing.HighlightMode; +import com.intellij.openapi.project.DumbAware; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.util.Map; + +public class HighlightModeAction extends ComboBoxAction implements DumbAware { + private final Map myActions = new HashMap(); + private static final HighlightMode[] ourActionOrder = + new HighlightMode[]{HighlightMode.BY_WORD, HighlightMode.BY_LINE, HighlightMode.NO_HIGHLIGHTING}; + + public HighlightModeAction() { + myActions.put(HighlightMode.BY_WORD, + new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.word"), HighlightMode.BY_WORD)); + myActions.put(HighlightMode.BY_LINE, + new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.line"), HighlightMode.BY_LINE)); + myActions.put(HighlightMode.NO_HIGHLIGHTING, + new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.no.highlighting"), + HighlightMode.NO_HIGHLIGHTING)); + } + + @Override + public JComponent createCustomComponent(final Presentation presentation) { + JPanel panel = new JPanel(new BorderLayout()); + final JLabel label = new JLabel(CommonBundle.message("diff.acton.highlight.mode.action.name")); + label.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4)); + panel.add(label, BorderLayout.WEST); + panel.add(super.createCustomComponent(presentation), BorderLayout.CENTER); + return panel; + } + + @NotNull + protected DefaultActionGroup createPopupActionGroup(JComponent button) { + DefaultActionGroup actionGroup = new DefaultActionGroup(); + for (HighlightMode comparisonPolicy : ourActionOrder) { + actionGroup.add(myActions.get(comparisonPolicy)); + } + return actionGroup; + } + + public void update(AnActionEvent e) { + super.update(e); + Presentation presentation = e.getPresentation(); + DiffPanelEx diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext()); + if (diffPanel != null && diffPanel.getComponent().isDisplayable()) { + AnAction action = myActions.get(diffPanel.getHighlightMode()); + Presentation templatePresentation = action.getTemplatePresentation(); + presentation.setIcon(templatePresentation.getIcon()); + presentation.setText(templatePresentation.getText()); + presentation.setEnabled(true); + } + else { + presentation.setIcon(null); + presentation.setText(DiffBundle.message("diff.acton.highlight.mode.not.available.action.name")); + presentation.setEnabled(false); + } + } + + private static class SetHighlightModeAction extends AnAction implements DumbAware { + private final HighlightMode myHighlightMode; + + public SetHighlightModeAction(String text, HighlightMode mode) { + super(text); + myHighlightMode = mode; + } + + public void actionPerformed(AnActionEvent e) { + final DiffPanelImpl diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext()); + if (diffPanel != null) { + diffPanel.setHighlightMode(myHighlightMode); + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java index c3bf682ab9f7..933d017be2ef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java @@ -27,6 +27,7 @@ package com.intellij.openapi.diff.ex; import com.intellij.openapi.Disposable; import com.intellij.openapi.diff.DiffPanel; import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.processing.HighlightMode; import com.intellij.openapi.editor.Editor; import org.jetbrains.annotations.Nullable; @@ -45,4 +46,8 @@ public interface DiffPanelEx extends DiffPanel, Disposable { void setAutoScrollEnabled(boolean enabled); boolean isAutoScrollEnabled(); + + void setHighlightMode(HighlightMode highlightMode); + + HighlightMode getHighlightMode(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java index 37b9438522b2..913d5e7cc8f9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java @@ -34,6 +34,7 @@ import com.intellij.openapi.diff.impl.fragments.Fragment; import com.intellij.openapi.diff.impl.fragments.FragmentList; import com.intellij.openapi.diff.impl.highlighting.DiffPanelState; import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.processing.HighlightMode; import com.intellij.openapi.diff.impl.processing.HorizontalDiffSplitter; import com.intellij.openapi.diff.impl.settings.DiffMergeEditorSetting; import com.intellij.openapi.diff.impl.settings.DiffMergeSettings; @@ -483,6 +484,15 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid setComparisonPolicy(comparisonPolicy, true); } + public void setHighlightMode(HighlightMode highlightMode) { + myData.setHighlightMode(highlightMode); + rediff(); + } + + public HighlightMode getHighlightMode() { + return myData.getHighlightMode(); + } + public Rediffers getDiffUpdater() { return myDiffUpdater; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java index 5446f66e50c6..d90005d70678 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java @@ -24,6 +24,7 @@ import com.intellij.openapi.diff.impl.fragments.FragmentList; import com.intellij.openapi.diff.impl.fragments.FragmentListImpl; import com.intellij.openapi.diff.impl.fragments.LineFragment; import com.intellij.openapi.diff.impl.processing.DiffPolicy; +import com.intellij.openapi.diff.impl.processing.HighlightMode; import com.intellij.openapi.diff.impl.processing.TextCompareProcessor; import com.intellij.openapi.diff.impl.splitter.LineBlocks; import com.intellij.openapi.project.Project; @@ -37,6 +38,7 @@ import java.util.Iterator; public abstract class SimpleDiffPanelState implements Disposable { protected ComparisonPolicy myComparisonPolicy = ComparisonPolicy.DEFAULT; protected DiffPolicy myDiffPolicy; + protected HighlightMode myHighlightMode; protected final EditorPlaceHolder myAppender1; protected final EditorPlaceHolder myAppender2; protected FragmentList myFragmentList = FragmentList.EMPTY; @@ -47,6 +49,7 @@ public abstract class SimpleDiffPanelState implements Disposable { myAppender2 = createEditorWrapper(project, changeListener, FragmentSide.SIDE2); myProject = project; myDiffPolicy = DiffPolicy.LINES_WO_FORMATTING; + myHighlightMode = HighlightMode.BY_WORD; Disposer.register(parentDisposable, this); } @@ -72,6 +75,14 @@ public abstract class SimpleDiffPanelState implements Disposable { return myComparisonPolicy; } + public HighlightMode getHighlightMode() { + return myHighlightMode; + } + + public void setHighlightMode(HighlightMode highlightMode) { + myHighlightMode = highlightMode; + } + public void dispose() { } @@ -105,7 +116,12 @@ public abstract class SimpleDiffPanelState implements Disposable { return LineBlocks.EMPTY; } - return addMarkup(new TextCompareProcessor(myComparisonPolicy, myDiffPolicy).process(myAppender1.getText(), myAppender2.getText())); + if (myHighlightMode == HighlightMode.NO_HIGHLIGHTING) { + return LineBlocks.fromLineFragments(new ArrayList()); + } + + return addMarkup(new TextCompareProcessor(myComparisonPolicy, myDiffPolicy, myHighlightMode == HighlightMode.BY_WORD) + .process(myAppender1.getText(), myAppender2.getText())); } public Project getProject() { return myProject; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java index 1555656c3865..01534b487ff5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java @@ -32,28 +32,38 @@ public class TextCompareProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Processor"); private final DiffPolicy myDiffPolicy; @NotNull private final ComparisonPolicy myComparisonPolicy; + private final boolean mySearchForSubFragments; - public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, final DiffPolicy diffPolicy) { + public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, + final DiffPolicy diffPolicy, + boolean searchForSubFragments) { myComparisonPolicy = comparisonPolicy; myDiffPolicy = diffPolicy; + mySearchForSubFragments = searchForSubFragments; } - public TextCompareProcessor(ComparisonPolicy comparisonPolicy) { + public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, final DiffPolicy diffPolicy) { + this(comparisonPolicy, diffPolicy, true); + } + + public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy) { this(comparisonPolicy, DiffPolicy.LINES_WO_FORMATTING); } public ArrayList process(String text1, String text2) throws FilesTooBigForDiffException { DiffFragment[] woFormattingBlocks = myDiffPolicy.buildFragments(text1, text2); - DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy). - correctAndNormalize(woFormattingBlocks); + DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy).correctAndNormalize(woFormattingBlocks); ArrayList lineBlocks = new DiffFragmentsProcessor().process(step1lineFragments); - for (LineFragment lineBlock : lineBlocks) { - if (lineBlock.isOneSide() || lineBlock.isEqual()) continue; - String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1); - String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2); - ArrayList subFragments = findSubFragments(subText1, subText2); - lineBlock.setChildren(new ArrayList(subFragments)); - lineBlock.adjustTypeFromChildrenTypes(); + + if (mySearchForSubFragments) { + for (LineFragment lineBlock : lineBlocks) { + if (lineBlock.isOneSide() || lineBlock.isEqual()) continue; + String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1); + String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2); + ArrayList subFragments = findSubFragments(subText1, subText2); + lineBlock.setChildren(new ArrayList(subFragments)); + lineBlock.adjustTypeFromChildrenTypes(); + } } return lineBlocks; } diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties index a07d1631bad5..e027bc32a12d 100644 --- a/platform/platform-resources-en/src/messages/CommonBundle.properties +++ b/platform/platform-resources-en/src/messages/CommonBundle.properties @@ -175,4 +175,5 @@ This may lead to incorrect behaviour. Proxy should be set in Settings | HTTP Pro This JVM property is old and its usage is not recommended by Oracle.\n\ \n(Note: It could have been assigned by some code dynamically.) label.proxy.exceptions.text=Example\: *.domain.com, 192.168.* -checkbox.automatic.proxy.configuration.url=Automatic proxy configuration URL\: \ No newline at end of file +checkbox.automatic.proxy.configuration.url=Automatic proxy configuration URL\: +diff.acton.highlight.mode.action.name=Highlighting Mode \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/DiffBundle.properties b/platform/platform-resources-en/src/messages/DiffBundle.properties index cb6a0d72819b..b0515df7f6f2 100644 --- a/platform/platform-resources-en/src/messages/DiffBundle.properties +++ b/platform/platform-resources-en/src/messages/DiffBundle.properties @@ -83,3 +83,7 @@ diff.content.selected.value=Selected Value diff.clipboard.vs.value.dialog.title=Clipboard vs Selected Value diff.can.not.show.unknown=Can not show diff for unknown file type +diff.acton.highlight.mode.action.by.word=By Word +diff.acton.highlight.mode.action.by.line=By Line +diff.acton.highlight.mode.action.no.highlighting=No Highlighting +diff.acton.highlight.mode.not.available.action.name= diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index c2e5c4aafaac..ab70a8603df4 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -550,6 +550,8 @@ + + diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/HighlightMode.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/HighlightMode.java new file mode 100644 index 000000000000..441aca3517eb --- /dev/null +++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/HighlightMode.java @@ -0,0 +1,20 @@ +/* + * 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.diff.impl.processing; + +public enum HighlightMode { + BY_WORD, BY_LINE, NO_HIGHLIGHTING +}