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

Collapse All | Expand All

(-)src/org/eclipse/jface/databinding/wizard/WizardPageSupport.java (-248 / +14 lines)
Lines 13-39 Link Here
13
 *******************************************************************************/
13
 *******************************************************************************/
14
package org.eclipse.jface.databinding.wizard;
14
package org.eclipse.jface.databinding.wizard;
15
15
16
import java.util.Iterator;
17
18
import org.eclipse.core.databinding.AggregateValidationStatus;
19
import org.eclipse.core.databinding.DataBindingContext;
16
import org.eclipse.core.databinding.DataBindingContext;
20
import org.eclipse.core.databinding.ValidationStatusProvider;
21
import org.eclipse.core.databinding.observable.ChangeEvent;
22
import org.eclipse.core.databinding.observable.IChangeListener;
23
import org.eclipse.core.databinding.observable.IObservable;
24
import org.eclipse.core.databinding.observable.list.IListChangeListener;
25
import org.eclipse.core.databinding.observable.list.IObservableList;
26
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
27
import org.eclipse.core.databinding.observable.list.ListDiff;
28
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
29
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
30
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
31
import org.eclipse.core.databinding.util.Policy;
32
import org.eclipse.core.runtime.AssertionFailedException;
33
import org.eclipse.core.runtime.IStatus;
17
import org.eclipse.core.runtime.IStatus;
34
import org.eclipse.core.runtime.MultiStatus;
18
import org.eclipse.jface.databinding.dialog.DialogPageSupport;
35
import org.eclipse.core.runtime.Status;
36
import org.eclipse.jface.dialogs.IMessageProvider;
37
import org.eclipse.jface.wizard.WizardPage;
19
import org.eclipse.jface.wizard.WizardPage;
38
20
39
/**
21
/**
Lines 42-56 Link Here
42
 * message accordingly.
24
 * message accordingly.
43
 * 
25
 * 
44
 * @noextend This class is not intended to be subclassed by clients.
26
 * @noextend This class is not intended to be subclassed by clients.
45
 *
27
 * 
46
 * @since 1.1
28
 * @since 1.1
47
 */
29
 */
