Fixed bug 447565: Easy way to skip diff capping once when comparing a big document

Signed-off-by: Markus Keller <markus_keller@ch.ibm.com>
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
index ec80e01..de96fc6 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -42,13 +42,14 @@
 import org.eclipse.compare.internal.BufferedCanvas;
 import org.eclipse.compare.internal.ChangeCompareFilterPropertyAction;
 import org.eclipse.compare.internal.ChangePropertyAction;
+import org.eclipse.compare.internal.CompareContentViewerSwitchingPane;
 import org.eclipse.compare.internal.CompareEditor;
 import org.eclipse.compare.internal.CompareEditorContributor;
 import org.eclipse.compare.internal.CompareEditorSelectionProvider;
+import org.eclipse.compare.internal.CompareFilterDescriptor;
 import org.eclipse.compare.internal.CompareHandlerService;
 import org.eclipse.compare.internal.CompareMessages;
 import org.eclipse.compare.internal.ComparePreferencePage;
-import org.eclipse.compare.internal.CompareFilterDescriptor;
 import org.eclipse.compare.internal.CompareUIPlugin;
 import org.eclipse.compare.internal.DocumentManager;
 import org.eclipse.compare.internal.ICompareContextIds;
@@ -3993,6 +3994,11 @@
 			}
 		} else if (key.equals(ICompareUIConstants.PREF_NAVIGATION_END_ACTION)) {
 			updateControls();
+		} else if (key.equals(CompareContentViewerSwitchingPane.DISABLE_CAPPING_TEMPORARILY)) {
+			if (Boolean.TRUE.equals(event.getNewValue())) {
+				getCompareConfiguration().setProperty(CompareContentViewerSwitchingPane.DISABLE_CAPPING_TEMPORARILY, null);
+				handleCompareInputChange();
+			}
 		} else {
 			super.handlePropertyChangeEvent(event);
 			
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java
index 09fe5cf..b50f30d 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareContentViewerSwitchingPane.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2011 IBM Corporation and others.
+ * Copyright (c) 2009, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -14,13 +14,8 @@
 import java.util.Collections;
 import java.util.List;
 
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.CompareEditorInput;
-import org.eclipse.compare.CompareViewerSwitchingPane;
-import org.eclipse.compare.Splitter;
-import org.eclipse.compare.structuremergeviewer.ICompareInput;
-import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.osgi.util.NLS;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.events.DisposeEvent;
@@ -39,17 +34,30 @@
 import org.eclipse.swt.layout.RowLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Link;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.Viewer;
+
 import org.eclipse.ui.PlatformUI;
 
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.CompareViewerSwitchingPane;
+import org.eclipse.compare.Splitter;
+import org.eclipse.compare.internal.core.ComparePlugin;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+
 public class CompareContentViewerSwitchingPane extends
 		CompareViewerSwitchingPane {
 
 	private static final String OPTIMIZED_INFO_IMAGE_NAME = "obj16/message_info.gif"; //$NON-NLS-1$
 	public static final String OPTIMIZED_ALGORITHM_USED = "OPTIMIZED_ALGORITHM_USED"; //$NON-NLS-1$
+	public static final String DISABLE_CAPPING_TEMPORARILY = "DISABLE_CAPPING_TEMPORARILY"; //$NON-NLS-1$
 
 	private CompareEditorInput fCompareEditorInput;
 
@@ -57,6 +65,7 @@
 
 	private ToolBar toolBar;
 	private CLabel clOptimized;
+	private Link recomputeLink;
 
 	private boolean menuShowing;
 
@@ -106,6 +115,8 @@
 
 		RowLayout layout = new RowLayout();
 		layout.marginTop = 0;
+		layout.center = true;
+		layout.wrap = false;
 		composite.setLayout(layout);
 
 		CLabel cl = new CLabel(composite, SWT.NONE);
@@ -130,10 +141,7 @@
 		});
 
 		clOptimized = new CLabel(composite, SWT.NONE);
