### Eclipse Workspace Patch 1.0
#P org.eclipse.jface
Index: src/org/eclipse/jface/viewers/CheckboxTableViewer.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/CheckboxTableViewer.java,v
retrieving revision 1.23
diff -u -r1.23 CheckboxTableViewer.java
--- src/org/eclipse/jface/viewers/CheckboxTableViewer.java 27 May 2008 18:24:04 -0000 1.23
+++ src/org/eclipse/jface/viewers/CheckboxTableViewer.java 12 Nov 2008 19:53:33 -0000
@@ -13,8 +13,8 @@
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
@@ -27,6 +27,9 @@
/**
* A concrete viewer based on an SWT Table
* control with checkboxes on each node.
+ *
This class supports setting an {@link ICheckStateProvider} to + * set the checkbox states. To see standard SWT behavior, view + * SWT Snippet274.
*
* This class is not intended to be subclassed outside the viewer framework.
* It is designed to be instantiated with a pre-existing SWT table control and configured
@@ -41,6 +44,11 @@
* List of check state listeners (element type: ICheckStateListener
).
*/
private ListenerList checkStateListeners = new ListenerList();
+
+ /**
+ * Provides the desired state of the check boxes.
+ */
+ private ICheckStateProvider checkStateProvider;
/**
* Creates a table viewer on a newly-created table control under the given parent.
@@ -139,8 +147,34 @@
public void addCheckStateListener(ICheckStateListener listener) {
checkStateListeners.add(listener);
}
-
+
/**
+ * Sets the {@link ICheckStateProvider} for this {@link CheckboxTreeViewer}.
+ * The check state provider will supply the logic for deciding whether the
+ * check box associated with each item should be checked, grayed or
+ * unchecked.
+ * @param checkStateProvider The provider.
+ * @since 3.5
+ */
+ public void setCheckStateProvider(ICheckStateProvider checkStateProvider) {
+ this.checkStateProvider = checkStateProvider;
+ refresh();
+ }
+
+ /*
+ * Extends this method to update check box states.
+ */
+ protected void doUpdateItem(Widget widget, Object element, boolean fullMap) {
+ super.doUpdateItem(widget, element, fullMap);
+ if(!widget.isDisposed()) {
+ if(checkStateProvider != null) {
+ setChecked(element, checkStateProvider.isChecked(element));
+ setGrayed(element, checkStateProvider.isGrayed(element));
+ }
+ }
+ }
+
+ /**
* Creates a new table control with one column.
*
* @param parent the parent control
@@ -275,7 +309,16 @@
* Method declared on Viewer.
*/
protected void preservingSelection(Runnable updateCode) {
-
+ //If a check provider is present, it determines the state across input
+ //changes.
+ if(checkStateProvider != null) {
+ //Try to preserve the selection, let the ICheckProvider manage
+ //the check states
+ super.preservingSelection(updateCode);
+ return;
+ }
+
+ //Preserve checked items
TableItem[] children = getTable().getItems();
CustomHashtable checked = newHashtable(children.length * 2 + 1);
CustomHashtable grayed = newHashtable(children.length * 2 + 1);
Index: src/org/eclipse/jface/viewers/CheckboxTreeViewer.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/viewers/CheckboxTreeViewer.java,v
retrieving revision 1.26
diff -u -r1.26 CheckboxTreeViewer.java
--- src/org/eclipse/jface/viewers/CheckboxTreeViewer.java 27 May 2008 18:24:04 -0000 1.26
+++ src/org/eclipse/jface/viewers/CheckboxTreeViewer.java 12 Nov 2008 19:53:33 -0000
@@ -13,8 +13,8 @@
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
@@ -28,6 +28,9 @@
/**
* A concrete tree-structured viewer based on an SWT Tree
* control with checkboxes on each node.
+ *
This class supports setting an {@link ICheckStateProvider} to + * set the checkbox states. To see standard SWT behavior, view + * SWT Snippet274.
*
* This class is not intended to be subclassed outside the viewer framework.
* It is designed to be instantiated with a pre-existing SWT tree control and configured
@@ -42,6 +45,11 @@
* List of check state listeners (element type: ICheckStateListener
).
*/
private ListenerList checkStateListeners = new ListenerList();
+
+ /**
+ * Provides the desired state of the check boxes.
+ */
+ private ICheckStateProvider checkStateProvider;
/**
* Last item clicked on, or null
if none.
@@ -91,8 +99,32 @@
public void addCheckStateListener(ICheckStateListener listener) {
checkStateListeners.add(listener);
}
-
+
/**
+ * Sets the {@link ICheckStateProvider} for this {@link CheckboxTreeViewer}.
+ * The check state provider will supply the logic for deciding whether the
+ * check box associated with each item should be checked, grayed or
+ * unchecked.
+ * @param checkStateProvider The provider.
+ * @since 3.5
+ */
+ public void setCheckStateProvider(ICheckStateProvider checkStateProvider) {
+ this.checkStateProvider = checkStateProvider;
+ refresh();
+ }
+
+ /*
+ * Extends this method to update check box states.
+ */
+ protected void doUpdateItem(Item item, Object element) {
+ super.doUpdateItem(item, element);
+ if(!item.isDisposed() && checkStateProvider != null) {
+ setChecked(element, checkStateProvider.isChecked(element));
+ setGrayed(element, checkStateProvider.isGrayed(element));
+ }
+ }
+
+ /**
* Applies the checked and grayed states of the given widget and its
* descendents.
*
@@ -362,7 +394,16 @@
* Method declared on Viewer.
*/
protected void preservingSelection(Runnable updateCode) {
-
+ //If a check provider is present, it determines the state across input
+ //changes.
+ if(checkStateProvider != null) {
+ //Try to preserve the selection, let the ICheckProvider manage
+ //the check states
+ super.preservingSelection(updateCode);
+ return;
+ }
+
+ //Preserve checked items
int n = getItemCount(getControl());
CustomHashtable checkedNodes = newHashtable(n * 2 + 1);
CustomHashtable grayedNodes = newHashtable(n * 2 + 1);
Index: src/org/eclipse/jface/viewers/ICheckStateProvider.java
===================================================================
RCS file: src/org/eclipse/jface/viewers/ICheckStateProvider.java
diff -N src/org/eclipse/jface/viewers/ICheckStateProvider.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/jface/viewers/ICheckStateProvider.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jface.viewers;
+
+/**
+ * Interface to provide checked and grayed state information about data in trees
+ * or tables. The following chart determines the checkbox state:
+ *
+ * | + * | isGrayed() |
+ * |
+ * | + * | false |
+ * true |
+ *
isChecked() |
+ * false |
+ * unchecked | + *|
true |
+ * checked | + *grayed | + *
true
+ * the {@link ICheckStateProvider#isGrayed(Object)} method will determine
+ * whether the check box displays a check mark ("checked") or a box
+ * ("grayed").
+ * @param element
+ * @return true if the element should be checked or grayed, false if it
+ * should be unchecked
+ */
+ public boolean isChecked(Object element);
+
+ /**
+ * Indicates whether the check box associated with an element, when checked
+ * as indicated by the {@link ICheckStateProvider#isChecked(Object)} method,
+ * should display the gray (boxed) state instead of the check mark.
+ * @param element
+ * @return true if the element should be gray
+ */
+ public boolean isGrayed(Object element);
+}
#P org.eclipse.ui.tests
Index: Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTreeViewerTest.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.tests/Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTreeViewerTest.java,v
retrieving revision 1.10
diff -u -r1.10 CheckboxTreeViewerTest.java
--- Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTreeViewerTest.java 16 Mar 2007 18:00:00 -0000 1.10
+++ Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTreeViewerTest.java 12 Nov 2008 19:53:34 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2006, 2008 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
@@ -10,11 +10,20 @@
*******************************************************************************/
package org.eclipse.jface.tests.viewers;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.tests.viewers.CheckStateProviderTestsUtil.TestCheckStateProvider;
+import org.eclipse.jface.tests.viewers.CheckStateProviderTestsUtil.TestMethodsInvokedCheckStateProvider;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TreeItem;
public class CheckboxTreeViewerTest extends TreeViewerTest {
public static class CheckboxTableTestLabelProvider extends
@@ -105,4 +114,221 @@
assertTrue(elements[2] == firstfirstfirst);
ctv.setParentsGrayed(firstfirstfirst, false);
}
+
+ public void testWithoutCheckProvider() {
+ //Check that without a provider, no exceptions are thrown
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer)fViewer;
+ ctv.expandAll();
+ ctv.refresh();
+ }
+
+ public void testCheckProviderInvoked() {
+ //Check that a refresh successfully causes the provider's
+ //setChecked and setGrayed methods to be invoked.
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer)fViewer;
+
+ TestMethodsInvokedCheckStateProvider provider = new TestMethodsInvokedCheckStateProvider();
+
+ ctv.setCheckStateProvider(provider);
+ assertTrue("isChecked should be invoked on a refresh", (!provider.isCheckedInvokedOn.isEmpty()));
+ assertTrue("isGrayed should be invoked on a refresh", (!provider.isGrayedInvokedOn.isEmpty()));
+
+ provider.reset();
+ ctv.refresh();
+ assertTrue("isChecked should be invoked on a refresh", (!provider.isCheckedInvokedOn.isEmpty()));
+ assertTrue("isGrayed should be invoked on a refresh", (!provider.isGrayedInvokedOn.isEmpty()));
+
+ }
+
+ public void testCheckProviderLazilyInvoked() {
+ //Check that a refresh successfully causes the provider's
+ //setChecked and setGrayed methods to be invoked.
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer)fViewer;
+
+ TestMethodsInvokedCheckStateProvider provider = new TestMethodsInvokedCheckStateProvider();
+
+ ctv.setCheckStateProvider(provider);
+ ctv.refresh();
+
+ TestElement[] expected = fRootElement.getChildren();
+
+ for (Iterator i = provider.isCheckedInvokedOn.iterator(); i.hasNext();) {
+ TestElement element = (TestElement) i.next();
+ boolean firstLevelElement = false;
+ for (int j = 0; j < expected.length && !firstLevelElement; j++) {
+ firstLevelElement = element.equals(expected[j]);
+ }
+ assertTrue("The check provider should only be invoked with visible elements", firstLevelElement);
+ }
+
+ for (Iterator i = provider.isGrayedInvokedOn.iterator(); i.hasNext();) {
+ TestElement element = (TestElement) i.next();
+ boolean firstLevelElement = false;
+ for (int j = 0; j < expected.length && !firstLevelElement; j++) {
+ firstLevelElement = element.equals(expected[j]);
+ }
+ assertTrue("The check provider should only be invoked with visible elements", firstLevelElement);
+ }
+ }
+
+ public void testCheckedFalseGrayedFalse() {
+ testSpecificState(false, false);
+ }
+
+ public void testCheckedFalseGrayedTrue() {
+ testSpecificState(false, true);
+ }
+
+ public void testCheckedTrueGrayedFalse() {
+ testSpecificState(true, false);
+ }
+
+ public void testCheckedTrueGrayedTrue() {
+ testSpecificState(true, true);
+ }
+
+ private void testSpecificState(final boolean isChecked, final boolean isGrayed) {
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer)fViewer;
+
+ ctv.setCheckStateProvider(new ICheckStateProvider() {
+ public boolean isChecked(Object element) { return isChecked; }
+ public boolean isGrayed(Object element) { return isGrayed; }
+ });
+
+ TreeItem item = ctv.getTree().getItem(0);
+
+ assertEquals(item.getChecked(), isChecked);
+ assertEquals(item.getGrayed(), isGrayed);
+ }
+
+ public void testSetCheckProviderRefreshesItems() {
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer) fViewer;
+
+ //First provider
+ //Should cause visible items' check state adhere to provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(0));
+
+ ctv.expandAll();
+
+ //Check that all states are properly set
+ checkAllStates("Testing checkbox state after refresh", ctv, 0);
+
+ //Remove the check state provider
+ ctv.setCheckStateProvider(null);
+
+ //Test that an update doesn't fail
+ TestElement update = fRootElement.getFirstChild().getChildAt(5);
+ ctv.update(update, null);
+
+ //Test that a refresh doesn't fail
+ ctv.refresh();
+ }
+
+ public void testCheckProviderWithSorter() {
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer) fViewer;
+
+ ctv.setSorter(new CheckStateProviderTestsUtil.Sorter());
+
+ //First provider
+ //Should cause visible items' check state adhere to provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(0));
+ ctv.expandAll();
+
+ //Check that all states are properly set
+ checkAllStates("Testing checkbox state with a sorter", ctv, 0);
+ }
+
+ public void testCheckProviderWithFilter() {
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer) fViewer;
+
+ final CheckStateProviderTestsUtil.Filter filter = new CheckStateProviderTestsUtil.Filter();
+ ctv.addFilter(filter);
+
+ //First provider
+ //Should cause visible items' check state adhere to provider
+ final TestCheckStateProvider checkStateProvider = new TestCheckStateProvider(0);
+ ctv.setCheckStateProvider(checkStateProvider);
+ ctv.expandAll();
+
+ //Check that all states are properly set
+ checkAllStates("Testing checkbox state with a sorter", ctv, 0);
+
+ //Check that the provider is only invoked on elements which pass the filter
+ for (Iterator i = checkStateProvider.isCheckedInvokedOn.iterator(); i.hasNext();) {
+ TestElement element = (TestElement) i.next();
+ assertTrue("The check provider should not be invoked on elements which did not get through the filter", filter.select(ctv, null, element));
+ }
+
+ for (Iterator i = checkStateProvider.isGrayedInvokedOn.iterator(); i.hasNext();) {
+ TestElement element = (TestElement) i.next();
+ assertTrue("The check provider should not be invoked on elements which did not get through the filter", filter.select(ctv, null, element));
+ }
+ }
+
+ public void testSetNewCheckProvider() {
+ CheckboxTreeViewer ctv = (CheckboxTreeViewer) fViewer;
+
+ //First provider
+ //Should cause visible items' check state to adhere to provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(0));
+ ctv.expandAll();
+
+ checkAllStates("Testing checkbox state after first refresh", ctv, 0);
+
+ //Put in a new check state provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(1));
+
+ //Check that setting a new check provider caused a refresh,
+ //and thus all the items have their new appropriate check
+ //states.
+ checkAllStates("Testing checkbox state after setting new check provider", ctv, 1);
+ }
+
+ private void collectElementsInBranch(TreeItem item, Collection treeItems, Collection testElements) {
+ treeItems.add(item);
+ testElements.add(item.getData());
+ TreeItem[] children = item.getItems();
+ for (int i = 0; i < children.length; i++) {
+ collectElementsInBranch(children[i], treeItems, testElements);
+ }
+ }
+
+ private void checkAllStates(String comment, CheckboxTreeViewer ctv, int shift) {
+ List items = new ArrayList();
+ List elements = new ArrayList();
+ collectElementsInBranch(ctv.getTree().getItem(0), items, elements);
+
+ //Check that actual states were set properly
+ for (Iterator i = items.iterator(), j = elements.iterator(); i.hasNext();) {
+ TreeItem item = (TreeItem)i.next();
+ TestElement element = (TestElement)j.next();
+
+ checkState(comment, element, item, shift); //check in Tree
+ checkState(comment, element, ctv, shift); //check in Viewer
+ }
+ }
+
+ /**
+ * Invokes the appropriate asserts to verify the state
+ * of a TestElement.
+ * @param te
+ * @param viewer the viewer te
is in.
+ * @param shift the shift parameter being used
+ */
+ private void checkState(String comment, TestElement te, CheckboxTreeViewer viewer, int shift) {
+ assertEquals(comment, CheckStateProviderTestsUtil.shouldBeChecked(te, shift), viewer.getChecked(te));
+ assertEquals(comment, CheckStateProviderTestsUtil.shouldBeGrayed(te, shift), viewer.getGrayed(te));
+ }
+
+ /**
+ * Invokes the appropriate asserts to verify the state
+ * of a TestElement's associated TreeItem
+ * @param te
+ * @param item the item representing te
+ * @param shift the shift parameter being used
+ */
+ private void checkState(String comment, TestElement te, TreeItem item, int shift) {
+ assertEquals("Wrong checkstate: " + comment, CheckStateProviderTestsUtil.shouldBeChecked(te, shift), item.getChecked());
+ assertEquals("Wrong checkstate: " + comment, CheckStateProviderTestsUtil.shouldBeGrayed(te, shift), item.getGrayed());
+ }
}
Index: Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTableViewerTest.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.tests/Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTableViewerTest.java,v
retrieving revision 1.8
diff -u -r1.8 CheckboxTableViewerTest.java
--- Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTableViewerTest.java 16 Mar 2007 18:00:00 -0000 1.8
+++ Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckboxTableViewerTest.java 12 Nov 2008 19:53:34 -0000
@@ -10,9 +10,14 @@
*******************************************************************************/
package org.eclipse.jface.tests.viewers;
+import java.util.Iterator;
+
+import org.eclipse.jface.tests.viewers.CheckStateProviderTestsUtil.TestCheckStateProvider;
+import org.eclipse.jface.tests.viewers.CheckStateProviderTestsUtil.TestMethodsInvokedCheckStateProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ICheckStateProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableLayout;
@@ -22,6 +27,7 @@
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
public class CheckboxTableViewerTest extends TableViewerTest {
public static class CheckboxTableTestLabelProvider extends
@@ -142,4 +148,172 @@
ctv.setAllGrayed(false);
}
+
+ public void testWithoutCheckProvider() {
+ //Check that without a provider, no exceptions are thrown
+ CheckboxTableViewer ctv = (CheckboxTableViewer)fViewer;
+ ctv.refresh();
+ }
+
+ public void testCheckProviderInvoked() {
+ //Check that a refresh successfully causes the provider's
+ //setChecked and setGrayed methods to be invoked.
+ CheckboxTableViewer ctv = (CheckboxTableViewer)fViewer;
+
+ TestMethodsInvokedCheckStateProvider provider = new TestMethodsInvokedCheckStateProvider();
+
+ ctv.setCheckStateProvider(provider);
+ assertTrue("isChecked should be invoked on a refresh", (!provider.isCheckedInvokedOn.isEmpty()));
+ assertTrue("isGrayed should be invoked on a refresh", (!provider.isGrayedInvokedOn.isEmpty()));
+
+ provider.reset();
+ ctv.refresh();
+ assertTrue("isChecked should be invoked on a refresh", (!provider.isCheckedInvokedOn.isEmpty()));
+ assertTrue("isGrayed should be invoked on a refresh", (!provider.isGrayedInvokedOn.isEmpty()));
+ }
+
+ public void testCheckedFalseGrayedFalse() {
+ testSpecificState(false, false);
+ }
+
+ public void testCheckedFalseGrayedTrue() {
+ testSpecificState(false, true);
+ }
+
+ public void testCheckedTrueGrayedFalse() {
+ testSpecificState(true, false);
+ }
+
+ public void testCheckedTrueGrayedTrue() {
+ testSpecificState(true, true);
+ }
+
+ private void testSpecificState(final boolean isChecked, final boolean isGrayed) {
+ CheckboxTableViewer ctv = (CheckboxTableViewer)fViewer;
+
+ ctv.setCheckStateProvider(new ICheckStateProvider() {
+ public boolean isChecked(Object element) { return isChecked; }
+ public boolean isGrayed(Object element) { return isGrayed; }
+ });
+
+ TableItem item = ctv.getTable().getItem(0);
+
+ assertEquals(item.getChecked(), isChecked);
+ assertEquals(item.getGrayed(), isGrayed);
+ }
+
+ public void testSetCheckProviderRefreshesItems() {
+ CheckboxTableViewer ctv = (CheckboxTableViewer)fViewer;
+
+ //First provider
+ //Should cause visible items' check state to adhere to provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(0));
+
+ //Check that all states are properly set
+ checkAllStates("Testing checkbox state after refresh", ctv, 0);
+
+ //Remove the check state provider
+ ctv.setCheckStateProvider(null);
+
+ //Test that an update doesn't fail
+ TestElement update = fRootElement.getChildAt(5);
+ ctv.update(update, null);
+
+ //Test that a refresh doesn't fail
+ ctv.refresh();
+ }
+
+ public void testCheckProviderWithSorter() {
+ CheckboxTableViewer ctv = (CheckboxTableViewer) fViewer;
+
+ ctv.setSorter(new CheckStateProviderTestsUtil.Sorter());
+
+ //First provider
+ //Should cause visible items' check state adhere to provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(0));
+
+ //Check that all states are properly set
+ checkAllStates("Testing checkbox state with a sorter", ctv, 0);
+ }
+
+ public void testCheckProviderWithFilter() {
+ CheckboxTableViewer ctv = (CheckboxTableViewer) fViewer;
+
+ final CheckStateProviderTestsUtil.Filter filter = new CheckStateProviderTestsUtil.Filter();
+ ctv.addFilter(filter);
+
+ //First provider
+ //Should cause visible items' check state adhere to provider
+ final TestCheckStateProvider checkStateProvider = new TestCheckStateProvider(0);
+ ctv.setCheckStateProvider(checkStateProvider);
+
+ //Check that all states are properly set
+ checkAllStates("Testing checkbox state with a sorter", ctv, 0);
+
+ //Check that the provider is only invoked on elements which pass the filter
+ for (Iterator i = checkStateProvider.isCheckedInvokedOn.iterator(); i.hasNext();) {
+ TestElement element = (TestElement) i.next();
+ assertTrue("The check provider should not be invoked on elements which did not get through the filter", filter.select(ctv, null, element));
+ }
+
+ for (Iterator i = checkStateProvider.isGrayedInvokedOn.iterator(); i.hasNext();) {
+ TestElement element = (TestElement) i.next();
+ assertTrue("The check provider should not be invoked on elements which did not get through the filter", filter.select(ctv, null, element));
+ }
+ }
+
+ public void testCheckProviderUpdate() {
+ CheckboxTableViewer ctv = (CheckboxTableViewer)fViewer;
+
+ //First provider
+ //Should cause visible items' check state to adhere to provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(0));
+
+ checkAllStates("Testing checkbox state after refresh", ctv, 0);
+
+ //Put in a new check state provider
+ ctv.setCheckStateProvider(new TestCheckStateProvider(1));
+
+ //Check that setting a new check provider caused a refresh,
+ //and thus all the items have their new appropriate check
+ //states.
+ checkAllStates("Testing checkbox state after refresh", ctv, 1);
+ }
+
+ private void checkAllStates(String comment, CheckboxTableViewer ctv, int shift) {
+ TableItem[] items = ctv.getTable().getItems();
+
+ //Check that actual states were set properly
+ for (int i = 0; i < items.length; i++) {
+ TableItem item = items[i];
+ TestElement element = (TestElement)items[i].getData();
+
+ checkState(comment, element, item, shift); //check in Table
+ checkState(comment, element, ctv, shift); //check in Viewer
+ }
+ }
+
+ /**
+ * Invokes the appropriate asserts to verify the state
+ * of a TestElement.
+ * @param te
+ * @param viewer the viewer te
is in.
+ * @param shift the shift parameter being used
+ */
+ private void checkState(String comment, TestElement te, CheckboxTableViewer viewer, int shift) {
+ assertEquals(comment, CheckStateProviderTestsUtil.shouldBeChecked(te, shift), viewer.getChecked(te));
+ assertEquals(comment, CheckStateProviderTestsUtil.shouldBeGrayed(te, shift), viewer.getGrayed(te));
+ }
+
+ /**
+ * Invokes the appropriate asserts to verify the state
+ * of a TestElement's associated TableItem
+ * @param te
+ * @param item the item representing te
+ * @param shift the shift parameter being used
+ */
+ private void checkState(String comment, TestElement te, TableItem item, int shift) {
+ assertEquals("Wrong checkstate: " + comment, CheckStateProviderTestsUtil.shouldBeChecked(te, shift), item.getChecked());
+ assertEquals("Wrong checkstate: " + comment, CheckStateProviderTestsUtil.shouldBeGrayed(te, shift), item.getGrayed());
+ }
}
Index: Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckStateProviderTestsUtil.java
===================================================================
RCS file: Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckStateProviderTestsUtil.java
diff -N Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckStateProviderTestsUtil.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Eclipse JFace Tests/org/eclipse/jface/tests/viewers/CheckStateProviderTestsUtil.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.jface.tests.viewers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ICheckStateProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+/**
+ * Utilities for testing ICheckStateProviders.
+ * @since 3.5
+ */
+public class CheckStateProviderTestsUtil {
+ private static final int NUMBER_OF_STATES = 4;
+
+ /**
+ * An ICheckStateProvider which records whether
+ * its isChecked and isGrayed methods are invoked.
+ * @since 3.5
+ */
+ public static class TestMethodsInvokedCheckStateProvider implements ICheckStateProvider {
+ public List isCheckedInvokedOn = new ArrayList();
+ public List isGrayedInvokedOn = new ArrayList();
+
+ public boolean isChecked(Object element) {
+ isCheckedInvokedOn.add(element);
+ return true;
+ }
+
+ public boolean isGrayed(Object element) {
+ isGrayedInvokedOn.add(element);
+ return true;
+ }
+
+ public void reset() {
+ isCheckedInvokedOn = new ArrayList();
+ isGrayedInvokedOn = new ArrayList();
+ }
+ }
+
+ /**
+ * An ICheckStateProvider which provides a consistent
+ * variety of states for input elements based on the
+ * parameter provided in the constructor.
+ * @since 3.5
+ */
+ public static final class TestCheckStateProvider extends TestMethodsInvokedCheckStateProvider {
+ private int shift;
+
+ /**
+ * A value from 0 to 2 which will change the
+ * checkstate assignments.
+ * @param shift
+ */
+ public TestCheckStateProvider(int shift) {
+ this.shift = shift;
+ }
+
+ public boolean isChecked(Object element) {
+ super.isChecked(element);
+ return shouldBeChecked((TestElement)element, shift);
+ }
+
+ public boolean isGrayed(Object element) {
+ super.isGrayed(element);
+ return shouldBeGrayed((TestElement)element, shift);
+ }
+ }
+
+ /**
+ * A sorter for TestElements.
+ * @since 3.5
+ */
+ public static final class Sorter extends ViewerSorter {
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ return constructNumber((TestElement)e1) - constructNumber((TestElement)e2);
+ }
+ }
+
+ /**
+ * A filter for TestElements.
+ * @since 3.5
+ */
+ public static final class Filter extends ViewerFilter {
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ return (constructNumber((TestElement)element) % (NUMBER_OF_STATES * 2 - 1)) == (NUMBER_OF_STATES - 1);
+ }
+ }
+ /**
+ * @param te
+ * @return a number between 0 and 3 based on te
.
+ * Given the same TestElement, this function always returns the
+ * same value.
+ */
+ public static int constructNumber(TestElement te) {
+ String id = te.getID();
+ int number = Integer.parseInt(id.substring(id.lastIndexOf('-') + 1)) + id.length();
+ return number % NUMBER_OF_STATES;
+ }
+
+ /**
+ * @param te
+ * @param shift a parameter to change all check states
+ * to be different (use to simulate different
+ * providers over time)
+ * @return true iff te
should be checked
+ */
+ public static boolean shouldBeChecked(TestElement te, int shift) {
+ return ((constructNumber(te) + shift) % NUMBER_OF_STATES) > 1;
+ }
+
+ /**
+ * @param te
+ * @param shift a parameter to change all check states
+ * to be different (use to simulate different
+ * providers over time)
+ * @return true iff te
should be grayed
+ */
+ public static boolean shouldBeGrayed(TestElement te, int shift) {
+ return ((constructNumber(te) + shift) % NUMBER_OF_STATES) % 2 == 1;
+ }
+}