Bug 502841 - TreeViewer::expandAll() causes cursor to flicker

This reverts the revert commit 01c431b4466b0ac32c6c8bdf70aed078d8ec12b4.

Busy cursor is shown while expansion of the tree.

Introduced new expand methods that allow disabling redraw while
expanding the tree. The busy indicator will be shown until the tree has
been redrawn.

Change-Id: I70f815e9ca6821ae81c5e3426f865f46c7de9ce7
Signed-off-by: Karsten Thoms <karsten.thoms@itemis.de>
diff --git a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF
index 97efe4b..67211eb 100644
--- a/bundles/org.eclipse.jface/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.jface/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jface;singleton:=true
-Bundle-Version: 3.13.100.qualifier
+Bundle-Version: 3.14.0.qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.jface/pom.xml b/bundles/org.eclipse.jface/pom.xml
index 6091f90..d4f2a9e 100644
--- a/bundles/org.eclipse.jface/pom.xml
+++ b/bundles/org.eclipse.jface/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.jface</groupId>
   <artifactId>org.eclipse.jface</artifactId>
-  <version>3.13.100-SNAPSHOT</version>
+  <version>3.14.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <properties>
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/AbstractTreeViewer.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/AbstractTreeViewer.java
index 3259563..633d250 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/AbstractTreeViewer.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/AbstractTreeViewer.java
@@ -789,35 +789,32 @@
 				}
 			}
 
-			BusyIndicator.showWhile(widget.getDisplay(), () -> {
-				// fix for PR 1FW89L7:
-				// don't complain and remove all "dummies" ...
-				if (items != null) {
-					for (Item item : items) {
-						if (item.getData() != null) {
-							disassociate(item);
-							Assert.isTrue(item.getData() == null,
-									"Second or later child is non -null");//$NON-NLS-1$
+			// fix for PR 1FW89L7:
+			// don't complain and remove all "dummies" ...
+			if (items != null) {
+				for (Item item : items) {
+					if (item.getData() != null) {
+						disassociate(item);
+						Assert.isTrue(item.getData() == null, "Second or later child is non -null");//$NON-NLS-1$
 
-						}
-						item.dispose();
 					}
+					item.dispose();
 				}
-				Object d = widget.getData();
-				if (d != null) {
-					Object parentElement = d;
-					Object[] children;
-					if (isTreePathContentProvider() && widget instanceof Item) {
-						TreePath path = getTreePathFromItem((Item) widget);
-						children = getSortedChildren(path);
-					} else {
-						children = getSortedChildren(parentElement);
-					}
-					for (Object element : children) {
-						createTreeItem(widget, element, -1);
-					}
+			}
+			Object d = widget.getData();
+			if (d != null) {
+				Object parentElement = d;
+				Object[] children;
+				if (isTreePathContentProvider() && widget instanceof Item) {
+					TreePath path = getTreePathFromItem((Item) widget);
+					children = getSortedChildren(path);
+				} else {
+					children = getSortedChildren(parentElement);
 				}
-			});
+				for (Object element : children) {
+					createTreeItem(widget, element, -1);
+				}
+			}
 		} finally {
 			setBusy(oldBusy);
 		}
@@ -1034,7 +1031,20 @@
 	 * method is equivalent to <code>expandToLevel(ALL_LEVELS)</code>.
 	 */
 	public void expandAll() {
-		expandToLevel(ALL_LEVELS);
+		expandToLevel(ALL_LEVELS, false);
+	}
+
+	/**
+	 * Expands all nodes of the viewer's tree, starting with the root. This method
+	 * is equivalent to <code>expandToLevel(ALL_LEVELS)</code>.
+	 *
+	 * @param disableRedraw
+	 *            <code>true</code> when drawing operations should be disabled
+	 *            during expansion.
+	 * @since 3.14
+	 */
+	public void expandAll(boolean disableRedraw) {
+		expandToLevel(ALL_LEVELS, disableRedraw);
 	}
 
 	/**
@@ -1045,7 +1055,24 @@
 	 *            levels of the tree
 	 */
 	public void expandToLevel(int level) {
-		expandToLevel(getRoot(), level);
+		expandToLevel(level, false);
+	}
+
+	/**
+	 * Expands the root of the viewer's tree to the given level.
+	 *
+	 * @param level
+	 *            non-negative level, or <code>ALL_LEVELS</code> to expand all
+	 *            levels of the tree
+	 * @param disableRedraw
+	 *            <code>true</code> when drawing operations should be disabled
+	 *            during expansion.
+	 * @since 3.14
+	 */
+	public void expandToLevel(int level, boolean disableRedraw) {
+		BusyIndicator.showWhile(getControl().getDisplay(), () -> {
+			expandToLevel(getRoot(), level);
+		});
 	}
 
 	/**
@@ -1060,11 +1087,37 @@
 	 *            levels of the tree
 	 */
 	public void expandToLevel(Object elementOrTreePath, int level) {
+		expandToLevel(elementOrTreePath, level, false);
+	}
+
+	/**
+	 * Expands all ancestors of the given element or tree path so that the given
+	 * element becomes visible in this viewer's tree control, and then expands the
+	 * subtree rooted at the given element to the given level.
+	 *
+	 * @param elementOrTreePath
+	 *            the element
+	 * @param level
+	 *            non-negative level, or <code>ALL_LEVELS</code> to expand all
+	 *            levels of the tree
+	 * @param disableRedraw
+	 *            <code>true</code> when drawing operations should be disabled
+	 *            during expansion.
+	 * @since 3.14
+	 */
+	public void expandToLevel(Object elementOrTreePath, int level, boolean disableRedraw) {
 		if (checkBusy())
 			return;
-		Widget w = internalExpand(elementOrTreePath, true);
-		if (w != null) {
-			internalExpandToLevel(w, level);
+		try {
+			if (disableRedraw) {
+				getControl().setRedraw(false);
+			}
+			Widget w = internalExpand(elementOrTreePath, true);
+			if (w != null) {
+				internalExpandToLevel(w, level);
+			}
+		} finally {
+			getControl().setRedraw(true);
 		}
 	}