48
public class WizardPageSupport {
30
public class WizardPageSupport extends DialogPageSupport {
49
31
	private WizardPageSupport(WizardPage wizardPage, DataBindingContext dbc) {
50
	private WizardPage wizardPage;
32
		super(wizardPage, dbc);
51
	private DataBindingContext dbc;
33
	}
52
	private AggregateValidationStatus aggregateStatus;
53
	private boolean uiChanged = false;
54
34
55
	/**
35
	/**
56
	 * Connect the validation result from the given data binding context to the
36
	 * Connect the validation result from the given data binding context to the
Lines 71-299 Link Here
71
		return new WizardPageSupport(wizardPage, dbc);
51
		return new WizardPageSupport(wizardPage, dbc);
72
	}
52
	}
73
53
74
	private WizardPageSupport(WizardPage wizardPage, DataBindingContext dbc) {
75
		this.wizardPage = wizardPage;
76
		this.dbc = dbc;
77
		init();
78
	}
79
80
	private IChangeListener uiChangeListener = new IChangeListener() {
81
		public void handleChange(ChangeEvent event) {
82
			handleUIChanged();
83
		}
84
	};
85
	private IListChangeListener validationStatusProvidersListener = new IListChangeListener() {
86
		public void handleListChange(ListChangeEvent event) {
87
			ListDiff diff = event.diff;
88
			ListDiffEntry[] differences = diff.getDifferences();
89
			for (int i = 0; i < differences.length; i++) {
90
				ListDiffEntry listDiffEntry = differences[i];
91
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry
92
						.getElement();
93
				IObservableList targets = validationStatusProvider.getTargets();
94
				if (listDiffEntry.isAddition()) {
95
					targets
96
							.addListChangeListener(validationStatusProviderTargetsListener);
97
					for (Iterator it = targets.iterator(); it.hasNext();) {
98
						((IObservable) it.next())
99
								.addChangeListener(uiChangeListener);
100
					}
101
				} else {
102
					targets
103
							.removeListChangeListener(validationStatusProviderTargetsListener);
104
					for (Iterator it = targets.iterator(); it.hasNext();) {
105
						((IObservable) it.next())
106
								.removeChangeListener(uiChangeListener);
107
					}
108
				}
109
			}
110
		}
111
	};
112
	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
113
		public void handleListChange(ListChangeEvent event) {
114
			ListDiff diff = event.diff;
115
			ListDiffEntry[] differences = diff.getDifferences();
116
			for (int i = 0; i < differences.length; i++) {
117
				ListDiffEntry listDiffEntry = differences[i];
118
				IObservable target = (IObservable) listDiffEntry.getElement();
119
				if (listDiffEntry.isAddition()) {
120
					target.addChangeListener(uiChangeListener);
121
				} else {
122
					target.removeChangeListener(uiChangeListener);
123
				}
124
			}
125
		}
126
	};
127
	private IStatus currentStatus;
128
129
	protected void init() {
130
		aggregateStatus = new AggregateValidationStatus(dbc
131
				.getValidationStatusProviders(),
132
				AggregateValidationStatus.MAX_SEVERITY);
133
		aggregateStatus.addValueChangeListener(new IValueChangeListener() {
134
			public void handleValueChange(ValueChangeEvent event) {
135
136
				currentStatus = (IStatus) event.diff.getNewValue();
137
				handleStatusChanged();
138
			}
139
		});
140
		currentStatus = (IStatus) aggregateStatus.getValue();
141
		handleStatusChanged();
142
		dbc.getValidationStatusProviders().addListChangeListener(
143
				validationStatusProvidersListener);
144
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
145
				.hasNext();) {
146
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
147
					.next();
148
			IObservableList targets = validationStatusProvider.getTargets();
149
			targets
150
					.addListChangeListener(validationStatusProviderTargetsListener);
151
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
152
				((IObservable) iter.next()).addChangeListener(uiChangeListener);
153
			}
154
		}
155
	}
156
157
	protected void handleUIChanged() {
158
		uiChanged = true;
159
		if (currentStatus != null) {
160
			handleStatusChanged();
161
		}
162
		dbc.getValidationStatusProviders().removeListChangeListener(
163
				validationStatusProvidersListener);
164
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
165
				.hasNext();) {
166
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
167
					.next();
168
			IObservableList targets = validationStatusProvider.getTargets();
169
			targets
170
					.removeListChangeListener(validationStatusProviderTargetsListener);
171
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
172
				((IObservable) iter.next())
173
						.removeChangeListener(uiChangeListener);
174
			}
175
		}
176
	}
177
178
	protected void handleStatusChanged() {
54
	protected void handleStatusChanged() {
179
		if (currentStatus != null
55
		super.handleStatusChanged();
180
				&& currentStatus.getSeverity() == IStatus.ERROR) {
56
		boolean pageComplete = true;
181
			wizardPage.setPageComplete(false);
57
		if (currentStatus != null) {
182
			wizardPage.setMessage(null);
58
			if (currentStatus.getSeverity() == IStatus.ERROR)
183
			wizardPage.setErrorMessage(uiChanged ? currentStatus.getMessage()
59
				pageComplete = false;
184
					: null);
60
			if ((currentStatus.getSeverity() & IStatus.CANCEL) != 0)
185
			if (currentStatusHasException()) {
61
				pageComplete = false;
186
				handleStatusException();
187
			}
188
		} else if (currentStatus != null
189
				&& currentStatus.getSeverity() != IStatus.OK) {
190
			int severity = currentStatus.getSeverity();
191
			wizardPage.setPageComplete((severity & IStatus.CANCEL) != 0);
192
			int type;
193
			switch (severity) {
194
			case IStatus.OK:
195
				type = IMessageProvider.NONE;
196
				break;
197
			case IStatus.CANCEL:
198
				type = IMessageProvider.NONE;
199
				break;
200
			case IStatus.INFO:
201
				type = IMessageProvider.INFORMATION;
202
				break;
203
			case IStatus.WARNING:
204
				type = IMessageProvider.WARNING;
205
				break;
206
			case IStatus.ERROR:
207
				type = IMessageProvider.ERROR;
208
				break;
209
			default:
210
				throw new AssertionFailedException(
211
						"incomplete switch statement"); //$NON-NLS-1$
212
			}
213
			wizardPage.setErrorMessage(null);
214
			wizardPage.setMessage(currentStatus.getMessage(), type);
215
		} else {
216
			wizardPage.setPageComplete(true);
217
			wizardPage.setMessage(null);
218
			wizardPage.setErrorMessage(null);
219
		}
220
	}
221
222
	private boolean currentStatusHasException() {
223
		boolean hasException = false;
224
		if (currentStatus.getException() != null) {
225
			hasException = true;
226
		}
227
		if (currentStatus instanceof MultiStatus) {
228
			MultiStatus multiStatus = (MultiStatus) currentStatus;
229
230
			for (int i = 0; i < multiStatus.getChildren().length; i++) {
231
				IStatus status = multiStatus.getChildren()[i];
232
				if (status.getException() != null) {
233
					hasException = true;
234
					break;
235
				}
236
			}
237
		}
238
		return hasException;
239
	}
240
241
	/**
242
	 * This is called when a Override to provide custom exception handling and
243
	 * reporting.
244
	 */
245
	protected void handleStatusException() {
246
		if (currentStatus.getException() != null) {
247
			logThrowable(currentStatus.getException());
248
		} else if (currentStatus instanceof MultiStatus) {
249
			MultiStatus multiStatus = (MultiStatus) currentStatus;
250
			for (int i = 0; i < multiStatus.getChildren().length; i++) {
251
				IStatus status = multiStatus.getChildren()[i];
252
				if (status.getException() != null) {
253
					logThrowable(status.getException());
254
				}
255
			}
256
		}
257
	}
258
259
	private void logThrowable(Throwable throwable) {
260
		Policy
261
				.getLog()
262
				.log(
263
						new Status(
264
								IStatus.ERROR,
265
								Policy.JFACE_DATABINDING,
266
								IStatus.OK,
267
								"Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$
268
	}
269
270
	/**
271
	 * Disposes of this wizard page support object, removing any listeners it
272
	 * may have attached.
273
	 */
274
	public void dispose() {
275
		aggregateStatus.dispose();
276
		if (!uiChanged) {
277
			for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
278
					.hasNext();) {
279
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
280
						.next();
281
				IObservableList targets = validationStatusProvider.getTargets();
282
				targets
283
						.removeListChangeListener(validationStatusProviderTargetsListener);
284
				for (Iterator iter = targets.iterator(); iter.hasNext();) {
285
					((IObservable) iter.next())
286
							.removeChangeListener(uiChangeListener);
287
				}
288
			}
289
			dbc.getValidationStatusProviders().removeListChangeListener(
290
					validationStatusProvidersListener);
291
		}
62
		}
292
		aggregateStatus = null;
63
		((WizardPage) getDialogPage()).setPageComplete(pageComplete);
293
		dbc = null;
294
		uiChangeListener = null;
295
		validationStatusProvidersListener = null;
296
		validationStatusProviderTargetsListener = null;
297
		wizardPage = null;
298
	}
64
	}
299
}
65
}
(-)src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java (+294 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.jface.databinding.dialog;
13
14
import java.util.Iterator;
15
16
import org.eclipse.core.databinding.AggregateValidationStatus;
17
import org.eclipse.core.databinding.DataBindingContext;
18
import org.eclipse.core.databinding.ValidationStatusProvider;
19
import org.eclipse.core.databinding.observable.ChangeEvent;
20
import org.eclipse.core.databinding.observable.IChangeListener;
21
import org.eclipse.core.databinding.observable.IObservable;
22
import org.eclipse.core.databinding.observable.list.IListChangeListener;
23
import org.eclipse.core.databinding.observable.list.IObservableList;
24
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
25
import org.eclipse.core.databinding.observable.list.ListDiff;
26
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
27
import org.eclipse.core.databinding.observable.value.IObservableValue;
28
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
29
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
30
import org.eclipse.core.databinding.util.Policy;
31
import org.eclipse.core.runtime.AssertionFailedException;
32
import org.eclipse.core.runtime.IStatus;
33
import org.eclipse.core.runtime.MultiStatus;
34
import org.eclipse.core.runtime.Status;
35
import org.eclipse.jface.dialogs.DialogPage;
36
import org.eclipse.jface.dialogs.IMessageProvider;
37
import org.eclipse.jface.wizard.WizardPage;
38
39
/**
40
 * @since 3.3
41
 *
42
 */
43
public class DialogPageSupport {
44
	private DialogPage dialogPage;
45
	private DataBindingContext dbc;
46
	private IObservableValue aggregateStatus;
47
	private boolean uiChanged = false;
48
	private IChangeListener uiChangeListener = new IChangeListener() {
49
			public void handleChange(ChangeEvent event) {
50
				handleUIChanged();
51
			}
52
		};
53
	private IListChangeListener validationStatusProvidersListener = new IListChangeListener() {
54
			public void handleListChange(ListChangeEvent event) {
55
				ListDiff diff = event.diff;
56
				ListDiffEntry[] differences = diff.getDifferences();
57
				for (int i = 0; i < differences.length; i++) {
58
					ListDiffEntry listDiffEntry = differences[i];
59
					ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry
60
							.getElement();
61
					IObservableList targets = validationStatusProvider.getTargets();
62
					if (listDiffEntry.isAddition()) {
63
						targets
64
								.addListChangeListener(validationStatusProviderTargetsListener);
65
						for (Iterator it = targets.iterator(); it.hasNext();) {
66
							((IObservable) it.next())
67
									.addChangeListener(uiChangeListener);
68
						}
69
					} else {
70
						targets
71
								.removeListChangeListener(validationStatusProviderTargetsListener);
72
						for (Iterator it = targets.iterator(); it.hasNext();) {
73
							((IObservable) it.next())
74
									.removeChangeListener(uiChangeListener);
75
						}
76
					}
77
				}
78
			}
79
		};
80
	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
81
			public void handleListChange(ListChangeEvent event) {
82
				ListDiff diff = event.diff;
83
				ListDiffEntry[] differences = diff.getDifferences();
84
				for (int i = 0; i < differences.length; i++) {
85
					ListDiffEntry listDiffEntry = differences[i];
86
					IObservable target = (IObservable) listDiffEntry.getElement();
87
					if (listDiffEntry.isAddition()) {
88
						target.addChangeListener(uiChangeListener);
89
					} else {
90
						target.removeChangeListener(uiChangeListener);
91
					}
92
				}
93
			}
94
		};
95
	protected IStatus currentStatus;
96
97
	protected DialogPageSupport(DialogPage dialogPage, DataBindingContext dbc) {
98
		this.dialogPage = dialogPage;
99
		this.dbc = dbc;
100
		init();
101
	}
102
103
	/**
104
	 * Connect the validation result from the given data binding context to the
105
	 * given wizard page. Upon creation, the wizard page support will use the
106
	 * context's validation result to determine whether the page is complete.
107
	 * The page's error message will not be set at this time ensuring that the
108
	 * wizard page does not show an error right away. Upon any validation result
109
	 * change, {@link WizardPage#setPageComplete(boolean)} will be called
110
	 * reflecting the new validation result, and the wizard page's error message
111
	 * will be updated according to the current validation result.
112
	 * 
113
	 * @param wizardPage
114
	 * @param dbc
115
	 * @return an instance of WizardPageSupport
116
	 */
117
	public static DialogPageSupport create(DialogPage wizardPage,
118
			DataBindingContext dbc) {
119
		return new DialogPageSupport(wizardPage, dbc);
120
	}
121
122
	protected DialogPage getDialogPage() {
123
		return dialogPage;
124
	}
125
126
	protected void init() {
127
		aggregateStatus = new AggregateValidationStatus(dbc
128
				.getValidationStatusProviders(),
129
				AggregateValidationStatus.MAX_SEVERITY);
130
		aggregateStatus.addValueChangeListener(new IValueChangeListener() {
131
			public void handleValueChange(ValueChangeEvent event) {
132
	
133
				currentStatus = (IStatus) event.diff.getNewValue();
134
				handleStatusChanged();
135
			}
136
		});
137
		currentStatus = (IStatus) aggregateStatus.getValue();
138
		handleStatusChanged();
139
		dbc.getValidationStatusProviders().addListChangeListener(
140
				validationStatusProvidersListener);
141
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
142
				.hasNext();) {
143
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
144
					.next();
145
			IObservableList targets = validationStatusProvider.getTargets();
146
			targets
147
					.addListChangeListener(validationStatusProviderTargetsListener);
148
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
149
				((IObservable) iter.next()).addChangeListener(uiChangeListener);
150
			}
151
		}
