Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 247818 | Differences between
and this patch

Collapse All | Expand All

(-)Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchStatusDialogManager.java (-1 / +19 lines)
Lines 92-97 Link Here
92
import org.eclipse.ui.internal.progress.ProgressManagerUtil;
92
import org.eclipse.ui.internal.progress.ProgressManagerUtil;
93
import org.eclipse.ui.internal.progress.ProgressMessages;
93
import org.eclipse.ui.internal.progress.ProgressMessages;
94
import org.eclipse.ui.internal.statushandlers.DefaultDetailsArea;
94
import org.eclipse.ui.internal.statushandlers.DefaultDetailsArea;
95
import org.eclipse.ui.internal.statushandlers.IStatusDialogListener;
95
import org.eclipse.ui.internal.statushandlers.StackTraceSupportArea;
96
import org.eclipse.ui.internal.statushandlers.StackTraceSupportArea;
96
import org.eclipse.ui.progress.IProgressConstants;
97
import org.eclipse.ui.progress.IProgressConstants;
97
98
Lines 222-227 Link Here
222
	 */
223
	 */
223
	private class InternalDialog extends TrayDialog {
224
	private class InternalDialog extends TrayDialog {
224
225
226
		/* (non-Javadoc)
227
		 * @see org.eclipse.jface.dialogs.TrayDialog#close()
228
		 */
229
		public boolean close() {
230
			boolean result = super.close();
231
			if (listener != null && !modalitySwitch) {
232
				listener.statusDialogClosed();
233
			}
234
			return result;
235
		}
236
225
		private WorkbenchStatusDialogManager statusDialog;
237
		private WorkbenchStatusDialogManager statusDialog;
226
238
227
		/**
239
		/**
Lines 1006-1011 Link Here
1006
	 */
1018
	 */
1007
	private Composite titleArea;
1019
	private Composite titleArea;
1008
1020
1021
	private IStatusDialogListener listener;
1022
1009
	/**
1023
	/**
1010
	 * Creates workbench status dialog.
1024
	 * Creates workbench status dialog.
1011
	 * 
1025
	 * 
Lines 1659-1665 Link Here
1659
	/**
1673
	/**
1660
	 * Returns the shell of the dialog.
1674
	 * Returns the shell of the dialog.
1661
	 */
1675
	 */
1662
	Shell getShell() {
1676
	private Shell getShell() {
1663
		if (this.dialog == null) return null;
1677
		if (this.dialog == null) return null;
1664
		return this.dialog.getShell();
1678
		return this.dialog.getShell();
1665
	}
1679
	}
Lines 2196-2199 Link Here
2196
		}
2210
		}
2197
		titleArea.layout();
2211
		titleArea.layout();
2198
	}
2212
	}
2213
	
2214
	void setStatusDialogListener(IStatusDialogListener listener){
2215
		this.listener = listener;
2216
	}
2199
}
2217
}
(-)Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java (-6 / +18 lines)
Lines 14-23 Link Here
14
import org.eclipse.core.runtime.IStatus;
14
import org.eclipse.core.runtime.IStatus;
15
import org.eclipse.core.runtime.Status;
15
import org.eclipse.core.runtime.Status;
16
import org.eclipse.swt.widgets.Display;
16
import org.eclipse.swt.widgets.Display;
17
import org.eclipse.swt.widgets.Shell;
18
import org.eclipse.ui.PlatformUI;
17
import org.eclipse.ui.PlatformUI;
19
import org.eclipse.ui.application.WorkbenchAdvisor;
18
import org.eclipse.ui.application.WorkbenchAdvisor;
20
import org.eclipse.ui.internal.WorkbenchPlugin;
19
import org.eclipse.ui.internal.WorkbenchPlugin;
20
import org.eclipse.ui.internal.statushandlers.IStatusDialogListener;
21
21
22
/**
22
/**
23
 * This is a default workbench error handler.
23
 * This is a default workbench error handler.
Lines 26-31 Link Here
26
 * @since 3.3
26
 * @since 3.3
27
 */
27
 */
