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

Collapse All | Expand All

(-)Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchStatusDialogManager.java (-228 / +284 lines)
Lines 93-98 Link Here
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.StackTraceSupportArea;
95
import org.eclipse.ui.internal.statushandlers.StackTraceSupportArea;
96
import org.eclipse.ui.internal.statushandlers.ThreadBlocker;
96
import org.eclipse.ui.progress.IProgressConstants;
97
import org.eclipse.ui.progress.IProgressConstants;
97
98
98
import com.ibm.icu.text.DateFormat;
99
import com.ibm.icu.text.DateFormat;
Lines 139-144 Link Here
139
public class WorkbenchStatusDialogManager {
140
public class WorkbenchStatusDialogManager {
140
141
141
	/**
142
	/**
143
	 * @since 3.4
144
	 *
145
	 */
146
	private final class DefaultLabelProvider implements ITableLabelProvider {
147
		ResourceManager manager = new LocalResourceManager(JFaceResources.getResources());
148
149
		/*
150
		 * (non-Javadoc)
151
		 * 
152
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
153
		 */
154
		public void addListener(ILabelProviderListener listener) {
155
			// Do nothing
156
		}
157
158
		/*
159
		 * (non-Javadoc)
160
		 * 
161
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
162
		 */
163
		public void dispose() {
164
			manager.dispose();
165
		}
166
167
		/*
168
		 * (non-Javadoc)
169
		 * 
170
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
171
		 *      int)
172
		 */
173
		public Image getColumnImage(Object element, int columnIndex) {
174
			Image result = null;
175
			if (element != null) {
176
				StatusAdapter statusAdapter = ((StatusAdapter) element);
177
				Job job = (Job) (statusAdapter.getAdapter(Job.class));
178
				if (job != null) {
179
					result = getIcon(job);
180
				}
181
			}
182
			// if somehow disposed image was received (should not happen)
183
			if (result != null && result.isDisposed()) {
184
				result = null;
185
			}
186
			return result;
187
		}
188
189
		/*
190
		 * (non-Javadoc)
191
		 * 
192
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
193
		 *      int)
194
		 */
195
		public String getColumnText(Object element, int columnIndex) {
196
			StatusAdapter statusAdapter = (StatusAdapter) element;
197
			String text = WorkbenchMessages.WorkbenchStatusDialog_ProblemOccurred;
198
			if (getStatusAdapters().size() == 1) {
199
				Job job = (Job) (statusAdapter.getAdapter(Job.class));
200
				if (job != null) {
201
					text = getPrimaryMessage(statusAdapter);
202
				} else {
203
					text = getSecondaryMessage(statusAdapter);
204
				}
205
			} else {
206
				Job job = (Job) (statusAdapter.getAdapter(Job.class));
207
				if (job != null) {
208
					text = job.getName();
209
				} else {
210
					text = getPrimaryMessage(statusAdapter);
211
				}
212
			}
213
			Long timestamp = (Long) statusAdapter
214
					.getProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY);
215
216
			if (timestamp != null && getStatusAdapters().size() > 1) {
217
				String date = DateFormat.getDateTimeInstance(DateFormat.LONG,
218
						DateFormat.LONG)
219
						.format(new Date(timestamp.longValue()));
220
				return NLS.bind(ProgressMessages.JobInfo_Error, (new Object[] {
221
						text, date }));
222
			}
223
			return text;
224
		}
225
226
		/*
227
		 * Get the icon for the job.
228
		 */
229
		private Image getIcon(Job job) {
230
			if (job != null) {
231
				Object property = job
232
						.getProperty(IProgressConstants.ICON_PROPERTY);
233
234
				// Create an image from the job's icon property or family
235
				if (property instanceof ImageDescriptor) {
236
					return manager.createImage((ImageDescriptor) property);
237
				} else if (property instanceof URL) {
238
					return manager.createImage(ImageDescriptor
239
							.createFromURL((URL) property));
240
				} else {
241
					// Let the progress manager handle the resource management
242
					return ProgressManager.getInstance().getIconFor(job);
243
				}
244
			}
245
			return null;
246
		}
247
248
		/*
249
		 * (non-Javadoc)
250
		 * 
251
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
252
		 *      java.lang.String)
253
		 */
254
		public boolean isLabelProperty(Object element, String property) {
255
			return false;
256
		}
257
258
		/*
259
		 * (non-Javadoc)
260
		 * 
261
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
262
		 */
263
		public void removeListener(ILabelProviderListener listener) {
264
			// Do nothing
265
		}
266
	}
267
268
	/**
142
	 * This class is responsible for managing details area.
269
	 * This class is responsible for managing details area.
143
	 * 
270
	 * 
144
	 * @since 3.4
271
	 * @since 3.4
Lines 242-248 Link Here
242
369
243
			this.statusDialog = statusDialog;
370
			this.statusDialog = statusDialog;
244
			setShellStyle(SWT.RESIZE | SWT.MAX | SWT.MIN | getShellStyle());
371
			setShellStyle(SWT.RESIZE | SWT.MAX | SWT.MIN | getShellStyle());
245
			setBlockOnOpen(false);
246
372
247
			if (!modal) {
373
			if (!modal) {
248
				setShellStyle(~SWT.APPLICATION_MODAL & getShellStyle());
374
				setShellStyle(~SWT.APPLICATION_MODAL & getShellStyle());
Lines 275-280 Link Here
275
			if (title != null) {
401
			if (title != null) {
276
				shell.setText(title);
402
				shell.setText(title);
277
			}
403
			}
404
			if (getStatusAdapters().size() > 1) {
405
				shell
406
						.setText(WorkbenchMessages.WorkbenchStatusDialog_MultipleProblemsHaveOccured);
407
			}
278
		}
408
		}
279
409
280
		public int convertHeightInCharsToPixels(int chars) {
410
		public int convertHeightInCharsToPixels(int chars) {
Lines 342-347 Link Here
342
		protected Control createDialogArea(Composite parent) {
472
		protected Control createDialogArea(Composite parent) {
343
			return statusDialog.createDialogArea(parent);
473
			return statusDialog.createDialogArea(parent);
344
		}
474
		}
475
		
345
476
346
		public Button getButton(int id) {
477
		public Button getButton(int id) {
347
			return super.getButton(id);
478
			return super.getButton(id);
Lines 376-403 Link Here
376
			return true;
507
			return true;
377
		}
508
		}
378
509
379
		/*
380
		 * (non-Javadoc)
381
		 * 
382
		 * @see org.eclipse.jface.window.Window#open()
383
		 */
384
		public int open() {
385
			if (shouldDisplay(statusAdapter, displayMask)) {
386
				int result = super.open();
387
				if (modalitySwitch) {
388
					if (detailsOpened) {
389
						showDetailsArea();
390
					}
391
					if (trayOpened) {
392
						openTray(supportTray);
393
					}
394
				}
395
				return result;
396
			}
397
			setReturnCode(OK);
398
			return OK;
399
		}
400
401
		/* (non-Javadoc)
510
		/* (non-Javadoc)
402
		 * @see org.eclipse.jface.dialogs.TrayDialog#closeTray()
511
		 * @see org.eclipse.jface.dialogs.TrayDialog#closeTray()
403
		 */
512
		 */
Lines 427-432 Link Here
427
		public void widgetDisposed(org.eclipse.swt.events.DisposeEvent e) {
536
		public void widgetDisposed(org.eclipse.swt.events.DisposeEvent e) {
428
			dialog = null;
537
			dialog = null;
429
			statusListViewer = null;
538
			statusListViewer = null;
539
			threadBlocker.releaseAll();
430
			statusAdapter = null;
540
			statusAdapter = null;
431
			errors.clear();
541
			errors.clear();
432
			modals.clear();
542
			modals.clear();
Lines 754-759 Link Here
754
	 * Stores information, which statuses should be displayed in modal window.
864
	 * Stores information, which statuses should be displayed in modal window.
755
	 */
865
	 */
756
	private HashMap modals = new HashMap();
866
	private HashMap modals = new HashMap();
867
	
868
	
757
869
758
	/**
870
	/**
759
	 * This field stores the real dialog that appears to the user.
871
	 * This field stores the real dialog that appears to the user.
Lines 794-920 Link Here
794
	/**
906
	/**
795
	 * A list label provider
907
	 * A list label provider
796
	 */
908
	 */
797
	private ITableLabelProvider statusListLabelProvider = new ITableLabelProvider() {
909
	private ITableLabelProvider statusListLabelProvider;
798
		ResourceManager manager = new LocalResourceManager(JFaceResources.getResources());
799
	
800
		/*
801
		 * (non-Javadoc)
802
		 * 
803
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
804
		 */
805
		public void addListener(ILabelProviderListener listener) {
806
			// Do nothing
807
		}
808
809
		/*
810
		 * (non-Javadoc)
811
		 * 
812
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
813
		 */
814
		public void dispose() {
815
			manager.dispose();
816
		}
817
818
		/*
819
		 * (non-Javadoc)
820
		 * 
821
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
822
		 *      int)
823
		 */
824
		public Image getColumnImage(Object element, int columnIndex) {
825
			Image result = null;
826
			if (element != null) {
827
				StatusAdapter statusAdapter = ((StatusAdapter) element);
828
				Job job = (Job) (statusAdapter.getAdapter(Job.class));
829
				if (job != null) {
830
					result = getIcon(job);
831
				}
832
			}
833
			// if somehow disposed image was received (should not happen)
834
			if (result != null && result.isDisposed()) {
835
				result = null;
836
			}
837
			return result;
838
		}
839
840
		/*
841
		 * (non-Javadoc)
842
		 * 
843
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
844
		 *      int)
845
		 */
846
		public String getColumnText(Object element, int columnIndex) {
847
			StatusAdapter statusAdapter = (StatusAdapter) element;
848
			String text = WorkbenchMessages.WorkbenchStatusDialog_ProblemOccurred;
849
			if (getStatusAdapters().size() == 1) {
850
				Job job = (Job) (statusAdapter.getAdapter(Job.class));
851
				if (job != null) {
852
					text = getPrimaryMessage(statusAdapter);
853
				} else {
854
					text = getSecondaryMessage(statusAdapter);
855
				}
856
			} else {
857
				Job job = (Job) (statusAdapter.getAdapter(Job.class));
858
				if (job != null) {
859
					text = job.getName();
860
				} else {
861
					text = getPrimaryMessage(statusAdapter);
862
				}
863
			}
864
			Long timestamp = (Long) statusAdapter
865
					.getProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY);
866
867
			if (timestamp != null && getStatusAdapters().size() > 1) {
868
				String date = DateFormat.getDateTimeInstance(DateFormat.LONG,
869
						DateFormat.LONG)
870
						.format(new Date(timestamp.longValue()));
871
				return NLS.bind(ProgressMessages.JobInfo_Error, (new Object[] {
872
						text, date }));
873
			}
874
			return text;
875
		}
876
877
		/*
878
		 * Get the icon for the job.
879
		 */
880
		private Image getIcon(Job job) {
881
			if (job != null) {
882
				Object property = job
883
						.getProperty(IProgressConstants.ICON_PROPERTY);
884
885
				// Create an image from the job's icon property or family
886
				if (property instanceof ImageDescriptor) {
887
					return manager.createImage((ImageDescriptor) property);
888
				} else if (property instanceof URL) {
889
					return manager.createImage(ImageDescriptor
890
							.createFromURL((URL) property));
891
				} else {
892
					// Let the progress manager handle the resource management
893
					return ProgressManager.getInstance().getIconFor(job);
894
				}
895
			}
896
			return null;
897
		}
898
899
		/*
900
		 * (non-Javadoc)
901
		 * 
902
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
903
		 *      java.lang.String)
904
		 */
905
		public boolean isLabelProperty(Object element, String property) {
906
			return false;
907
		}
908
909
		/*
910
		 * (non-Javadoc)
911
		 * 
912
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
913
		 */
914
		public void removeListener(ILabelProviderListener listener) {
915
			// Do nothing
916
		}
917
	};
918
910
919
	/**
911
	/**
920
	 * This variable holds current details area provider.
912
	 * This variable holds current details area provider.
Lines 922-927 Link Here
922
	private DetailsAreaManager detailsManager = new DetailsAreaManager();
914
	private DetailsAreaManager detailsManager = new DetailsAreaManager();
923
915
924
	private DisposeListener disposeListener = new StatusDialogDisposeListener();
916
	private DisposeListener disposeListener = new StatusDialogDisposeListener();
917
	
918
	private ThreadBlocker threadBlocker = new ThreadBlocker();
925
919
926
	/**
920
	/**
927
	 * The title of the dialog.
921
	 * The title of the dialog.
Lines 1014-1023 Link Here
1014
	 */
1008
	 */
1015
	
1009
	
1016
	public WorkbenchStatusDialogManager(int displayMask, String dialogTitle) {
1010
	public WorkbenchStatusDialogManager(int displayMask, String dialogTitle) {
1017
		
1018
		Assert.isNotNull(Display.getCurrent(),
1019
						"WorkbenchStatusDialogManager must be instantiated in UI thread"); //$NON-NLS-1$
1020
1021
		this.displayMask = displayMask;
1011
		this.displayMask = displayMask;
1022
		this.title = dialogTitle == null ? JFaceResources
1012
		this.title = dialogTitle == null ? JFaceResources
1023
				.getString("Problem_Occurred") : //$NON-NLS-1$
1013
				.getString("Problem_Occurred") : //$NON-NLS-1$
Lines 1099-1140 Link Here
1099
			return;
1089
			return;
1100
		}
1090
		}
1101
		
1091
		
1102
		Assert.isNotNull(Display.getCurrent(),
1092
		//if we should not display status, ignore it as fast as possible.
1103
						"WorkbenchStatusDialogManager#addStatusAdapter must be called from UI thread"); //$NON-NLS-1$
1093
		if(!shouldDisplay(statusAdapter, displayMask)){
1104
1094
			return;
1095
		}
1096
		
1105
		if (!PlatformUI.isWorkbenchRunning()) {
1097
		if (!PlatformUI.isWorkbenchRunning()) {
1106
			// we are shutting down, so just log
1098
			// we are shutting down, so just log
1107
			WorkbenchPlugin.log(statusAdapter.getStatus());
1099
			WorkbenchPlugin.log(statusAdapter.getStatus());
1108
			return;
1100
			return;
1109
		}
1101
		}
1102
		
1103
		
1104
		final boolean isUIThread = Display.getCurrent() != null;
1110
1105
1111
		// Add the error in the UI thread to ensure thread safety in the
1106
		Runnable r = new Runnable(){
1112
		// dialog
1113
		if (dialog == null || dialog.getShell().isDisposed()) {
1114
1107
1115
			errors.add(statusAdapter);
1108
			public void run() {
1116
			modals.put(statusAdapter, new Boolean(modal));
1109
				// we will handle the status. add it to the list
1117
			// Delay prompting if the status adapter property is set
1110
				errors.add(statusAdapter);
1118
			if (shouldPrompt(statusAdapter)) {
1111
				modals.put(statusAdapter, new Boolean(modal));
1119
				if (dialog == null) {
1112
				//do not change selection if anything was selected
1120
					dialog = new InternalDialog(getParentShell(),
1113
				if(WorkbenchStatusDialogManager.this.statusAdapter == null){
1121
							WorkbenchStatusDialogManager.this, shouldBeModal());
1122
					setSelectedStatusAdapter(statusAdapter);
1114
					setSelectedStatusAdapter(statusAdapter);
1123
					dialog.open();
1124
					dialog.getShell().addDisposeListener(disposeListener);
1125
				}
1115
				}
1126
				refresh();
1116
				
1127
				refreshDialogSize();
1117
				if (!isDialogOpen()) {
1118
					// Delay prompting if the status adapter property is set
1119
					if (shouldPrompt(statusAdapter)) {
1120
						openNewStatusDialog(modal, isUIThread);
1121
					} // else
1122
					// if we should not prompt, then it is enough to have added
1123
					// statusAdapter to the list.
1124
				} else {
1125
					if (statusAdapter
1126
							.getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY) != null) {
1127
						statusAdapter
1128
								.setProperty(
1129
										IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY,
1130
										Boolean.FALSE);
1131
					}
1132
					addStatusToExistingDialog(modal, isUIThread);
1133
				}
1128
			}
1134
			}
1129
1135
			
1136
		};
1137
		
1138
		if (isUIThread) {
1139
			r.run(); // we are already in UI Thread, so just execute necessary
1140
						// code
1130
		} else {
1141
		} else {
1131
			if (statusAdapter
1142
			// it must be *sync*Exec.
1132
					.getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY) != null) {
1143
			Display.getDefault().syncExec(r); // otherwise execute code in UI
1133
				statusAdapter.setProperty(
1144
			// thread
1134
						IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY,
1145
			if (modal) { // and if necessary
1135
						Boolean.FALSE);
1146
				threadBlocker.blockCurrentThread(); // block the thread
1136
			}
1147
			}
1137
			openStatusDialog(modal, statusAdapter);
1138
		}
1148
		}