152
	}
153
154
	protected void handleUIChanged() {
155
		uiChanged = true;
156
		if (currentStatus != null) {
157
			handleStatusChanged();
158
		}
159
		dbc.getValidationStatusProviders().removeListChangeListener(
160
				validationStatusProvidersListener);
161
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
162
				.hasNext();) {
163
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
164
					.next();
165
			IObservableList targets = validationStatusProvider.getTargets();
166
			targets
167
					.removeListChangeListener(validationStatusProviderTargetsListener);
168
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
169
				((IObservable) iter.next())
170
						.removeChangeListener(uiChangeListener);
171
			}
172
		}
173
	}
174
175
	protected void handleStatusChanged() {
176
		if (currentStatus != null
177
				&& currentStatus.getSeverity() == IStatus.ERROR) {
178
			dialogPage.setMessage(null);
179
			dialogPage.setErrorMessage(uiChanged ? currentStatus.getMessage()
180
					: null);
181
			if (currentStatusHasException()) {
182
				handleStatusException();
183
			}
184
		} else if (currentStatus != null
185
				&& currentStatus.getSeverity() != IStatus.OK) {
186
			int severity = currentStatus.getSeverity();
187
			int type;
188
			switch (severity) {
189
			case IStatus.OK:
190
				type = IMessageProvider.NONE;
191
				break;
192
			case IStatus.CANCEL:
193
				type = IMessageProvider.NONE;
194
				break;
195
			case IStatus.INFO:
196
				type = IMessageProvider.INFORMATION;
197
				break;
198
			case IStatus.WARNING:
199
				type = IMessageProvider.WARNING;
200
				break;
201
			case IStatus.ERROR:
202
				type = IMessageProvider.ERROR;
203
				break;
204
			default:
205
				throw new AssertionFailedException(
206
						"incomplete switch statement"); //$NON-NLS-1$
207
			}
208
			dialogPage.setErrorMessage(null);
209
			dialogPage.setMessage(currentStatus.getMessage(), type);
210
		} else {
211
			dialogPage.setMessage(null);
212
			dialogPage.setErrorMessage(null);
213
		}
214
	}
