# HG changeset patch # User dadubrow # Date 1267205421 21600 # Node ID 42eaaa076776b6bd4678e9d5d7fb7df79febadef # Parent 083e0a53ef298318f3821fc713aeaed88ba247b4 Add support for status notification popups diff -r 083e0a53ef29 -r 42eaaa076776 connectivity/com.nokia.carbide.remoteConnections/META-INF/MANIFEST.MF --- a/connectivity/com.nokia.carbide.remoteConnections/META-INF/MANIFEST.MF Thu Feb 25 23:47:43 2010 -0600 +++ b/connectivity/com.nokia.carbide.remoteConnections/META-INF/MANIFEST.MF Fri Feb 26 11:30:21 2010 -0600 @@ -7,12 +7,13 @@ Bundle-Vendor: Nokia Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, - org.eclipse.ui, + org.eclipse.ui;visibility:=reexport, com.nokia.cpp.utils.core, org.eclipse.emf.ecore.xmi;bundle-version="2.4.0", org.eclipse.core.net;bundle-version="1.1.0", org.eclipse.help;bundle-version="3.4.0", - com.nokia.cpp.utils.ui + com.nokia.cpp.utils.ui, + org.eclipse.mylyn.commons.ui;bundle-version="3.2.0" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Export-Package: com.nokia.carbide.installpackages, diff -r 083e0a53ef29 -r 42eaaa076776 connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/RemoteConnectionsActivator.java --- a/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/RemoteConnectionsActivator.java Thu Feb 25 23:47:43 2010 -0600 +++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/RemoteConnectionsActivator.java Fri Feb 26 11:30:21 2010 -0600 @@ -30,6 +30,8 @@ import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IFilter; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; @@ -38,11 +40,12 @@ import com.nokia.carbide.remoteconnections.interfaces.IConnectionTypeProvider; import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager; import com.nokia.carbide.remoteconnections.internal.api.IDeviceDiscoveryAgent; +import com.nokia.carbide.remoteconnections.internal.api.IStatusDisplay; import com.nokia.carbide.remoteconnections.internal.api.IDeviceDiscoveryAgent.IPrerequisiteStatus; import com.nokia.carbide.remoteconnections.internal.registry.Registry; import com.nokia.carbide.remoteconnections.internal.ui.DeviceDiscoveryPrequisiteErrorDialog; +import com.nokia.carbide.remoteconnections.internal.ui.StatusDisplay; import com.nokia.cpp.internal.api.utils.core.Logging; -import com.nokia.cpp.internal.api.utils.ui.RunRunnableWhenWorkbenchVisibleJob; import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils; /** @@ -50,6 +53,39 @@ */ public class RemoteConnectionsActivator extends AbstractUIPlugin { + private final class WhenWorkbenchIsVisibleThread extends Thread { + private Shell shell; + private boolean visible; + private final Runnable runnable; + + public WhenWorkbenchIsVisibleThread(Runnable runnable) { + this.runnable = runnable; + shell = WorkbenchUtils.getActiveShell(); + } + + public void run() { + while (true) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + if (shell != null && shell.isVisible()) { + visible = true; + } + } + }); + if (visible) + break; + + try { + Thread.sleep(500); + } catch (InterruptedException e) { + break; + } + } + if (visible) + runnable.run(); + } + } + // The plug-in ID public static final String PLUGIN_ID = "com.nokia.carbide.remoteConnections"; //$NON-NLS-1$ @@ -59,6 +95,7 @@ private static RemoteConnectionsActivator plugin; private Collection discoveryAgents; + private static final String IGNORE_AGENT_LOAD_ERRORS_KEY = "ignoreAgentLoadErrors"; //$NON-NLS-1$ /** @@ -74,14 +111,14 @@ instance.loadExtensions(); instance.loadConnections(); - RunRunnableWhenWorkbenchVisibleJob.start(new Runnable() { + new WhenWorkbenchIsVisibleThread(new Runnable() { public void run() { if (!ignoreAgentLoadErrors()) checkPrerequisites(); - + loadAndStartDeviceDiscoveryAgents(); } - }); + }).start(); } private boolean ignoreAgentLoadErrors() { @@ -242,4 +279,8 @@ } } } + + public static IStatusDisplay getStatusDisplay() { + return new StatusDisplay(); + } } diff -r 083e0a53ef29 -r 42eaaa076776 connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/api/IStatusDisplay.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/api/IStatusDisplay.java Fri Feb 26 11:30:21 2010 -0600 @@ -0,0 +1,42 @@ +/** +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.carbide.remoteconnections.internal.api; + +import org.eclipse.core.runtime.IStatus; + +public interface IStatusDisplay { + + /** + * Asynchronously displays status with notification UI + * @param status IStatus + */ + void displayStatus(IStatus status); + + /** + * Synchronously displays status with notification UI + * Displays a prompt and runs action if user accepts. + * Calling thread will block until notification is closed (either by timer or by user) + * and if action will be called on the calling thread. + * NOTE: This cannot be called on display thread!
+ * assert Display.getCurrent() == null; + * @param status IStatus + * @param prompt String + * @param action Runnable + */ + void displayStatusWithAction(IStatus status, String prompt, Runnable action); +} diff -r 083e0a53ef29 -r 42eaaa076776 connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/ui/StatusDisplay.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/ui/StatusDisplay.java Fri Feb 26 11:30:21 2010 -0600 @@ -0,0 +1,147 @@ +/** +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.carbide.remoteconnections.internal.ui; + +import java.text.MessageFormat; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.mylyn.internal.provisional.commons.ui.AbstractNotificationPopup; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; + +import com.nokia.carbide.remoteconnections.internal.api.IStatusDisplay; +import com.nokia.cpp.internal.api.utils.core.Check; + +@SuppressWarnings("restriction") +public class StatusDisplay implements IStatusDisplay { + + private final class NotificationPopup extends AbstractNotificationPopup { + private final IStatus status; + private final String prompt; + + private NotificationPopup(Display display, IStatus status, String prompt) { + super(display); + this.status = status; + this.prompt = prompt; + setDelayClose(30 * 1000); + } + + protected void createContentArea(Composite composite) { + GridLayoutFactory.fillDefaults().margins(5, 5).applyTo(composite); + Label label = new Label(composite, SWT.WRAP); + label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + label.setText(status.getMessage()); + label.setBackground(composite.getBackground()); + if (prompt != null) { + Link link = new Link(composite, SWT.WRAP); + link.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + link.setText(MessageFormat.format("{0}", prompt)); + link.setBackground(composite.getBackground()); + link.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + clicked = true; + NotificationPopup.this.close(); + } + }); + } + } + + @Override + protected String getPopupShellTitle() { + switch (status.getSeverity()) { + case IStatus.INFO: + return "Information"; + case IStatus.WARNING: + return "Warning"; + case IStatus.ERROR: + return "Error"; + }; + Check.checkState(false); + return null; + } + + @Override + protected Image getPopupShellImage(int maximumHeight) { + switch (status.getSeverity()) { + case IStatus.INFO: + return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_INFO); + case IStatus.WARNING: + return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING); + case IStatus.ERROR: + return JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR); + }; + Check.checkState(false); + return null; + } + } + + private boolean clicked; + private boolean closed; + + public StatusDisplay() { + } + + public void displayStatus(final IStatus status) { + final Display display = Display.getDefault(); + display.syncExec(new Runnable() { + public void run() { + doDisplayStatus(display, null, status); + } + }); + } + + public void displayStatusWithAction(final IStatus status, final String prompt, Runnable action) { + final Display display = Display.getDefault(); + display.asyncExec(new Runnable() { + public void run() { + doDisplayStatus(display, prompt, status); + } + }); + while (!closed) { + try { + Thread.sleep(200); + } catch (InterruptedException e1) { + } + } + if (clicked) + action.run(); + } + + protected void doDisplayStatus(Display display, String prompt, IStatus status) { + NotificationPopup popup = new NotificationPopup(display, status, prompt); + popup.open(); + popup.getShell().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + StatusDisplay.this.closed = true; + } + }); + } + +}