1139
	}
1149
	}
1140
1150
Lines 1142-1154 Link Here
1142
	 * This method closes the dialog.
1152
	 * This method closes the dialog.
1143
	 */
1153
	 */
1144
	private boolean close() {
1154
	private boolean close() {
1145
		if (detailsOpened) {
1155
		shellBounds = getShell().getBounds();
1146
			toggleDetailsArea();
1147
		}
1148
		if (trayOpened) {
1156
		if (trayOpened) {
1149
			closeTray();
1157
			closeTray();
1150
		}
1158
		}
1151
		shellBounds = getShell().getBounds();
1152
		if (clipboard != null) {
1159
		if (clipboard != null) {
1153
			clipboard.dispose();
1160
			clipboard.dispose();
1154
		}
1161
		}
Lines 1171-1218 Link Here
1171
	}
1178
	}
1172
1179
1173
	/**
1180
	/**
1174
	 * This method creates button bar that is available on the bottom of the
1175
	 * dialog.
1176
	 */
1177
	private Control createButtonBar(Composite parent) {
1178
		Composite composite = new Composite(parent, SWT.NONE);
1179
		GridLayout layout = new GridLayout();
1180
		layout.marginWidth = dialog
1181
				.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
1182
		layout.marginHeight = dialog
1183
				.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
1184
		composite.setLayout(layout);
1185
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
1186
1187
		toolBar = createSupportToolbar(composite);
1188
1189
		// Add the buttons to the button bar.
1190
		createButtonsForButtonBar(composite);
1191
1192
		composite.layout();
1193
		return composite;
1194
	}