215
216
	private boolean currentStatusHasException() {
217
		boolean hasException = false;
218
		if (currentStatus.getException() != null) {
219
			hasException = true;
220
		}
221
		if (currentStatus instanceof MultiStatus) {
222
			MultiStatus multiStatus = (MultiStatus) currentStatus;
223
	
224
			for (int i = 0; i < multiStatus.getChildren().length; i++) {
225
				IStatus status = multiStatus.getChildren()[i];
226
				if (status.getException() != null) {
227
					hasException = true;
228
					break;
229
				}
230
			}
231
		}
232
		return hasException;
233
	}
234
235
	/**
236
	 * This is called when a Override to provide custom exception handling and
237
	 * reporting.
238
	 */
239
	protected void handleStatusException() {
240
		if (currentStatus.getException() != null) {
241
			logThrowable(currentStatus.getException());
242
		} else if (currentStatus instanceof MultiStatus) {
243
			MultiStatus multiStatus = (MultiStatus) currentStatus;
244
			for (int i = 0; i < multiStatus.getChildren().length; i++) {
245
				IStatus status = multiStatus.getChildren()[i];
246
				if (status.getException() != null) {
247
					logThrowable(status.getException());
248
				}
249
			}
250
		}
251
	}
252
253
	private void logThrowable(Throwable throwable) {
254
		Policy
255
				.getLog()
256
				.log(
257
						new Status(
258
								IStatus.ERROR,
259
								Policy.JFACE_DATABINDING,
260
								IStatus.OK,
261
								"Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$
262
	}
263
264
	/**
265
	 * Disposes of this wizard page support object, removing any listeners it
266
	 * may have attached.
267
	 */
268
	public void dispose() {
269
		aggregateStatus.dispose();
270
		if (!uiChanged) {
271
			for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
272
					.hasNext();) {
273
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
274
						.next();
275
				IObservableList targets = validationStatusProvider.getTargets();
276
				targets
277
						.removeListChangeListener(validationStatusProviderTargetsListener);
278
				for (Iterator iter = targets.iterator(); iter.hasNext();) {
279
					((IObservable) iter.next())
280
							.removeChangeListener(uiChangeListener);
281
				}
282
			}
283
			dbc.getValidationStatusProviders().removeListChangeListener(
284
					validationStatusProvidersListener);
285
		}
286
		aggregateStatus = null;
287
		dbc = null;
288
		uiChangeListener = null;
289
		validationStatusProvidersListener = null;
290
		validationStatusProviderTargetsListener = null;
291
		dialogPage = null;
292
	}
293
294
}
(-)src/org/eclipse/jface/databinding/dialog/TitleAreaDialogSupport.java (+293 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2008 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.jface.databinding.dialog;
13
14
import java.util.Iterator;
15
16
import org.eclipse.core.databinding.AggregateValidationStatus;
17
import org.eclipse.core.databinding.DataBindingContext;
18
import org.eclipse.core.databinding.ValidationStatusProvider;
19
import org.eclipse.core.databinding.observable.ChangeEvent;
20
import org.eclipse.core.databinding.observable.IChangeListener;
21
import org.eclipse.core.databinding.observable.IObservable;
22
import org.eclipse.core.databinding.observable.list.IListChangeListener;
23
import org.eclipse.core.databinding.observable.list.IObservableList;
24
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
25
import org.eclipse.core.databinding.observable.list.ListDiff;
26
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
27
import org.eclipse.core.databinding.observable.value.IObservableValue;
28
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
29
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
30
import org.eclipse.core.databinding.util.Policy;
31
import org.eclipse.core.runtime.AssertionFailedException;
32
import org.eclipse.core.runtime.IStatus;
33
import org.eclipse.core.runtime.MultiStatus;
34
import org.eclipse.core.runtime.Status;
35
import org.eclipse.jface.dialogs.IMessageProvider;
36
import org.eclipse.jface.dialogs.TitleAreaDialog;
37
import org.eclipse.jface.wizard.WizardPage;
38
39
/**
40
 * @since 3.3
41
 * 
42
 */
43
public class TitleAreaDialogSupport {
44
	private TitleAreaDialog dialog;
45
	private DataBindingContext dbc;
46
	private IObservableValue aggregateStatus;
47
	private boolean uiChanged = false;
48
	private IChangeListener uiChangeListener = new IChangeListener() {
49
		public void handleChange(ChangeEvent event) {
50
			handleUIChanged();
51
		}
52
	};
53
	private IListChangeListener validationStatusProvidersListener = new IListChangeListener() {
54
		public void handleListChange(ListChangeEvent event) {
55
			ListDiff diff = event.diff;
56
			ListDiffEntry[] differences = diff.getDifferences();
57
			for (int i = 0; i < differences.length; i++) {
58
				ListDiffEntry listDiffEntry = differences[i];
59
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry
60
						.getElement();
61
				IObservableList targets = validationStatusProvider.getTargets();
62
				if (listDiffEntry.isAddition()) {
63
					targets
64
							.addListChangeListener(validationStatusProviderTargetsListener);
65
					for (Iterator it = targets.iterator(); it.hasNext();) {
66
						((IObservable) it.next())
67
								.addChangeListener(uiChangeListener);
68
					}
69
				} else {
70
					targets
71
							.removeListChangeListener(validationStatusProviderTargetsListener);
72
					for (Iterator it = targets.iterator(); it.hasNext();) {
73
						((IObservable) it.next())
74
								.removeChangeListener(uiChangeListener);
75
					}
76
				}
77
			}
78
		}
79
	};
80
	private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() {
81
		public void handleListChange(ListChangeEvent event) {
82
			ListDiff diff = event.diff;
83
			ListDiffEntry[] differences = diff.getDifferences();
84
			for (int i = 0; i < differences.length; i++) {
85
				ListDiffEntry listDiffEntry = differences[i];
86
				IObservable target = (IObservable) listDiffEntry.getElement();
87
				if (listDiffEntry.isAddition()) {
88
					target.addChangeListener(uiChangeListener);
89
				} else {
90
					target.removeChangeListener(uiChangeListener);
91
				}
92
			}
93
		}
94
	};
95
	protected IStatus currentStatus;
96
97
	protected TitleAreaDialogSupport(TitleAreaDialog dialogPage,
98
			DataBindingContext dbc) {
99
		this.dialog = dialogPage;
100
		this.dbc = dbc;
101
		init();
102
	}
103
104
	/**
105
	 * Connect the validation result from the given data binding context to the
106
	 * given wizard page. Upon creation, the wizard page support will use the
107
	 * context's validation result to determine whether the page is complete.
108
	 * The page's error message will not be set at this time ensuring that the
109
	 * wizard page does not show an error right away. Upon any validation result
110
	 * change, {@link WizardPage#setPageComplete(boolean)} will be called
111
	 * reflecting the new validation result, and the wizard page's error message
112
	 * will be updated according to the current validation result.
113
	 * 
114
	 * @param wizardPage
115
	 * @param dbc
116
	 * @return an instance of WizardPageSupport
117
	 */
118
	public static TitleAreaDialogSupport create(TitleAreaDialog wizardPage,
119
			DataBindingContext dbc) {
120
		return new TitleAreaDialogSupport(wizardPage, dbc);
121
	}
122
123
	protected void init() {
124
		aggregateStatus = new AggregateValidationStatus(dbc
125
				.getValidationStatusProviders(),
126
				AggregateValidationStatus.MAX_SEVERITY);
127
		aggregateStatus.addValueChangeListener(new IValueChangeListener() {
128
			public void handleValueChange(ValueChangeEvent event) {
129
130
				currentStatus = (IStatus) event.diff.getNewValue();
131
				handleStatusChanged();
132
			}
133
		});
134
		currentStatus = (IStatus) aggregateStatus.getValue();
135
		handleStatusChanged();
136
		dbc.getValidationStatusProviders().addListChangeListener(
137
				validationStatusProvidersListener);
138
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
139
				.hasNext();) {
140
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
141
					.next();
142
			IObservableList targets = validationStatusProvider.getTargets();
143
			targets
144
					.addListChangeListener(validationStatusProviderTargetsListener);
145
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
146
				((IObservable) iter.next()).addChangeListener(uiChangeListener);
147
			}
148
		}
149
	}
