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

Collapse All | Expand All

(-)src/org/eclipse/core/databinding/TargetsListener.java (+162 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 DataBindingContext context;
56
	private final List changeListeners = new ArrayList();
57
58
	private IChangeListener targetListener = new IChangeListener() {
59
		public void handleChange(ChangeEvent event) {
60
			Iterator iterator = changeListeners.iterator();
61
			while (iterator.hasNext()) {
62
				IChangeListener listener = (IChangeListener) iterator.next();
63
				listener.handleChange(event);
64
			}
65
		}
66
	};
67
	private IListChangeListener validationStatusProvidersListener = new IListChangeListener() {
68
		public void handleListChange(ListChangeEvent event) {
69
			ListDiff diff = event.diff;
70
			ListDiffEntry[] differences = diff.getDifferences();
71
			for (int i = 0; i < differences.length; i++) {
72
				ListDiffEntry listDiffEntry = differences[i];
73
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry
74
						.getElement();
75
				IObservableList targets = validationStatusProvider.getTargets();
76
				if (listDiffEntry.isAddition()) {
77
					targets.addListChangeListener(validationStatusProviderTargetsListener);
78
					for (Iterator it = targets.iterator(); it.hasNext();) {
79
						((IObservable) it.next()).addChangeListener(targetListener);
80
					}
81
				} else {
82
					targets.removeListChangeListener(validationStatusProviderTargetsListener);
83
					for (Iterator it = targets.iterator(); it.hasNext();) {
84
						((IObservable) it.next()).removeChangeListener(targetListener);
85
					}
86
				}
87
			}
88
		}
89
	};
90
	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
91
		public void handleListChange(ListChangeEvent event) {
92
			ListDiff diff = event.diff;
93
			ListDiffEntry[] differences = diff.getDifferences();
94
			for (int i = 0; i < differences.length; i++) {
95
				ListDiffEntry listDiffEntry = differences[i];
96
				IObservable target = (IObservable) listDiffEntry.getElement();
97
				if (listDiffEntry.isAddition()) {
98
					target.addChangeListener(targetListener);
99
				} else {
100
					target.removeChangeListener(targetListener);
101
				}
102
			}
103
		}
104
	};
105
106
	/**
107
	 * A TargetListener listens to changes of any target of any
108
	 * ValidationStatusProvider in the given context.
109
	 * 
110
	 * @param context
111
	 */
112
	public TargetsListener(DataBindingContext context) {
113
		this.context = context;
114
		IObservableList validationStatusProviders = context.getValidationStatusProviders();
115
		validationStatusProviders.addListChangeListener(validationStatusProvidersListener);
116
		for (Iterator iter = validationStatusProviders.iterator(); iter.hasNext();) {
117
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) iter.next();
118
			IObservableList targets = validationStatusProvider.getTargets();
119
			targets.addListChangeListener(validationStatusProviderTargetsListener);
120
			for (Iterator it = targets.iterator(); it.hasNext();) {
121
				((IObservable) it.next()).addChangeListener(targetListener);
122
			}
123
		}
124
	}
125
126
	/**
127
	 * Adds the {@link IChangeListener} to the list of target listeners.
128
	 * 
129
	 * @param listener
130
	 *            The IChangeListener that will be notified in case any target
131
	 *            changes.
132
	 * @since 1.2
133
	 */
134
	public final void addChangeListener(IChangeListener listener) {
135
		changeListeners.add(listener);
136
	}
137
138
	/**
139
	 * Removes the {@link IChangeListener} from the list of target listeners.
140
	 * 
141
	 * @param listener
142
	 *            The IChangeListener that should no longer be notified in case
143
	 *            any target changes.
144
	 * @since 1.2
145
	 */
146
	public final void removeChangeListener(IChangeListener listener) {
147
		changeListeners.remove(listener);
148
	}
149
150
	public void dispose() {
151
		IObservableList validationStatusProviders = context.getValidationStatusProviders();
152
		validationStatusProviders.removeListChangeListener(validationStatusProvidersListener);
153
		for (Iterator iter = validationStatusProviders.iterator(); iter.hasNext();) {
154
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) iter.next();
155
			IObservableList targets = validationStatusProvider.getTargets();
156
			targets.removeListChangeListener(validationStatusProviderTargetsListener);
157
			for (Iterator it = targets.iterator(); it.hasNext();) {
158
				((IObservable) it.next()).removeChangeListener(targetListener);
159
			}
160
		}
161
	}
162
}
(-)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