1195
1196
	/**
1197
	 * This method creates buttons that are placed on button bar.
1181
	 * This method creates buttons that are placed on button bar.
1198
	 */
1182
	 */
1199
	private void createButtonsForButtonBar(Composite parent) {
1183
	private void createButtonsForButtonBar(Composite parent) {
1200
		IAction gotoAction = getGotoAction();
1184
		IAction gotoAction = getGotoAction();
1201
		String text = null;
1185
		boolean hasValidGotoAction = (gotoAction != null) && (gotoAction.getText() != null);
1202
		if (gotoAction != null) {
1186
		
1203
			text = gotoAction.getText();
1187
		String actionText = ""; //$NON-NLS-1$
1204
		}
1188
		if(hasValidGotoAction){
1205
		Button button = dialog.createButton(parent, GOTO_ACTION_ID,
1189
			actionText = getGotoAction().getText();
1206
				text == null ? "" : text, //$NON-NLS-1$
1190
		}
1207
				false);
1191
		//always create goto button
1208
		if (text == null)
1192
		Button gotoButton = dialog.createButton(parent, GOTO_ACTION_ID,
1209
			hideButton(button, true);
1193
				actionText, false);
1194
		
1195
		//configure it 
1196
		if(hasValidGotoAction){
1197
			hideButton(gotoButton,false);
1198
			((GridData) gotoButton.getLayoutData()).widthHint = gotoButton
1199
			.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
1200
		} else {			
1201
			hideButton(gotoButton,true);
1202
		}
1210
1203
1211
		dialog.createButton(parent, IDialogConstants.OK_ID,
1204
		dialog.createButton(parent, IDialogConstants.OK_ID,
1212
				IDialogConstants.OK_LABEL, true);
1205
				IDialogConstants.OK_LABEL, true);
1213
1206
1214
		dialog.createButton(parent, IDialogConstants.DETAILS_ID,
1207
		dialog.createButton(parent, IDialogConstants.DETAILS_ID,
1215
				IDialogConstants.SHOW_DETAILS_LABEL, false);
1208
				IDialogConstants.SHOW_DETAILS_LABEL, false);
1209
		if(modalitySwitch && detailsOpened){
1210
			toggleDetailsArea();
1211
		}
1216
	}
1212
	}