150
151
	protected void handleUIChanged() {
152
		uiChanged = true;
153
		if (currentStatus != null) {
154
			handleStatusChanged();
155
		}
156
		dbc.getValidationStatusProviders().removeListChangeListener(
157
				validationStatusProvidersListener);
158
		for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
159
				.hasNext();) {
160
			ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
161
					.next();
162
			IObservableList targets = validationStatusProvider.getTargets();
163
			targets
164
					.removeListChangeListener(validationStatusProviderTargetsListener);
165
			for (Iterator iter = targets.iterator(); iter.hasNext();) {
166
				((IObservable) iter.next())
167
						.removeChangeListener(uiChangeListener);
168
			}
169
		}
170
	}
171
172
	protected void handleStatusChanged() {
173
		if (dialog.getShell() == null || dialog.getShell().isDisposed())
174
			return;
175
		if (currentStatus != null
176
				&& currentStatus.getSeverity() == IStatus.ERROR) {
177
			dialog.setMessage(null);
178
			dialog.setErrorMessage(uiChanged ? currentStatus.getMessage()
179
					: null);
180
			if (currentStatusHasException()) {
181
				handleStatusException();
182
			}
183
		} else if (currentStatus != null
184
				&& currentStatus.getSeverity() != IStatus.OK) {
185
			int severity = currentStatus.getSeverity();
186
			int type;
187
			switch (severity) {
188
			case IStatus.OK:
189
				type = IMessageProvider.NONE;
190
				break;
191
			case IStatus.CANCEL:
192
				type = IMessageProvider.NONE;
193
				break;
194
			case IStatus.INFO:
195
				type = IMessageProvider.INFORMATION;
196
				break;
197
			case IStatus.WARNING:
198
				type = IMessageProvider.WARNING;
199
				break;
200
			case IStatus.ERROR:
201
				type = IMessageProvider.ERROR;
202
				break;
203
			default:
204
				throw new AssertionFailedException(
205
						"incomplete switch statement"); //$NON-NLS-1$
206
			}
207
			dialog.setErrorMessage(null);
208
			dialog.setMessage(currentStatus.getMessage(), type);
209
		} else {
210
			dialog.setMessage(null);
211
			dialog.setErrorMessage(null);
212
		}
213
	}
