001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 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.databinding.viewers;
011:
012: import org.eclipse.core.databinding.observable.list.IListChangeListener;
013: import org.eclipse.core.databinding.observable.list.IObservableList;
014: import org.eclipse.core.databinding.observable.list.ListChangeEvent;
015: import org.eclipse.core.databinding.observable.list.ListDiffEntry;
016: import org.eclipse.core.databinding.observable.list.WritableList;
017: import org.eclipse.core.databinding.observable.set.IObservableSet;
018: import org.eclipse.core.databinding.observable.set.WritableSet;
019: import org.eclipse.jface.databinding.swt.SWTObservables;
020: import org.eclipse.jface.viewers.AbstractListViewer;
021: import org.eclipse.jface.viewers.IStructuredContentProvider;
022: import org.eclipse.jface.viewers.TableViewer;
023: import org.eclipse.jface.viewers.Viewer;
024: import org.eclipse.swt.widgets.Display;
025:
026: /**
027: * @since 1.1
028: *
029: */
030: public class ObservableListContentProvider implements
031: IStructuredContentProvider {
032:
033: private IObservableList observableList;
034:
035: private Viewer viewer;
036:
037: private IListChangeListener listener = new IListChangeListener() {
038: public void handleListChange(ListChangeEvent event) {
039: if (viewer.getControl().isDisposed()) {
040: return;
041: }
042: ListDiffEntry[] differences = event.diff.getDifferences();
043: for (int i = 0; i < differences.length; i++) {
044: ListDiffEntry entry = differences[i];
045: if (entry.isAddition()) {
046: knownElements.add(entry.getElement());
047: if (viewer instanceof AbstractListViewer) {
048: ((AbstractListViewer) viewer).add(entry
049: .getElement());
050: } else {
051: ((TableViewer) viewer).insert(entry
052: .getElement(), entry.getPosition());
053: }
054: } else {
055: if (viewer instanceof AbstractListViewer) {
056: ((AbstractListViewer) viewer).remove(entry
057: .getElement());
058: } else {
059: ((TableViewer) viewer).remove(entry
060: .getElement());
061: }
062: knownElements.remove(entry.getElement());
063: }
064: }
065: }
066: };
067:
068: private IObservableSet knownElements;
069:
070: /**
071: *
072: */
073: public ObservableListContentProvider() {
074: observableList = new WritableList(SWTObservables
075: .getRealm(Display.getDefault()));
076: knownElements = new WritableSet(SWTObservables.getRealm(Display
077: .getDefault()));
078: }
079:
080: public Object[] getElements(Object inputElement) {
081: return observableList.toArray();
082: }
083:
084: public void dispose() {
085: observableList.removeListChangeListener(listener);
086: }
087:
088: public void inputChanged(Viewer viewer, Object oldInput,
089: Object newInput) {
090: this .viewer = viewer;
091:
092: if (!(viewer instanceof TableViewer || viewer instanceof AbstractListViewer)) {
093: // use reflection to avoid 3.3 dependency:
094: Class abstractTableViewerClass = null;
095: try {
096: abstractTableViewerClass = Class
097: .forName("org.eclipse.jface.viewers.AbstractTableViewer"); //$NON-NLS-1$
098: } catch (Exception ex) {
099: // ignore, we might be running against 3.2
100: }
101: if (abstractTableViewerClass == null
102: || !abstractTableViewerClass.isInstance(viewer)) {
103: throw new IllegalArgumentException(
104: "This content provider only works with (Abstract)TableViewer or AbstractListViewer"); //$NON-NLS-1$
105: }
106: }
107:
108: if (newInput != null && !(newInput instanceof IObservableList)) {
109: throw new IllegalArgumentException(
110: "This content provider only works with input of type IObservableList"); //$NON-NLS-1$
111: }
112:
113: setInput((IObservableList) newInput);
114: }
115:
116: /**
117: * @param list
118: */
119: private void setInput(IObservableList list) {
120:
121: if (list == null) {
122: list = new WritableList(SWTObservables.getRealm(Display
123: .getDefault()));
124: }
125:
126: if (observableList != null) {
127: observableList.removeListChangeListener(listener);
128: }
129:
130: knownElements.clear();
131:
132: observableList = list;
133:
134: knownElements.addAll(list);
135:
136: observableList.addListChangeListener(listener);
137: }
138:
139: /**
140: * @return the set of elements known to this content provider. Label providers may track
141: * this set if they need to be notified about additions before the viewer sees the added
142: * element, and notified about removals after the element was removed from the viewer.
143: */
144: public IObservableSet getKnownElements() {
145: return knownElements;
146: }
147:
148: }
|