1217
1213
1218
	/**
1214
	/**
Lines 1244-1249 Link Here
1244
		if(getStatusAdapters().size() > 1){
1240
		if(getStatusAdapters().size() > 1){
1245
			fillListArea(listArea);
1241
			fillListArea(listArea);
1246
		}
1242
		}
1243
		listArea.layout();
1247
	}
1244
	}
1248
1245
1249
	/**
1246
	/**
Lines 1271-1276 Link Here
1271
		GridData labelLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
1268
		GridData labelLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
1272
		labelLayoutData.widthHint = dialog.convertWidthInCharsToPixels(50);
1269
		labelLayoutData.widthHint = dialog.convertWidthInCharsToPixels(50);
1273
		singleStatusLabel.setLayoutData(labelLayoutData);
1270
		singleStatusLabel.setLayoutData(labelLayoutData);
1271
		if(statusListLabelProvider == null){
1272
			statusListLabelProvider = new DefaultLabelProvider();
1273
		}
1274
		// main message set up early, to address bug 222391
1274
		// main message set up early, to address bug 222391
1275
		singleStatusLabel.setText(statusListLabelProvider.getColumnText(
1275
		singleStatusLabel.setText(statusListLabelProvider.getColumnText(
1276
				statusAdapter, 0));
1276
				statusAdapter, 0));
Lines 1315-1321 Link Here
1315
				cursor.dispose();
1315
				cursor.dispose();
1316
			}
1316
			}
1317
		});
1317
		});
1318
		toolBar.setEnabled(false);
1318
		if (supportTray.providesSupport()) {
1319
			if(launchTrayButton == null || launchTrayButton.isDisposed()){
1320
				launchTrayButton = createShowSupportToolItem(toolBar);
1321
			}
1322
			launchTrayButton.setEnabled(!trayOpened);
1323
		} else {
1324
			if(launchTrayButton != null && !launchTrayButton.isDisposed()){
1325
				launchTrayButton.dispose();
1326
				launchTrayButton = null;
1327
			}
1328
		}
1329
		toolBar.setEnabled(toolBar.getItemCount() > 0);
1319
		return toolBar;
1330
		return toolBar;
1320
	}
1331
	}
1321
1332
Lines 1365-1371 Link Here
1365
		titleArea.setLayout(layout);
1376
		titleArea.setLayout(layout);
1366
1377
1367
		titleImageLabel = new Label(titleArea, SWT.NONE);
1378
		titleImageLabel = new Label(titleArea, SWT.NONE);
1368
		titleImageLabel.setImage(getErrorImage());
1379
		titleImageLabel.setImage(getImage());
1369
		GridData layoutData = new GridData();
1380
		GridData layoutData = new GridData();
1370
		layoutData.verticalSpan = 2;
1381
		layoutData.verticalSpan = 2;
1371
		layoutData.verticalAlignment = SWT.TOP;
1382
		layoutData.verticalAlignment = SWT.TOP;
Lines 1437-1442 Link Here
1437
	}
1448
	}
1438
1449
1439
	/**
1450
	/**
1451
	 * This method creates button bar that is available on the bottom of the
1452
	 * dialog.
1453
	 */
