### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.workbench Index: Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchStatusDialogManager.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchStatusDialogManager.java,v retrieving revision 1.14 diff -u -r1.14 WorkbenchStatusDialogManager.java --- Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchStatusDialogManager.java 24 Jul 2008 22:47:59 -0000 1.14 +++ Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchStatusDialogManager.java 1 Aug 2008 12:07:11 -0000 @@ -12,12 +12,14 @@ package org.eclipse.ui.statushandlers; import java.net.URL; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; @@ -139,6 +141,132 @@ public class WorkbenchStatusDialogManager { /** + * @since 3.4 + * + */ + private final class DefaultLabelProvider implements ITableLabelProvider { + ResourceManager manager = new LocalResourceManager(JFaceResources.getResources()); + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + // Do nothing + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() + */ + public void dispose() { + manager.dispose(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, + * int) + */ + public Image getColumnImage(Object element, int columnIndex) { + Image result = null; + if (element != null) { + StatusAdapter statusAdapter = ((StatusAdapter) element); + Job job = (Job) (statusAdapter.getAdapter(Job.class)); + if (job != null) { + result = getIcon(job); + } + } + // if somehow disposed image was received (should not happen) + if (result != null && result.isDisposed()) { + result = null; + } + return result; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, + * int) + */ + public String getColumnText(Object element, int columnIndex) { + StatusAdapter statusAdapter = (StatusAdapter) element; + String text = WorkbenchMessages.WorkbenchStatusDialog_ProblemOccurred; + if (getStatusAdapters().size() == 1) { + Job job = (Job) (statusAdapter.getAdapter(Job.class)); + if (job != null) { + text = getPrimaryMessage(statusAdapter); + } else { + text = getSecondaryMessage(statusAdapter); + } + } else { + Job job = (Job) (statusAdapter.getAdapter(Job.class)); + if (job != null) { + text = job.getName(); + } else { + text = getPrimaryMessage(statusAdapter); + } + } + Long timestamp = (Long) statusAdapter + .getProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY); + + if (timestamp != null && getStatusAdapters().size() > 1) { + String date = DateFormat.getDateTimeInstance(DateFormat.LONG, + DateFormat.LONG) + .format(new Date(timestamp.longValue())); + return NLS.bind(ProgressMessages.JobInfo_Error, (new Object[] { + text, date })); + } + return text; + } + + /* + * Get the icon for the job. + */ + private Image getIcon(Job job) { + if (job != null) { + Object property = job + .getProperty(IProgressConstants.ICON_PROPERTY); + + // Create an image from the job's icon property or family + if (property instanceof ImageDescriptor) { + return manager.createImage((ImageDescriptor) property); + } else if (property instanceof URL) { + return manager.createImage(ImageDescriptor + .createFromURL((URL) property)); + } else { + // Let the progress manager handle the resource management + return ProgressManager.getInstance().getIconFor(job); + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, + * java.lang.String) + */ + public boolean isLabelProperty(Object element, String property) { + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + // Do nothing + } + } + + /** * This class is responsible for managing details area. * * @since 3.4 @@ -427,6 +555,13 @@ public void widgetDisposed(org.eclipse.swt.events.DisposeEvent e) { dialog = null; statusListViewer = null; + for (Iterator iterator = threads.iterator(); iterator.hasNext();) { + Thread thread = (Thread) iterator.next(); + synchronized (thread) { + thread.notify(); + } + } + threads.clear(); statusAdapter = null; errors.clear(); modals.clear(); @@ -754,6 +889,11 @@ * Stores information, which statuses should be displayed in modal window. */ private HashMap modals = new HashMap(); + + /** + * Stores blocked threads; + */ + private List threads = new ArrayList(); /** * This field stores the real dialog that appears to the user. @@ -794,127 +934,7 @@ /** * A list label provider */ - private ITableLabelProvider statusListLabelProvider = new ITableLabelProvider() { - ResourceManager manager = new LocalResourceManager(JFaceResources.getResources()); - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener) - */ - public void addListener(ILabelProviderListener listener) { - // Do nothing - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose() - */ - public void dispose() { - manager.dispose(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, - * int) - */ - public Image getColumnImage(Object element, int columnIndex) { - Image result = null; - if (element != null) { - StatusAdapter statusAdapter = ((StatusAdapter) element); - Job job = (Job) (statusAdapter.getAdapter(Job.class)); - if (job != null) { - result = getIcon(job); - } - } - // if somehow disposed image was received (should not happen) - if (result != null && result.isDisposed()) { - result = null; - } - return result; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, - * int) - */ - public String getColumnText(Object element, int columnIndex) { - StatusAdapter statusAdapter = (StatusAdapter) element; - String text = WorkbenchMessages.WorkbenchStatusDialog_ProblemOccurred; - if (getStatusAdapters().size() == 1) { - Job job = (Job) (statusAdapter.getAdapter(Job.class)); - if (job != null) { - text = getPrimaryMessage(statusAdapter); - } else { - text = getSecondaryMessage(statusAdapter); - } - } else { - Job job = (Job) (statusAdapter.getAdapter(Job.class)); - if (job != null) { - text = job.getName(); - } else { - text = getPrimaryMessage(statusAdapter); - } - } - Long timestamp = (Long) statusAdapter - .getProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY); - - if (timestamp != null && getStatusAdapters().size() > 1) { - String date = DateFormat.getDateTimeInstance(DateFormat.LONG, - DateFormat.LONG) - .format(new Date(timestamp.longValue())); - return NLS.bind(ProgressMessages.JobInfo_Error, (new Object[] { - text, date })); - } - return text; - } - - /* - * Get the icon for the job. - */ - private Image getIcon(Job job) { - if (job != null) { - Object property = job - .getProperty(IProgressConstants.ICON_PROPERTY); - - // Create an image from the job's icon property or family - if (property instanceof ImageDescriptor) { - return manager.createImage((ImageDescriptor) property); - } else if (property instanceof URL) { - return manager.createImage(ImageDescriptor - .createFromURL((URL) property)); - } else { - // Let the progress manager handle the resource management - return ProgressManager.getInstance().getIconFor(job); - } - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, - * java.lang.String) - */ - public boolean isLabelProperty(Object element, String property) { - return false; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener) - */ - public void removeListener(ILabelProviderListener listener) { - // Do nothing - } - }; + private ITableLabelProvider statusListLabelProvider; /** * This variable holds current details area provider. @@ -1014,10 +1034,6 @@ */ public WorkbenchStatusDialogManager(int displayMask, String dialogTitle) { - - Assert.isNotNull(Display.getCurrent(), - "WorkbenchStatusDialogManager must be instantiated in UI thread"); //$NON-NLS-1$ - this.displayMask = displayMask; this.title = dialogTitle == null ? JFaceResources .getString("Problem_Occurred") : //$NON-NLS-1$ @@ -1099,42 +1115,64 @@ return; } - Assert.isNotNull(Display.getCurrent(), - "WorkbenchStatusDialogManager#addStatusAdapter must be called from UI thread"); //$NON-NLS-1$ - if (!PlatformUI.isWorkbenchRunning()) { // we are shutting down, so just log WorkbenchPlugin.log(statusAdapter.getStatus()); return; } + final boolean isUIThread = Display.getCurrent() != null; - // Add the error in the UI thread to ensure thread safety in the - // dialog - if (dialog == null || dialog.getShell().isDisposed()) { - - errors.add(statusAdapter); - modals.put(statusAdapter, new Boolean(modal)); - // Delay prompting if the status adapter property is set - if (shouldPrompt(statusAdapter)) { - if (dialog == null) { - dialog = new InternalDialog(getParentShell(), - WorkbenchStatusDialogManager.this, shouldBeModal()); - setSelectedStatusAdapter(statusAdapter); - dialog.open(); - dialog.getShell().addDisposeListener(disposeListener); + Runnable r = new Runnable(){ + + public void run() { + if (dialog == null || dialog.getShell().isDisposed()) { + + errors.add(statusAdapter); + modals.put(statusAdapter, new Boolean(modal)); + // Delay prompting if the status adapter property is set + if (shouldPrompt(statusAdapter)) { + if (dialog == null) { + dialog = new InternalDialog(getParentShell(), + WorkbenchStatusDialogManager.this, shouldBeModal()); + setSelectedStatusAdapter(statusAdapter); + if(modal && isUIThread){ + dialog.setBlockOnOpen(true); + } + dialog.open(); + dialog.getShell().addDisposeListener(disposeListener); + } + refresh(); + refreshDialogSize(); + } + + } else { + if (statusAdapter + .getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY) != null) { + statusAdapter.setProperty( + IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, + Boolean.FALSE); + } + openStatusDialog(modal, isUIThread, statusAdapter); } - refresh(); - refreshDialogSize(); + } - + + }; + + if(isUIThread){ + r.run(); } else { - if (statusAdapter - .getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY) != null) { - statusAdapter.setProperty( - IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY, - Boolean.FALSE); + Display.getDefault().asyncExec(r); + if(modal){ + synchronized (Thread.currentThread()) { + threads.add(Thread.currentThread()); + try { + Thread.currentThread().wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } - openStatusDialog(modal, statusAdapter); } } @@ -1271,6 +1309,9 @@ GridData labelLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true); labelLayoutData.widthHint = dialog.convertWidthInCharsToPixels(50); singleStatusLabel.setLayoutData(labelLayoutData); + if(statusListLabelProvider == null){ + statusListLabelProvider = new DefaultLabelProvider(); + } // main message set up early, to address bug 222391 singleStatusLabel.setText(statusListLabelProvider.getColumnText( statusAdapter, 0)); @@ -1862,7 +1903,7 @@ * @param statusAdapter * status adapter to be selected. */ - private void openStatusDialog(final boolean modal, + private void openStatusDialog(final boolean modal, final boolean isUIThread, final StatusAdapter statusAdapter) { errors.add(statusAdapter); modals.put(statusAdapter, new Boolean(modal)); @@ -1873,6 +1914,9 @@ close(); setSelectedStatusAdapter(statusAdapter); dialog = new InternalDialog(getParentShell(), this, modal); + if(modal && isUIThread){ + dialog.setBlockOnOpen(true); + } dialog.open(); dialog.getShell().addDisposeListener(disposeListener); modalitySwitch = false; Index: Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java,v retrieving revision 1.20 diff -u -r1.20 WorkbenchErrorHandler.java --- Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java 15 May 2008 22:14:07 -0000 1.20 +++ Eclipse UI/org/eclipse/ui/statushandlers/WorkbenchErrorHandler.java 1 Aug 2008 12:07:11 -0000 @@ -13,8 +13,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.application.WorkbenchAdvisor; import org.eclipse.ui.internal.WorkbenchPlugin; @@ -60,21 +58,7 @@ } final boolean modal = ((style & StatusManager.BLOCK) == StatusManager.BLOCK); - if (Display.getCurrent() != null) { - getStatusDialogManager().addStatusAdapter(statusAdapter, modal); - } else { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - if (!PlatformUI.isWorkbenchRunning()) { - // we are shutting down, so just log - WorkbenchPlugin.log(statusAdapter.getStatus()); - return; - } - getStatusDialogManager().addStatusAdapter( - statusAdapter, modal); - } - }); - } + getStatusDialogManager().addStatusAdapter(statusAdapter, modal); } if ((style & StatusManager.LOG) == StatusManager.LOG) {