-		clOptimized
-				.setText(CompareMessages.CompareContentViewerSwitchingPane_optimized);
-		clOptimized
-				.setToolTipText(CompareMessages.CompareContentViewerSwitchingPane_optimizedTooltip);
+		clOptimized.setToolTipText(CompareMessages.CompareContentViewerSwitchingPane_optimizedTooltip);
 		clOptimized.setImage(CompareUIPlugin.getImageDescriptor(
 				OPTIMIZED_INFO_IMAGE_NAME).createImage());
 		clOptimized.setVisible(false); // hide by default
@@ -146,9 +154,34 @@
 			}
 		});
 
+		recomputeLink = new Link(composite, SWT.NONE);
+		recomputeLink.setText(CompareMessages.CompareContentViewerSwitchingPane_optimizedLinkLabel);
+		recomputeLink.setToolTipText(CompareMessages.CompareContentViewerSwitchingPane_optimizedTooltip);
+		recomputeLink.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				/*
+				 * Disable capping temporarily, refresh, restore global state.
+				 * The global state is bad, but fixing that would require lots of changes and new APIs.
+				 */
+				IPreferenceStore preferenceStore = CompareUIPlugin.getDefault().getPreferenceStore();
+				boolean wasDisabled = preferenceStore.getBoolean(ComparePreferencePage.CAPPING_DISABLED);
+				ComparePlugin.getDefault().setCappingDisabled(true);
+				preferenceStore.setValue(ComparePreferencePage.CAPPING_DISABLED, true);
+				try {
+					getCompareConfiguration().setProperty(DISABLE_CAPPING_TEMPORARILY, Boolean.TRUE);
+				} finally {
+					if (!wasDisabled) {
+						ComparePlugin.getDefault().setCappingDisabled(false);
+						preferenceStore.setValue(ComparePreferencePage.CAPPING_DISABLED, false);
+					}
+				}
+			}
+		});
+		recomputeLink.setVisible(false);
+
 		return composite;
 	}