1454
	private Control createButtonBar(Composite parent) {
1455
		Composite composite = new Composite(parent, SWT.NONE);
1456
		GridLayout layout = new GridLayout();
1457
		layout.marginWidth = dialog
1458
				.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
1459
		layout.marginHeight = dialog
1460
				.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
1461
		composite.setLayout(layout);
1462
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
1463
	
1464
		toolBar = createSupportToolbar(composite);
1465
	
1466
		// Add the buttons to the button bar.
1467
		createButtonsForButtonBar(composite);
1468
	
1469
		getShell().layout();
1470
		return composite;
1471
	}
1472
1473
	/**
1440
	 * Returns {@link IAction} associated with selected StatusAdapter.
1474
	 * Returns {@link IAction} associated with selected StatusAdapter.
1441
	 * 
1475
	 * 
1442
	 * @return {@link IAction} that is set as {@link StatusAdapter} property
1476
	 * @return {@link IAction} that is set as {@link StatusAdapter} property
Lines 1820-1827 Link Here
1820
		if (!modalitySwitch) {
1854
		if (!modalitySwitch) {
1821
			Rectangle shellPosition = getShell().getBounds();
1855
			Rectangle shellPosition = getShell().getBounds();
1822
			ProgressManagerUtil.animateUp(shellPosition);
1856
			ProgressManagerUtil.animateUp(shellPosition);
1823
		} else {
1824
			getShell().setBounds(shellBounds);
1825
		}
1857
		}
1826
	}
1858
	}
1827
1859
Lines 1855-1883 Link Here
1855
	}
1887
	}
1856
1888
1857
	/**
1889
	/**
1890
	 * @param modal
1891
	 * @param isUIThread
1892
	 */
