View | Details | Raw Unified | Return to bug 258967 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/core/databinding/TargetsListener.java (+131 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.core.databinding;
13
14
import java.util.ArrayList;
15
import java.util.Iterator;
16
import java.util.List;
17
18
import org.eclipse.core.databinding.observable.ChangeEvent;
19
import org.eclipse.core.databinding.observable.IChangeListener;
20
import org.eclipse.core.databinding.observable.IObservable;
21
import org.eclipse.core.databinding.observable.list.IListChangeListener;
22
import org.eclipse.core.databinding.observable.list.IObservableList;
23
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
24
import org.eclipse.core.databinding.observable.list.ListDiff;
25
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
26
27
/**
28
 * A TargetListener listens to changes of any target of any
29
 * ValidationStatusProvider in the given context.
30
 * 
31
 * @since 1.2
32
 * 
33
 */
34
public class TargetsListener {
35
	/**
36
	 * Creates a TargetsListener. Once when any target changes the listener will
37
	 * be notified and the TargetsListener will be disposed.
38
	 * 
39
	 * @param context
40
	 * @param listener
41
	 * @return The TargetsListener is returned so it can be disposed even if no
42
	 *         change occurs. It should not be used for anything else.
43
	 */
44
	public static TargetsListener listenOnce(DataBindingContext context, final IChangeListener listener) {
45
		final TargetsListener targetsListener = new TargetsListener(context);
46
		targetsListener.addChangeListener(new IChangeListener() {
47
			public void handleChange(ChangeEvent event) {
48
				listener.handleChange(event);
49
				targetsListener.dispose();
50
			}
51
		});
52
		return targetsListener;
53
	}
54
55
	private final List changeListeners = new ArrayList();
56
57
	private IChangeListener targetListener = new IChangeListener() {
58
		public void handleChange(ChangeEvent event) {
59
			Iterator iterator = changeListeners.iterator();
60
			while (iterator.hasNext()) {
61
				IChangeListener listener = (IChangeListener) iterator.next();
62
				listener.handleChange(event);
63
			}
64
		}
65
	};
66
	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
67
		public void handleListChange(ListChangeEvent event) {
68
			ListDiff diff = event.diff;
69
			ListDiffEntry[] differences = diff.getDifferences();
70
			for (int i = 0; i < differences.length; i++) {
71
				ListDiffEntry listDiffEntry = differences[i];
72
				IObservable target = (IObservable) listDiffEntry.getElement();
73
				if (listDiffEntry.isAddition()) {
74
					target.addChangeListener(targetListener);
75
				} else {
76
					target.removeChangeListener(targetListener);
77
				}
78
			}
79
		}
80
	};
81
	private IObservableList targets;
82
83
	/**
84
	 * A TargetListener listens to changes of any target of any
85
	 * ValidationStatusProvider in the given context.
86
	 * 
87
	 * @param context
88
	 */
89
	public TargetsListener(DataBindingContext context) {
90
		targets = BindingProperties.validationStatusProviders().lists(
91
				   BindingProperties.targets()).observe(context);
92
		targets.addListChangeListener(validationStatusProviderTargetsListener);
93
		for (Iterator it = targets.iterator(); it.hasNext();) {
94
			((IObservable) it.next()).addChangeListener(targetListener);
95
		}
96
	}
97
98
	/**
99
	 * Adds the {@link IChangeListener} to the list of target listeners.
100
	 * 
101
	 * @param listener
102
	 *            The IChangeListener that will be notified in case any target
103
	 *            changes.
104
	 * @since 1.2
105
	 */
106
	public final void addChangeListener(IChangeListener listener) {
107
		changeListeners.add(listener);
108
	}
109
110
	/**
111
	 * Removes the {@link IChangeListener} from the list of target listeners.
112
	 * 
113
	 * @param listener
114
	 *            The IChangeListener that should no longer be notified in case
115
	 *            any target changes.
116
	 * @since 1.2
117
	 */
118
	public final void removeChangeListener(IChangeListener listener) {
119
		changeListeners.remove(listener);
120
	}
121
122
	/**
123
	 * 
124
	 */
125
	public void dispose() {
126
		for (Iterator it = targets.iterator(); it.hasNext();) {
127
			((IObservable) it.next()).removeChangeListener(targetListener);
128
		}
129
		targets.dispose();
130
	}
131
}
(-)src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java (-99 / +7 lines)
Lines 15-35 Link Here
15
15
16
package org.eclipse.jface.databinding.dialog;
16
package org.eclipse.jface.databinding.dialog;
17
17
18
import java.util.Iterator;
19
20
import org.eclipse.core.databinding.AggregateValidationStatus;
18
import org.eclipse.core.databinding.AggregateValidationStatus;
21
import org.eclipse.core.databinding.DataBindingContext;
19
import org.eclipse.core.databinding.DataBindingContext;
22
import org.eclipse.core.databinding.ValidationStatusProvider;
20
import org.eclipse.core.databinding.TargetsListener;
23
import org.eclipse.core.databinding.observable.ChangeEvent;
21
import org.eclipse.core.databinding.observable.ChangeEvent;
24
import org.eclipse.core.databinding.observable.IChangeListener;
22
import org.eclipse.core.databinding.observable.IChangeListener;
25
import org.eclipse.core.databinding.observable.IObservable;
26
import org.eclipse.core.databinding.observable.IStaleListener;
23
import org.eclipse.core.databinding.observable.IStaleListener;
27
import org.eclipse.core.databinding.observable.StaleEvent;
24
import org.eclipse.core.databinding.observable.StaleEvent;
28
import org.eclipse.core.databinding.observable.list.IListChangeListener;
29
import org.eclipse.core.databinding.observable.list.IObservableList;
30
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
31
import org.eclipse.core.databinding.observable.list.ListDiff;
32
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
33
import org.eclipse.core.databinding.observable.value.IObservableValue;
25
import org.eclipse.core.databinding.observable.value.IObservableValue;
34
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
26
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
35
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
27
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
Lines 68-122 Link Here
68
	private DataBindingContext dbc;
