blob: 362ffb1385bcf19cbbf24d2066b1a7eb6af0c49e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.security.ui;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.internal.provisional.security.ui.AuthorizationManager;
import org.eclipse.jface.action.ControlContribution;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IWorkbenchWindow;
/**
* This contribution item is used to create a visual cue that informs the
* user of bundles disabled in the system for signature validation reasons.
*
* It has the following functions:
* - Two levels of severity, represented by two distinct graphical icons
* - Visual notification when new user attention is required (e.g. throbbing)
* - An informational message when the user hovers over the icon
* - A right-click menu for contributing security related actions
*
* @since 3.4
*/
public class SecurityStatusControl extends ControlContribution {
private static final String IMAGE_PATH_OK = "/full/obj16/green.GIF"; //$NON-NLS-1$
private static final String IMAGE_PATH_ERROR = "/full/obj16/red.GIF"; //$NON-NLS-1$
private static final String IMAGE_PATH_DISABLED = "/full/obj16/red.GIF"; //$NON-NLS-1$
private static final String IMAGE_PATH_UNKNOWN = "/full/obj16/red.GIF"; //$NON-NLS-1$
/* the default id for this Item */
private static final String ID = "org.eclipse.ui.securityStatus"; //$NON-NLS-1$
private IWorkbenchWindow window;
private CLabel label;
private IconState currentState;
/**
* Creates the contribution item.
*
* @param window the window
*/
public SecurityStatusControl(IWorkbenchWindow window) {
this(window, ID);
}
/**
* Creates the contribution item.
*
* @param window the window
* @param id the id
*/
public SecurityStatusControl(IWorkbenchWindow window, String id) {
super(id);
Assert.isNotNull(window);
this.window = window;
this.currentState = getCurrentState();
}
private static IconState getCurrentState() {
AuthorizationManager mgr = Activator.getAuthorizationManager();
return new IconState(mgr.isEnabled(), mgr.getStatus(), mgr.needsAttention());
}
protected Control createControl(Composite parent) {
label = new CLabel(parent, SWT.NONE);
label.setImage(getIcon(currentState));
Job updateJob = new Job(ID) {
public IStatus run(IProgressMonitor monitor) {
while (true) {
IconState newState = getCurrentState();
if (!currentState.equals(newState)) {
final Display display = getDisplay(window);
if (null != display)
display.asyncExec(() -> {
if (!label.isDisposed()) {
Image oldIcon = label.getImage();
label.setImage(getIcon(currentState));
oldIcon.dispose();
}
});
currentState = newState;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
break;
}
}
return null;
}
};
updateJob.setSystem(true);
updateJob.setPriority(Job.DECORATE);
updateJob.schedule();
return label;
}
public void dispose() {
Image currentImage = label.getImage();
if (currentImage != null) {
currentImage.dispose();
}
label.dispose();
}
protected static Image getIcon(IconState iconState) {
Image returnValue = null;
if (iconState.isEnabled()) {
IStatus status = iconState.getStatus();
ImageDescriptor imgDesc = null;
switch (status.getSeverity()) {
case IStatus.OK :
imgDesc = Activator.getImageDescriptor(IMAGE_PATH_OK);
break;
case IStatus.ERROR :
imgDesc = Activator.getImageDescriptor(IMAGE_PATH_ERROR);
break;
default :
imgDesc = Activator.getImageDescriptor(IMAGE_PATH_UNKNOWN);
break;
}
returnValue = imgDesc.createImage();
//TODO: decorate for needsAttention
} else {
ImageDescriptor imgDesc = Activator.getImageDescriptor(IMAGE_PATH_DISABLED);
returnValue = imgDesc.createImage();
}
return returnValue;
}
private static Display getDisplay(IWorkbenchWindow window) {
if (null != window) {
Shell shell = window.getShell();
if (null != shell)
return shell.getDisplay();
}
return null;
}
private static class IconState {
boolean enabled;
boolean needsAttention;
IStatus status;
IconState(boolean enabled, IStatus status, boolean needsAttention) {
if (null == status)
throw new IllegalArgumentException();
this.enabled = enabled;
this.status = status;
this.needsAttention = needsAttention;
}
public boolean isEnabled() {
return enabled;
}
public IStatus getStatus() {
return status;
}
@Override
public boolean equals(Object another) {
boolean returnValue = false;
if (another instanceof IconState) {
if (enabled == ((IconState) another).enabled) {
if (needsAttention == ((IconState) another).needsAttention) {
if (status.equals(((IconState) another).getStatus())) {
returnValue = true;
}
}
}
}
return returnValue;
}
@Override
public int hashCode() {
return Boolean.valueOf(enabled).hashCode() + status.hashCode() + Boolean.valueOf(needsAttention).hashCode();
}
}
}