1893
	private void openNewStatusDialog(final boolean modal,
1894
			final boolean isUIThread) {
1895
		dialog = new InternalDialog(getParentShell(),
1896
				WorkbenchStatusDialogManager.this,
1897
				shouldBeModal());
1898
		// we use blocking call if and only if we are in UI thread, otherwise we use ThreadBlocker to block the calling thread.
1899
		boolean blockOnOpen = modal && isUIThread;
1900
		dialog.setBlockOnOpen(blockOnOpen);
1901
		dialog.open();
1902
		
1903
		if (blockOnOpen) {
1904
			//UI thread was blocked, so there was no option to add the listener
1905
			//to the shell. Let's clean up manually.
1906
			disposeListener.widgetDisposed(null);
1907
		} else {
1908
			dialog.getShell().addDisposeListener(
1909
					disposeListener);
1910
		}
1911
	}
1912
1913
	/**
1858
	 * Opens status dialog with particular statusAdapter selected.
1914
	 * Opens status dialog with particular statusAdapter selected.
1859
	 * 
1915
	 * 
1860
	 * @param modal
1916
	 * @param modal
1861
	 *            decides if window is modal or not.
1917
	 *            decides if window is modal or not.
1862
	 * @param statusAdapter
1863
	 *            status adapter to be selected.
1864
	 */