60
	private DataBindingContext dbc;
69
	private IObservableValue aggregateStatus;
61
	private IObservableValue aggregateStatus;
70
	private boolean uiChanged = false;
62
	private boolean uiChanged = false;
71
	private IChangeListener uiChangeListener = new IChangeListener() {
72
		public void handleChange(ChangeEvent event) {
73
			handleUIChanged();
74
		}
75
	};
76
	private IListChangeListener validationStatusProvidersListener = new IListChangeListener() {
77
		public void handleListChange(ListChangeEvent event) {
78
			ListDiff diff = event.diff;
79
			ListDiffEntry[] differences = diff.getDifferences();
80
			for (int i = 0; i < differences.length; i++) {
81
				ListDiffEntry listDiffEntry = differences[i];
82
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry
83
						.getElement();
84
				IObservableList targets = validationStatusProvider.getTargets();
85
				if (listDiffEntry.isAddition()) {
86
					targets
87
							.addListChangeListener(validationStatusProviderTargetsListener);
88
					for (Iterator it = targets.iterator(); it.hasNext();) {
89
						((IObservable) it.next())
90
								.addChangeListener(uiChangeListener);
91
					}
92
				} else {
93
					targets
94
							.removeListChangeListener(validationStatusProviderTargetsListener);
95
					for (Iterator it = targets.iterator(); it.hasNext();) {
96
						((IObservable) it.next())
97
								.removeChangeListener(uiChangeListener);
98
					}
99
				}
100
			}
101
		}
102
	};
103
	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
104
		public void handleListChange(ListChangeEvent event) {
105
			ListDiff diff = event.diff;
106
			ListDiffEntry[] differences = diff.getDifferences();
107
			for (int i = 0; i < differences.length; i++) {
108
				ListDiffEntry listDiffEntry = differences[i];
109
				IObservable target = (IObservable) listDiffEntry.getElement();
110
				if (listDiffEntry.isAddition()) {
111
					target.addChangeListener(uiChangeListener);
112
				} else {
113
					target.removeChangeListener(uiChangeListener);
114
				}
115
			}
116
		}
117
	};
118
	protected IStatus currentStatus;
63
	protected IStatus currentStatus;
119
	protected boolean currentStatusStale;
64
	protected boolean currentStatusStale;
65
	private TargetsListener targetsListener;
120
66
121
	/**
67
	/**
122
	 * @param dialogPage
68
	 * @param dialogPage
Lines 161-179 Link Here
161
		currentStatus = (IStatus) aggregateStatus.getValue();
107
		currentStatus = (IStatus) aggregateStatus.getValue();
162
		currentStatusStale = aggregateStatus.isStale();
108
		currentStatusStale = aggregateStatus.isStale();
163
		handleStatusChanged();
109
		handleStatusChanged();
164
		dbc.getValidationStatusProviders().addListChangeListener(
110
		targetsListener = TargetsListener.listenOnce(dbc, new IChangeListener() {
165
				validationStatusProvidersListener);
111
			public void handleChange(ChangeEvent event) {
166
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
112
				handleUIChanged();
167
				.hasNext();) {
168
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
169
					.next();
170
			IObservableList targets = validationStatusProvider.getTargets();
171
			targets
172
					.addListChangeListener(validationStatusProviderTargetsListener);
173
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
174
				((IObservable) iter.next()).addChangeListener(uiChangeListener);
175
			}
113
			}
176
		}
114
		});
177
	}
115
	}
178
116
179
	/**
117
	/**
Lines 184-203 Link Here
184
		if (currentStatus != null) {
122
		if (currentStatus != null) {
185
			handleStatusChanged();
123
			handleStatusChanged();
186
		}
124
		}
187
		dbc.getValidationStatusProviders().removeListChangeListener(
188
				validationStatusProvidersListener);
189
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
190
				.hasNext();) {
191
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
192
					.next();
193
			IObservableList targets = validationStatusProvider.getTargets();
194
			targets
195
					.removeListChangeListener(validationStatusProviderTargetsListener);
196
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
197
				((IObservable) iter.next())
198
						.removeChangeListener(uiChangeListener);
199
			}
200
		}
201
	}
125
	}
202
126
203
	/**
127
	/**
Lines 298-323 Link Here
298
	public void dispose() {
222
	public void dispose() {
299
		aggregateStatus.dispose();
223
		aggregateStatus.dispose();
300
		if (!uiChanged) {
224
		if (!uiChanged) {
301
			for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
225
			targetsListener.dispose();
302
					.hasNext();) {
303
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
304
						.next();
305
				IObservableList targets = validationStatusProvider.getTargets();
306
				targets
307
						.removeListChangeListener(validationStatusProviderTargetsListener);
308
				for (Iterator iter = targets.iterator(); iter.hasNext();) {
309
					((IObservable) iter.next())
310
							.removeChangeListener(uiChangeListener);
311
				}
312
			}
313
			dbc.getValidationStatusProviders().removeListChangeListener(
314
					validationStatusProvidersListener);
315
		}
226
		}
316
		aggregateStatus = null;
227
		aggregateStatus = null;
317
		dbc = null;
228
		dbc = null;
318
		uiChangeListener = null;
319
		validationStatusProvidersListener = null;
320
		validationStatusProviderTargetsListener = null;
321
		dialogPage = null;
229
		dialogPage = null;
322
	}
230
	}
323
}
231
}

Return to bug 258967