blob: 670944869ca420d55b22b5becece1c411e76287c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.progress;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.SideValue;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
import org.eclipse.e4.ui.model.application.ui.menu.MToolControl;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.internal.TrimUtil;
/**
* The ProgressRegion is class for the region of the workbench where the
* progress line and the animation item are shown.
*/
public class ProgressRegion {
@Inject
MToolControl toolControl;
@Inject
IWorkbenchWindow workbenchWindow;
ProgressCanvasViewer viewer;
ProgressAnimationItem animationItem;
Composite region;
/**
* the side the receiver is placed on
*/
private SideValue getLocation() {
if (toolControl == null) {
// if we don't have a ToolControl, assume bottom
return SideValue.BOTTOM;
}
MElementContainer<?> parent = toolControl.getParent();
while (parent != null) {
if (parent instanceof MTrimBar) {
return ((MTrimBar) parent).getSide();
}
parent = parent.getParent();
}
return SideValue.BOTTOM;
}
private boolean forceHorizontal;
/**
* Create the contents of the receiver in the parent. Use the window for the
* animation item.
*
* @param parent
* The parent widget of the composite.
* @return Control
*/
@PostConstruct
public Control createContents(Composite parent) {
// Test whether or not 'advanced' graphics are available
// If not then we'll 'force' the ProgressBar to always be
// HORIZONTAL...
//TODO: This should likely be at some 'global' level state
GC gc = new GC(parent);
gc.setAdvanced(true);
forceHorizontal = !gc.getAdvanced();
gc.dispose();
region = new Composite(parent, SWT.NONE) {
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
Point size = super.computeSize(wHint, hHint, changed);
if (isHorizontal())
size.y = TrimUtil.TRIM_DEFAULT_HEIGHT;
else {
size.x = TrimUtil.TRIM_DEFAULT_HEIGHT;
}
return size;
}
};
GridLayout gl = new GridLayout();
gl.marginHeight = 0;
gl.marginWidth = 0;
if (isHorizontal())
gl.numColumns = 3;
region.setLayout(gl);
viewer = new ProgressCanvasViewer(region, SWT.NO_FOCUS, 1, 36, isHorizontal() ? SWT.HORIZONTAL : SWT.VERTICAL);
viewer.setUseHashlookup(true);
Control viewerControl = viewer.getControl();
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
Point viewerSizeHints = viewer.getSizeHints();
if (isHorizontal()) {
gd.widthHint = viewerSizeHints.x;
gd.heightHint = viewerSizeHints.y;
} else {
gd.widthHint = viewerSizeHints.y;
gd.heightHint = viewerSizeHints.x;
}
viewerControl.setLayoutData(gd);
int widthPreference = AnimationManager.getInstance()
.getPreferredWidth() + 25;
animationItem = new ProgressAnimationItem(this, isHorizontal() ? SWT.HORIZONTAL : SWT.VERTICAL);
animationItem.createControl(region);
animationItem.setAnimationContainer(new AnimationItem.IAnimationContainer() {
@Override
public void animationDone() {
//Add an extra refresh to the viewer in case
//of stale input if the controls are not disposed
if (viewer.getControl().isDisposed()) {
return;
}
viewer.refresh();
}
@Override
public void animationStart() {
// Nothing by default here.
}
});
if (isHorizontal()) {
gd = new GridData(GridData.FILL_VERTICAL);
gd.widthHint = widthPreference;
} else {
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.heightHint = widthPreference;
}
animationItem.getControl().setLayoutData(gd);
viewerControl.addMouseListener(new MouseAdapter() {
@Override
public void mouseDoubleClick(MouseEvent e) {
processDoubleClick();
}
});
//Never show debug info
IContentProvider provider = new ProgressViewerContentProvider(viewer,
false,false);
viewer.setContentProvider(provider);
viewer.setInput(provider);
viewer.setLabelProvider(new ProgressViewerLabelProvider(viewerControl));
viewer.setComparator(ProgressManagerUtil.getProgressViewerComparator());
viewer.addFilter(new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (element instanceof JobInfo) {
JobInfo info= (JobInfo)element;
if (info.isBlocked() || info.getJob().getState() == Job.WAITING) {
return false;
}
}
return true;
}
});
return region;
}
/**
* Return the animationItem for the receiver.
*
* @return AnimationItem
*/
public AnimationItem getAnimationItem() {
return animationItem;
}
/**
* Return the control for the receiver.
*
* @return Control
*/
public Control getControl() {
return region;
}
/**
* Process the double click event.
*/
public void processDoubleClick() {
ProgressManagerUtil.openProgressView(workbenchWindow);
}
/**
* Answer true if the side is a horizonal one
*
* @param dropSide
* @return <code>true</code> if the side is horizontal
*/
private boolean isHorizontal() {
if (forceHorizontal)
return true;
SideValue loc = getLocation();
return loc == SideValue.TOP || loc == SideValue.BOTTOM;
}
}