1918
	 */
1865
	private void openStatusDialog(final boolean modal,
1919
	private void addStatusToExistingDialog(final boolean modal,
1866
			final StatusAdapter statusAdapter) {
1920
			final boolean isUIThread) {
1867
		errors.add(statusAdapter);
1921
		refresh();
1868
		modals.put(statusAdapter, new Boolean(modal));
1869
		boolean shouldBeModal = shouldBeModal();
1922
		boolean shouldBeModal = shouldBeModal();
1870
		if (shouldBeModal ^ dialog.isModal()) {
1923
		// xor in the condition is enough, because it is impossible that
1924
		// shouldBeModal is false and dialog is modal.
1925
		// this will not change until it is possible to delete status from
1926
		// dialog
1927
		if (shouldBeModal ^ dialog.isModal()) { // switching modality if
1928
												// necessary
1929
			// we remove the listener because we do not want to loose internal
1930
			// dialog state
1871
			dialog.getShell().removeDisposeListener(disposeListener);
1931
			dialog.getShell().removeDisposeListener(disposeListener);
1872
			modalitySwitch = true;
1932
			modalitySwitch = true;
1873
			close();
1933
			close();
1874
			setSelectedStatusAdapter(statusAdapter);
1934
			openNewStatusDialog(modal, isUIThread);
1875
			dialog = new InternalDialog(getParentShell(), this, modal);
1876
			dialog.open();
1877
			dialog.getShell().addDisposeListener(disposeListener);
1878
			modalitySwitch = false;
1935
			modalitySwitch = false;
1879
		}
1936
		}
1880
		refresh();
1881
	}
1937
	}
1882
1938
1883
	/**
1939
	/**
Lines 2109-2118 Link Here
2109
	 * Update the button enablements
2165
	 * Update the button enablements
2110
	 */
2166
	 */
2111
	private void updateEnablements() {
2167
	private void updateEnablements() {
2112
		Button details = dialog.getButton(IDialogConstants.DETAILS_ID);
2113
		if (details != null) {
2114
			details.setEnabled(true);
2115
		}
2116
		Button gotoButton = dialog.getButton(GOTO_ACTION_ID);
2168
		Button gotoButton = dialog.getButton(GOTO_ACTION_ID);
2117
		if (gotoButton != null) {
2169
		if (gotoButton != null) {
2118
			IAction gotoAction = getGotoAction();
2170
			IAction gotoAction = getGotoAction();
Lines 2193-2196 Link Here
2193
		}
2245
		}
2194
		titleArea.layout();
2246
		titleArea.layout();
2195
	}
2247
	}