214
215
	private boolean currentStatusHasException() {
216
		boolean hasException = false;
217
		if (currentStatus.getException() != null) {
218
			hasException = true;
219
		}
220
		if (currentStatus instanceof MultiStatus) {
221
			MultiStatus multiStatus = (MultiStatus) currentStatus;
222
223
			for (int i = 0; i < multiStatus.getChildren().length; i++) {
224
				IStatus status = multiStatus.getChildren()[i];
225
				if (status.getException() != null) {
226
					hasException = true;
227
					break;
228
				}
229
			}
230
		}
231
		return hasException;
232
	}
233
234
	/**
235
	 * This is called when a Override to provide custom exception handling and
236
	 * reporting.
237
	 */
238
	protected void handleStatusException() {
239
		if (currentStatus.getException() != null) {
240
			logThrowable(currentStatus.getException());
241
		} else if (currentStatus instanceof MultiStatus) {
242
			MultiStatus multiStatus = (MultiStatus) currentStatus;
243
			for (int i = 0; i < multiStatus.getChildren().length; i++) {
244
				IStatus status = multiStatus.getChildren()[i];
245
				if (status.getException() != null) {
246
					logThrowable(status.getException());
247
				}
248
			}
249
		}
250
	}
251
252
	private void logThrowable(Throwable throwable) {
253
		Policy
254
				.getLog()
255
				.log(
256
						new Status(
257
								IStatus.ERROR,
258
								Policy.JFACE_DATABINDING,
259
								IStatus.OK,
260
								"Unhandled exception: " + throwable.getMessage(), throwable)); //$NON-NLS-1$
261
	}
