/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.cathy.internal; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.statushandlers.AbstractStatusHandler; import org.eclipse.ui.statushandlers.IStatusAdapterConstants; import org.eclipse.ui.statushandlers.StatusAdapter; import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.ui.statushandlers.StatusManager.INotificationTypes; import org.xmind.ui.internal.ToolkitPlugin; import org.xmind.ui.internal.statushandlers.RuntimeErrorDialog; public class CathyStatusHandler extends AbstractStatusHandler { private static final String PROPERTY_PREFIX = "org.xmind.cathy.statusHandlers.adapters"; //$NON-NLS-1$ private static final QualifiedName BLOCK = new QualifiedName( PROPERTY_PREFIX, "block"); //$NON-NLS-1$ private List<StatusAdapter> statusQueue = new ArrayList<StatusAdapter>(4); private RuntimeErrorDialog currentDialog = null; public CathyStatusHandler() { } public boolean supportsNotification(int type) { if (type == INotificationTypes.HANDLED) { return true; } return super.supportsNotification(type); } public void handle(final StatusAdapter statusAdapter, final int style) { if (((style & StatusManager.SHOW) == StatusManager.SHOW) || ((style & StatusManager.BLOCK) == StatusManager.BLOCK)) { final boolean block = ((style & StatusManager.BLOCK) == StatusManager.BLOCK); addProperties(statusAdapter, block); if (Display.getCurrent() != null) { showStatusAdapter(statusAdapter); } else { if (block) { Display.getDefault().syncExec(new Runnable() { public void run() { showStatusAdapter(statusAdapter); } }); } else { Display.getDefault().asyncExec(new Runnable() { public void run() { showStatusAdapter(statusAdapter); } }); } } } if ((style & StatusManager.LOG) == StatusManager.LOG) { StatusManager.getManager() .addLoggedStatus(statusAdapter.getStatus()); ToolkitPlugin.getDefault().getLog().log(statusAdapter.getStatus()); } } private void addProperties(final StatusAdapter statusAdapter, boolean block) { // Add timestamp: if (statusAdapter.getProperty( IStatusAdapterConstants.TIMESTAMP_PROPERTY) == null) { statusAdapter.setProperty( IStatusAdapterConstants.TIMESTAMP_PROPERTY, Long.valueOf(System.currentTimeMillis())); } statusAdapter.setProperty(BLOCK, Boolean.valueOf(block)); } /** * Shows the status adapter. * * @param statusAdapter * the status adapter to show * @param block * <code>true</code> to request a modal dialog and suspend the * calling thread till the dialog is closed, <code>false</code> * otherwise. */ private void showStatusAdapter(final StatusAdapter statusAdapter) { if (!PlatformUI.isWorkbenchRunning()) { // we are shutting down, so just log ToolkitPlugin.getDefault().getLog().log(statusAdapter.getStatus()); return; } statusQueue.add(statusAdapter); if (currentDialog == null) { currentDialog = showErrorDialogFor(statusAdapter); } if (((Boolean) statusAdapter.getProperty(BLOCK)).booleanValue()) { Display display = Display.getCurrent(); if (display != null && !display.isDisposed()) { while (statusQueue.contains(statusAdapter) && !display.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } } } private RuntimeErrorDialog showErrorDialogFor( final StatusAdapter statusAdapter) { StatusManager.getManager().fireNotification(INotificationTypes.HANDLED, new StatusAdapter[] { statusAdapter }); int style = RuntimeErrorDialog.NONE; if (((Boolean) statusAdapter.getProperty(BLOCK)).booleanValue()) { style |= RuntimeErrorDialog.BLOCKED; } RuntimeErrorDialog dialog = new RuntimeErrorDialog(style, statusAdapter, null, CathyPlugin.getDefault().getErrorReporter()); dialog.create(); dialog.getShell().addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { statusQueue.remove(statusAdapter); if (statusQueue.size() > 0) { currentDialog = showErrorDialogFor(statusQueue.get(0)); } else { currentDialog = null; } } }); dialog.open(); return dialog; } }