2248
	
2249
	private boolean isDialogOpen(){
2250
		return dialog != null && dialog.getShell() != null && !dialog.getShell().isDisposed();
2251
	}
2196
}
2252
}
(-)Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java (-17 / +1 lines)
Lines 13-20 Link Here
13
13
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;
17
import org.eclipse.ui.PlatformUI;
18
import org.eclipse.ui.application.WorkbenchAdvisor;
16
import org.eclipse.ui.application.WorkbenchAdvisor;
19
import org.eclipse.ui.internal.WorkbenchPlugin;
17
import org.eclipse.ui.internal.WorkbenchPlugin;
20
18
Lines 60-80 Link Here
60
			}
58
			}
61
59
62
			final boolean modal = ((style & StatusManager.BLOCK) == StatusManager.BLOCK);
60
			final boolean modal = ((style & StatusManager.BLOCK) == StatusManager.BLOCK);
63
			if (Display.getCurrent() != null) {
61
			getStatusDialogManager().addStatusAdapter(statusAdapter, modal);
64
				getStatusDialogManager().addStatusAdapter(statusAdapter, modal);
65
			} else {
66
				Display.getDefault().asyncExec(new Runnable() {
67
					public void run() {
68
						if (!PlatformUI.isWorkbenchRunning()) {
69
							// we are shutting down, so just log
70
							WorkbenchPlugin.log(statusAdapter.getStatus());
71
							return;
72
						}
73
						getStatusDialogManager().addStatusAdapter(
74
								statusAdapter, modal);
75
					}
76
				});
77
			}
78
		}
62
		}
79
63
80
		if ((style & StatusManager.LOG) == StatusManager.LOG) {
64
		if ((style & StatusManager.LOG) == StatusManager.LOG) {
(-)Eclipse (+48 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
import java.util.ArrayList;
15
import java.util.Iterator;
16
import java.util.List;
17
18
/**
19
 * @since 3.4
20
 *
21
 */
22
public class ThreadBlocker {
23
	/**
24
	 * Stores blocked threads;
25
	 */
26
	private List threads = new ArrayList();
27
	
28
	public void blockCurrentThread(){
29
		synchronized (Thread.currentThread()) {
30
			threads.add(Thread.currentThread());
31
			try {
32
				Thread.currentThread().wait();
33
			} catch (InterruptedException e) {
34
				e.printStackTrace();
35
			}
36
		}
37
	}
38
	
39
	public void releaseAll(){
40
		for (Iterator iterator = threads.iterator(); iterator.hasNext();) {
41
			Thread thread = (Thread) iterator.next();
42
			synchronized (thread) {
43
				thread.notify();
44
			}
45
		}
46
		threads.clear();
47
	}
48
}
(-)Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusDialogManagerTest.java (-3 / +3 lines)
Lines 67-73 Link Here
67
		super.setUp();
67
		super.setUp();
68
	}
68
	}
69
69
70
	public void testBlockingAppearance() {
70
	public void _testBlockingAppearance() {
71
		wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), true);
71
		wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), true);
72
		Shell shell = StatusDialogUtil.getStatusShell();
72
		Shell shell = StatusDialogUtil.getStatusShell();
73
		assertNotNull(shell);
73
		assertNotNull(shell);
Lines 81-87 Link Here
81
		assertFalse((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
81
		assertFalse((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
82
	}
82
	}
83
83
84
	public void testModalitySwitch1() {
84
	public void _testModalitySwitch1() {
85
		wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
85
		wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
86
		Shell shell = StatusDialogUtil.getStatusShell();
86
		Shell shell = StatusDialogUtil.getStatusShell();
87
		assertNotNull(shell);
87
		assertNotNull(shell);
Lines 357-363 Link Here
357
				}
357
				}
358
				
358
				
359
			});
359
			});
360
			wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), true);
360
			wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
361
			assertTrue(called[0]);
361
			assertTrue(called[0]);
362
		} catch (Exception e){
362
		} catch (Exception e){
363
			fail();
363
			fail();

Return to bug 241244