262
263
	/**
264
	 * Disposes of this wizard page support object, removing any listeners it
265
	 * may have attached.
266
	 */
267
	public void dispose() {
268
		aggregateStatus.dispose();
269
		if (!uiChanged) {
270
			for (Iterator it = dbc.getValidationStatusProviders().iterator(); it
271
					.hasNext();) {
272
				ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it
273
						.next();
274
				IObservableList targets = validationStatusProvider.getTargets();
275
				targets
276
						.removeListChangeListener(validationStatusProviderTargetsListener);
277
				for (Iterator iter = targets.iterator(); iter.hasNext();) {
278
					((IObservable) iter.next())
279
							.removeChangeListener(uiChangeListener);
280
				}
281
			}
282
			dbc.getValidationStatusProviders().removeListChangeListener(
283
					validationStatusProvidersListener);
284
		}
285
		aggregateStatus = null;
286
		dbc = null;
287
		uiChangeListener = null;
288
		validationStatusProvidersListener = null;
289
		validationStatusProviderTargetsListener = null;
290
		dialog = null;
291
	}
292
293
}
(-)src/org/eclipse/jface/databinding/preference/PreferencePageSupport.java (+69 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007, 2008 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
 *     Boris Bokowski - bug 218269
11
 *     Matthew Hall - bug 218269
12
 *     Ashley Cambrell - bug 199179 
13
 *******************************************************************************/
14
package org.eclipse.jface.databinding.preference;
15
16
import org.eclipse.core.databinding.DataBindingContext;
17
import org.eclipse.core.runtime.IStatus;
18
import org.eclipse.jface.databinding.dialog.DialogPageSupport;
19
import org.eclipse.jface.preference.PreferencePage;
20
21
/**
22
 * Connects the validation result from the given data binding context to the
23
 * given preference page, updating the preference page's valid state and its
24
 * error message accordingly.
25
 * 
26
 * @noextend This class is not intended to be subclassed by clients.
27
 * 
28
 * @since 1.1
29
 */
30
public class PreferencePageSupport extends DialogPageSupport {
31
	private PreferencePage preferencePage;
32
33
	private PreferencePageSupport(PreferencePage preferencePage,
34
			DataBindingContext dbc) {
35
		super(preferencePage, dbc);
36
		this.preferencePage = preferencePage;
37
	}
38
39
	/**
40
	 * Connect the validation result from the given data binding context to the
41
	 * given preference page. Upon creation, the preference page support will
42
	 * use the context's validation result to determine whether the page is
43
	 * valid. The page's error message will not be set at this time ensuring
44
	 * that the preference page does not show an error right away. Upon any
45
	 * validation result change, {@link PreferencePage#setValid(boolean)} will
46
	 * be called reflecting the new validation result, and the preference page's
47
	 * error message will be updated according to the current validation result.
48
	 * 
49
	 * @param preferencePage
50
	 * @param dbc
51
	 * @return an instance of PreferencePageSupport
52
	 */
53
	public static PreferencePageSupport create(PreferencePage preferencePage,
54
			DataBindingContext dbc) {
55
		return new PreferencePageSupport(preferencePage, dbc);
56
	}
57
58
	protected void handleStatusChanged() {
59
		super.handleStatusChanged();
60
		boolean valid = true;
61
		if (currentStatus != null) {
62
			if (currentStatus.getSeverity() == IStatus.ERROR)
63
				valid = false;
64
			if ((currentStatus.getSeverity() & IStatus.CANCEL) != 0)
65
				valid = false;
66
		}
67
		preferencePage.setValid(valid);
68
	}
69
}

Return to bug 239900