-	
+
 	protected boolean inputChanged(Object input) {
 		return getInput() != input
 				|| fCompareEditorInput.getContentViewerDescriptor() != fSelectedViewerDescriptor;
@@ -164,7 +197,9 @@
 		toolBar.setVisible(vd != null && vd.length > 1);
 		CompareConfiguration cc = getCompareConfiguration();
 		Boolean isOptimized = (Boolean) cc.getProperty(OPTIMIZED_ALGORITHM_USED);
-		clOptimized.setVisible(isOptimized != null && isOptimized.booleanValue());
+		boolean optimizedVisible = isOptimized != null && isOptimized.booleanValue();
+		clOptimized.setVisible(optimizedVisible);
+		recomputeLink.setVisible(optimizedVisible);
 	}
 
 	private void showMenu() {
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.java
index 3d44786..c011a0f 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -121,7 +121,7 @@
 	public static String CompareContentViewerSwitchingPane_defaultViewer;
 	public static String CompareContentViewerSwitchingPane_switchButtonTooltip;
 	public static String CompareContentViewerSwitchingPane_discoveredLabel;
-	public static String CompareContentViewerSwitchingPane_optimized;
+	public static String CompareContentViewerSwitchingPane_optimizedLinkLabel;
 	public static String CompareContentViewerSwitchingPane_optimizedTooltip;
 	public static String CompareStructureViewerSwitchingPane_defaultViewer;
 	public static String CompareStructureViewerSwitchingPane_switchButtonTooltip;
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.properties b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.properties
index d5b995a..b4cc292 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.properties
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/CompareMessages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2013 IBM Corporation and others.
+# Copyright (c) 2000, 2015 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -134,8 +134,8 @@
 CompareContentViewerSwitchingPane_defaultViewer=Default Compare
 CompareContentViewerSwitchingPane_switchButtonTooltip=Switch Compare Viewer
 CompareContentViewerSwitchingPane_discoveredLabel={0} Compare
-CompareContentViewerSwitchingPane_optimized=Differences shown might not be optimal
-CompareContentViewerSwitchingPane_optimizedTooltip=To avoid long computation time a faster comparison algorithm has been used. As a result, the differences highlighted in the viewer may be larger than necessary.
+CompareContentViewerSwitchingPane_optimizedLinkLabel=Differences shown might not be optimal. <A>Recompute with slower algorithm</A>.
+CompareContentViewerSwitchingPane_optimizedTooltip=To avoid long computation time, a faster comparison algorithm has been used. As a result, some differences highlighted in the viewer may be larger than necessary.
 CompareStructureViewerSwitchingPane_defaultViewer=Default Structure Compare
 CompareStructureViewerSwitchingPane_switchButtonTooltip=Switch Structure Compare Viewer
 CompareStructureViewerSwitchingPane_discoveredLabel={0} Structure Compare
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
index 2a58149..b43129f 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/ComparePreferencePage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -16,6 +16,19 @@
 import java.util.Iterator;
 import java.util.Map;
 
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IEncodedStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
+import org.eclipse.compare.internal.core.ComparePlugin;
+import org.eclipse.compare.structuremergeviewer.DiffNode;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.DisposeEvent;
 import org.eclipse.swt.events.DisposeListener;
@@ -34,28 +47,12 @@
 import org.eclipse.swt.widgets.TabFolder;
 import org.eclipse.swt.widgets.TabItem;
 import org.eclipse.swt.widgets.Text;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.jface.preference.RadioGroupFieldEditor;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.dialogs.PreferenceLinkArea;
 import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
 
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.IEncodedStreamContentAccessor;
-import org.eclipse.compare.ITypedElement;
-import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
-import org.eclipse.compare.internal.core.ComparePlugin;
-import org.eclipse.compare.structuremergeviewer.DiffNode;
-import org.eclipse.compare.structuremergeviewer.Differencer;
-
 
 public class ComparePreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
 	
@@ -133,6 +130,8 @@
 		new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ICompareUIConstants.PREF_NAVIGATION_END_ACTION_LOCAL),
 	};
 	private RadioGroupFieldEditor editor;
+	private TabItem fTextCompareTab;
+	private Button fDisableCappingCheckBox;
 	
 	
 	public static void initDefaults(IPreferenceStore store) {
@@ -260,6 +259,7 @@
 		item.setText(Utilities.getString("ComparePreferencePage.textCompareTab.label"));	//$NON-NLS-1$
 		//item.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_CFILE));
 		item.setControl(createTextComparePage(folder));
+		fTextCompareTab = item;
 		
 		initializeFields();
 		Dialog.applyDialogFont(folder);
@@ -354,7 +354,7 @@
 		addCheckBox(composite, "ComparePreferencePage.useSingleLine.label", USE_SINGLE_LINE, 0);	//$NON-NLS-1$
 		addCheckBox(composite, "ComparePreferencePage.highlightTokenChanges.label", HIGHLIGHT_TOKEN_CHANGES, 0);	//$NON-NLS-1$
 		//addCheckBox(composite, "ComparePreferencePage.useResolveUI.label", USE_RESOLVE_UI, 0);	//$NON-NLS-1$
-		addCheckBox(composite, "ComparePreferencePage.disableCapping.label", CAPPING_DISABLED, 0);	//$NON-NLS-1$
+		fDisableCappingCheckBox = addCheckBox(composite, "ComparePreferencePage.disableCapping.label", CAPPING_DISABLED, 0);	//$NON-NLS-1$
 		
 		Composite radioGroup = new Composite(composite, SWT.NULL);
 		radioGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
@@ -486,4 +486,11 @@
 		}
 		return buffer.toString();
 	}
+
+	public void applyData(Object data) {
+		if (ComparePreferencePage.CAPPING_DISABLED.equals(data)) {
+			fTextCompareTab.getParent().setSelection(fTextCompareTab);
+			fDisableCappingCheckBox.setFocus();
+		}
+	}
 }