001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jface.viewers.deferred;
011:
012: import java.util.Comparator;
013:
014: import org.eclipse.core.runtime.Assert;
015: import org.eclipse.jface.viewers.AcceptAllFilter;
016: import org.eclipse.jface.viewers.IFilter;
017: import org.eclipse.jface.viewers.ILazyContentProvider;
018: import org.eclipse.jface.viewers.TableViewer;
019: import org.eclipse.jface.viewers.Viewer;
020: import org.eclipse.swt.widgets.Control;
021: import org.eclipse.swt.widgets.Table;
022:
023: /**
024: * Content provider that performs sorting and filtering in a background thread.
025: * Requires a <code>TableViewer</code> created with the <code>SWT.VIRTUAL</code>
026: * flag and an <code>IConcurrentModel</code> as input.
027: * <p>
028: * The sorter and filter must be set directly on the content provider.
029: * Any sorter or filter on the TableViewer will be ignored.
030: * </p>
031: *
032: * <p>
033: * The real implementation is in <code>BackgroundContentProvider</code>. This
034: * object is a lightweight wrapper that adapts the algorithm to work with
035: * <code>TableViewer</code>.
036: * </p>
037: *
038: * @since 3.1
039: */
040: public class DeferredContentProvider implements ILazyContentProvider {
041:
042: private int limit = -1;
043: private BackgroundContentProvider provider;
044: private Comparator sortOrder;
045: private IFilter filter = AcceptAllFilter.getInstance();
046: private AbstractVirtualTable table;
047:
048: private static final class TableViewerAdapter extends
049: AbstractVirtualTable {
050:
051: private TableViewer viewer;
052:
053: /**
054: * @param viewer
055: */
056: public TableViewerAdapter(TableViewer viewer) {
057: this .viewer = viewer;
058: }
059:
060: /* (non-Javadoc)
061: * @see org.eclipse.jface.viewers.deferred.AbstractVirtualTable#flushCache(java.lang.Object)
062: */
063: public void clear(int index) {
064: viewer.clear(index);
065: }
066:
067: /* (non-Javadoc)
068: * @see org.eclipse.jface.viewers.deferred.AbstractVirtualTable#replace(java.lang.Object, int)
069: */
070: public void replace(Object element, int itemIndex) {
071: viewer.replace(element, itemIndex);
072: }
073:
074: /* (non-Javadoc)
075: * @see org.eclipse.jface.viewers.deferred.AbstractVirtualTable#setItemCount(int)
076: */
077: public void setItemCount(int total) {
078: viewer.setItemCount(total);
079: }
080:
081: /* (non-Javadoc)
082: * @see org.eclipse.jface.viewers.deferred.AbstractVirtualTable#getItemCount()
083: */
084: public int getItemCount() {
085: return viewer.getTable().getItemCount();
086: }
087:
088: /* (non-Javadoc)
089: * @see org.eclipse.jface.viewers.deferred.AbstractVirtualTable#getTopIndex()
090: */
091: public int getTopIndex() {
092: return Math.max(viewer.getTable().getTopIndex() - 1, 0);
093: }
094:
095: /* (non-Javadoc)
096: * @see org.eclipse.jface.viewers.deferred.AbstractVirtualTable#getVisibleItemCount()
097: */
098: public int getVisibleItemCount() {
099: int start = getTopIndex();
100: int itemCount = getItemCount();
101: Table table = viewer.getTable();
102: return Math.min(table.getBounds().height
103: / table.getItemHeight() + 2, itemCount - start);
104: }
105:
106: /* (non-Javadoc)
107: * @see org.eclipse.jface.viewers.deferred.AbstractVirtualTable#getControl()
108: */
109: public Control getControl() {
110: return viewer.getControl();
111: }
112:
113: }
114:
115: /**
116: * Create a DeferredContentProvider with the given sort order.
117: * @param sortOrder a comparator that sorts the content.
118: */
119: public DeferredContentProvider(Comparator sortOrder) {
120: this .sortOrder = sortOrder;
121: }
122:
123: /* (non-Javadoc)
124: * @see org.eclipse.jface.viewers.IContentProvider#dispose()
125: */
126: public void dispose() {
127: setProvider(null);
128: }
129:
130: /* (non-Javadoc)
131: * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
132: */
133: public void inputChanged(Viewer viewer, Object oldInput,
134: Object newInput) {
135: if (newInput == null) {
136: setProvider(null);
137: return;
138: }
139:
140: Assert.isTrue(newInput instanceof IConcurrentModel);
141: Assert.isTrue(viewer instanceof TableViewer);
142: IConcurrentModel model = (IConcurrentModel) newInput;
143:
144: this .table = new TableViewerAdapter((TableViewer) viewer);
145:
146: BackgroundContentProvider newProvider = new BackgroundContentProvider(
147: table, model, sortOrder);
148:
149: setProvider(newProvider);
150:
151: newProvider.setLimit(limit);
152: newProvider.setFilter(filter);
153: }
154:
155: /**
156: * Sets the sort order for this content provider. This sort order takes priority
157: * over anything that was supplied to the <code>TableViewer</code>.
158: *
159: * @param sortOrder new sort order. The comparator must be able to support being
160: * used in a background thread.
161: */
162: public void setSortOrder(Comparator sortOrder) {
163: Assert.isNotNull(sortOrder);
164: this .sortOrder = sortOrder;
165: if (provider != null) {
166: provider.setSortOrder(sortOrder);
167: }
168: }
169:
170: /**
171: * Sets the filter for this content provider. This filter takes priority over
172: * anything that was supplied to the <code>TableViewer</code>. The filter
173: * must be capable of being used in a background thread.
174: *
175: * @param toSet filter to set
176: */
177: public void setFilter(IFilter toSet) {
178: this .filter = toSet;
179: if (provider != null) {
180: provider.setFilter(toSet);
181: }
182: }
183:
184: /**
185: * Sets the maximum number of rows in the table. If the model contains more
186: * than this number of elements, only the top elements will be shown based on
187: * the current sort order.
188: *
189: * @param limit maximum number of rows to show or -1 if unbounded
190: */
191: public void setLimit(int limit) {
192: this .limit = limit;
193: if (provider != null) {
194: provider.setLimit(limit);
195: }
196: }
197:
198: /**
199: * Returns the current maximum number of rows or -1 if unbounded
200: *
201: * @return the current maximum number of rows or -1 if unbounded
202: */
203: public int getLimit() {
204: return limit;
205: }
206:
207: /* (non-Javadoc)
208: * @see org.eclipse.jface.viewers.ILazyContentProvider#updateElement(int)
209: */
210: public void updateElement(int element) {
211: if (provider != null) {
212: provider.checkVisibleRange(element);
213: }
214: }
215:
216: private void setProvider(BackgroundContentProvider newProvider) {
217: if (provider != null) {
218: provider.dispose();
219: }
220:
221: provider = newProvider;
222: }
223:
224: }
|