28
public class WorkbenchErrorHandler extends AbstractStatusHandler {
28
public class WorkbenchErrorHandler extends AbstractStatusHandler {
29
	
30
	private boolean dialogClosed = false;
31
	private IStatusDialogListener listener = new IStatusDialogListener(){
32
33
		public void statusDialogClosed() {
34
			dialogClosed = true;
35
		}
36
		
37
	};
29
38
30
	private WorkbenchStatusDialogManager statusDialog;
39
	private WorkbenchStatusDialogManager statusDialog;
31
40
Lines 110-119 Link Here
110
		getStatusDialogManager().addStatusAdapter(statusAdapter, block);
119
		getStatusDialogManager().addStatusAdapter(statusAdapter, block);
111
120
112
		if (block) {
121
		if (block) {
113
			Shell shell;
122
			// this variable will be set to true if and only if user closes the
114
			while ((shell = getStatusDialogManager().getShell()) != null
123
			// dialog
115
					&& !getStatusDialogManager().getShell().isDisposed()) {
124
			dialogClosed = false;
116
				if (!shell.getDisplay().readAndDispatch()) {
125
			while (!dialogClosed) {
126
				if (!Display.getDefault().readAndDispatch()) {
117
					Thread.yield();
127
					Thread.yield();
118
				}
128
				}
119
			}
129
			}
Lines 124-131 Link Here
124
	 * This method returns current {@link WorkbenchStatusDialogManager}.
134
	 * This method returns current {@link WorkbenchStatusDialogManager}.
125
	 * 
135
	 * 
126
	 * @return current {@link WorkbenchStatusDialogManager}
136
	 * @return current {@link WorkbenchStatusDialogManager}
137
	 * @noreference This method is not intended to be referenced by clients.
127
	 */
138
	 */
128
	private WorkbenchStatusDialogManager getStatusDialogManager() {
139
	public WorkbenchStatusDialogManager getStatusDialogManager() {
129
		if (statusDialog == null) {
140
		if (statusDialog == null) {
130
			initStatusDialogManager();
141
			initStatusDialogManager();
131
		}
142
		}
Lines 159-163 Link Here
159
	private void initStatusDialogManager() {
170
	private void initStatusDialogManager() {
160
		statusDialog = new WorkbenchStatusDialogManager(null);
171
		statusDialog = new WorkbenchStatusDialogManager(null);
161
		configureStatusDialog(statusDialog);
172
		configureStatusDialog(statusDialog);
173
		statusDialog.setStatusDialogListener(listener);
162
	}
174
	}
163
}
175
}
(-)Eclipse (+20 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.ui.internal.statushandlers;
13
14
/**
15
 * This interface allows for listening to dialog state changes.
16
 * @since 3.4
17
 */
18
public interface IStatusDialogListener {
19
	public void statusDialogClosed();
20
}
(-)Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusDialogManagerTest.java (-1 / +111 lines)
Lines 31-36 Link Here
31
import org.eclipse.swt.widgets.Button;
31
import org.eclipse.swt.widgets.Button;
32
import org.eclipse.swt.widgets.Composite;
32
import org.eclipse.swt.widgets.Composite;
33
import org.eclipse.swt.widgets.Control;
33
import org.eclipse.swt.widgets.Control;
34
import org.eclipse.swt.widgets.Display;
34
import org.eclipse.swt.widgets.Event;
35
import org.eclipse.swt.widgets.Event;
35
import org.eclipse.swt.widgets.Label;
36
import org.eclipse.swt.widgets.Label;
36
import org.eclipse.swt.widgets.Shell;
37
import org.eclipse.swt.widgets.Shell;
Lines 42-47 Link Here
42
import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider;
43
import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider;
43
import org.eclipse.ui.statushandlers.IStatusAdapterConstants;
44
import org.eclipse.ui.statushandlers.IStatusAdapterConstants;
44
import org.eclipse.ui.statushandlers.StatusAdapter;
45
import org.eclipse.ui.statushandlers.StatusAdapter;
46
import org.eclipse.ui.statushandlers.StatusManager;
47
import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;
45
import org.eclipse.ui.statushandlers.WorkbenchStatusDialogManager;
48
import org.eclipse.ui.statushandlers.WorkbenchStatusDialogManager;
46
49
47
public class StatusDialogManagerTest extends TestCase {
50
public class StatusDialogManagerTest extends TestCase {
Lines 51-56 Link Here
51
	private static final String THROWABLE = "throwable";
54
	private static final String THROWABLE = "throwable";
52
	private final static String MESSAGE_1 = "TEST_MESSAGE_1";
55
	private final static String MESSAGE_1 = "TEST_MESSAGE_1";
53
	private final static String MESSAGE_2 = "TEST_MESSAGE_2";
56
	private final static String MESSAGE_2 = "TEST_MESSAGE_2";
57
	private final static String MESSAGE_3 = "TEST_MESSAGE_2";
54
	private final static String TITLE = "TEST_TITLE";
58
	private final static String TITLE = "TEST_TITLE";
55
	private final static NullPointerException NPE = new NullPointerException();
59
	private final static NullPointerException NPE = new NullPointerException();
56
	private final static NullPointerException NPE_WITH_MESSAGE = new NullPointerException(
60
	private final static NullPointerException NPE_WITH_MESSAGE = new NullPointerException(
Lines 59-68 Link Here
59
63
60
	private boolean automatedMode;
64
	private boolean automatedMode;
61
	WorkbenchStatusDialogManager wsdm;
65
	WorkbenchStatusDialogManager wsdm;
66
	WorkbenchErrorHandler weh;
62
	
67
	
63
	protected void setUp() throws Exception {
68
	protected void setUp() throws Exception {
64
		automatedMode = ErrorDialog.AUTOMATED_MODE;
69
		automatedMode = ErrorDialog.AUTOMATED_MODE;
65
		wsdm = new WorkbenchStatusDialogManager(null, null);
70
		weh = new WorkbenchErrorHandler();
71
		wsdm = weh.getStatusDialogManager();
66
		ErrorDialog.AUTOMATED_MODE = false;
72
		ErrorDialog.AUTOMATED_MODE = false;
67
		super.setUp();
73
		super.setUp();
68
	}
74
	}
Lines 73-78 Link Here
73
		assertNotNull(shell);
79
		assertNotNull(shell);
74
		assertTrue((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
80
		assertTrue((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
75
	}
81
	}
82
	
83
	/**
84
	 * This test checks if the calling thread is really blocked. It opens a
85
	 * dialog with the BLOCK flag in UI thread, and then monitors in the
86
	 * background thread that the dialog really appears (in 50 tries, 50
87
	 * milliseconds each). After the dialog appears, "OK" selection is emulated,
88
	 * the dialog is closed and the handle method returns. At this point there
89
	 * can be no shell.
90
	 */
91
	public void testBlockingBehavior1() {
92
		wsdm = weh.getStatusDialogManager();
93
		Thread thread = new Thread(new Runnable(){
94
			public void run() {
95
				int count = 50;
96
				final boolean opened[] = new boolean[]{false};
97
				while (!opened[0] && count-- != 0) {
98
					try {
99
						Thread.sleep(50);
100
					} catch (InterruptedException e) {
101
						e.printStackTrace();
102
					}
103
					Display.getDefault().syncExec(new Runnable() {
104
						public void run() {
105
							opened[0] = StatusDialogUtil.getStatusShell() != null;
106
							if(opened[0]){
107
								selectWidget(StatusDialogUtil.getOkButton());
108
							}
109
						}
110
					});
111
				}
112
				assertTrue("Dialog should appear!", count > 0);
113
				
114
			}
115
		});
116
		thread.start();
117
		weh.handle(createStatusAdapter(MESSAGE_1), StatusManager.BLOCK);
118
		assertNull("Dialog should block the calling thread!", StatusDialogUtil
119
				.getStatusShell());
120
	}
121
122
	/**
123
	 * This is more advanced version of testBlockingBehavior1. We have 2
124
	 * background threads that raise statuses. UI thread also raises one. No
125
	 * thread can proceed until "OK" is emulated (and this will happen if the
126
	 * dialog is opened and three statuses were reported).
127
	 */
128
	public void testBlockingBehavior2() {
129
		Thread thread1 = new Thread(new Runnable() {
130
			public void run() {
131
				weh.handle(createStatusAdapter(MESSAGE_1), StatusManager.BLOCK);
132
				Display.getDefault().syncExec(new Runnable() {
133
					public void run() {
134
						assertNull("Dialog should block the calling thread!",
135
								StatusDialogUtil.getStatusShell());
136
					}
137
				});
138
			}
139
140
		});
141
		thread1.start();
142
		Thread thread2 = new Thread(new Runnable() {
143
			public void run() {
144
				weh.handle(createStatusAdapter(MESSAGE_2), StatusManager.BLOCK);
145
				Display.getDefault().syncExec(new Runnable() {
146
					public void run() {
147
						assertNull("Dialog should block the calling thread!",
148
								StatusDialogUtil.getStatusShell());
149
					}
150
				});
151
			}
152
		});
153
		thread2.start();
154
		Thread checker = new Thread(new Runnable() {
155
			public void run() {
156
				int count = 50;
157
				final boolean statusesShown[] = new boolean[] { false };
158
				while (!statusesShown[0] && count-- != 0) {
159
					try {
160
						Thread.sleep(50);
161
					} catch (InterruptedException e) {
162
						e.printStackTrace();
163
					}
164
					Display.getDefault().syncExec(new Runnable() {
165
						public void run() {
166
							boolean dialogVisible = StatusDialogUtil
167
									.getStatusShell() != null;
168
							statusesShown[0] = dialogVisible
169
									&& wsdm.getStatusAdapters().size() == 3;
170
							if (statusesShown[0]) {
171
								selectWidget(StatusDialogUtil.getOkButton());
172
							}
173
						}
174
					});
175
				}
176
				assertTrue(
177
						"Dialog should appear and all statuses should be shown",
178
						count > 0);
179
			}
180
		});
181
		checker.start();
182
		weh.handle(createStatusAdapter(MESSAGE_3), StatusManager.BLOCK);
183
		assertNull("Dialog should block the calling thread!", StatusDialogUtil
184
				.getStatusShell());
185
	}
76
186
77
	public void testNonBlockingAppearance() {
187
	public void testNonBlockingAppearance() {
78
		wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
188
		wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);

Return to bug 247818