org.eclipse.e4.ui.progress.internal.DetailedProgressViewer.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.e4.ui.progress.internal.DetailedProgressViewer.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 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 Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.e4.ui.progress.internal;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.e4.ui.progress.IProgressService;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
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.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;

/**
 * The DetailedProgressViewer is a viewer that shows the details of all in
 * progress job or jobs that are finished awaiting user input.
 *
 * @since 3.2
 *
 */
public class DetailedProgressViewer extends AbstractProgressViewer {

    //Maximum number of entries to display so that the view does not flood the UI with events
    private static final int MAX_DISPLAYED = 20;

    Composite control;

    private ScrolledComposite scrolled;

    private Composite noEntryArea;

    private IProgressService progressService;

    private FinishedJobs finishedJobs;

    /**
     * Create a new instance of the receiver with a control that is a child of
     * parent with style style.
     *
     * @param parent
     * @param style
     */
    public DetailedProgressViewer(Composite parent, int style, IProgressService progressService,
            FinishedJobs finishedJobs) {
        this.progressService = progressService;
        this.finishedJobs = finishedJobs;

        scrolled = new ScrolledComposite(parent, SWT.V_SCROLL | style);
        int height = JFaceResources.getDefaultFont().getFontData()[0].getHeight();
        scrolled.getVerticalBar().setIncrement(height * 2);
        scrolled.setExpandHorizontal(true);
        scrolled.setExpandVertical(true);

        control = new Composite(scrolled, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        control.setLayout(layout);
        control.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

        control.addFocusListener(new FocusAdapter() {

            private boolean settingFocus = false;

            @Override
            public void focusGained(FocusEvent e) {
                if (!settingFocus) {
                    // Prevent new focus events as a result this update
                    // occurring
                    settingFocus = true;
                    setFocus();
                    settingFocus = false;
                }
            }
        });

        control.addControlListener(new ControlListener() {
            @Override
            public void controlMoved(ControlEvent e) {
                updateVisibleItems();

            }

            @Override
            public void controlResized(ControlEvent e) {
                updateVisibleItems();
            }
        });

        // TODO E4 - missing e4 replacement
        // PlatformUI.getWorkbench().getHelpSystem().setHelp(control,
        // IWorkbenchHelpContextIds.RESPONSIVE_UI);

        scrolled.setContent(control);
        hookControl(control);

        noEntryArea = new Composite(scrolled, SWT.NONE);
        noEntryArea.setLayout(new GridLayout());
        noEntryArea.setBackground(noEntryArea.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

        Text noEntryLabel = new Text(noEntryArea, SWT.SINGLE);
        noEntryLabel.setText(ProgressMessages.ProgressView_NoOperations);
        noEntryLabel.setBackground(noEntryArea.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
        GridData textData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
        noEntryLabel.setLayoutData(textData);
        noEntryLabel.setEditable(false);

        // TODO E4 - missing e4 replacement
        // PlatformUI.getWorkbench().getHelpSystem().setHelp(noEntryLabel,
        //      IWorkbenchHelpContextIds.RESPONSIVE_UI);

    }

    @Override
    public void add(Object[] elements) {
        ViewerComparator sorter = getComparator();

        // Use a Set in case we are getting something added that exists
        Set<Object> newItems = new HashSet<>(elements.length);

        Control[] existingChildren = control.getChildren();
        for (int i = 0; i < existingChildren.length; i++) {
            if (existingChildren[i].getData() != null)
                newItems.add(existingChildren[i].getData());
        }

        for (int i = 0; i < elements.length; i++) {
            if (elements[i] != null)
                newItems.add(elements[i]);
        }

        JobTreeElement[] infos = new JobTreeElement[newItems.size()];
        newItems.toArray(infos);

        if (sorter != null) {
            sorter.sort(this, infos);
        }

        // Update with the new elements to prevent flash
        for (int i = 0; i < existingChildren.length; i++) {
            ((ProgressInfoItem) existingChildren[i]).dispose();
        }

        int totalSize = Math.min(newItems.size(), MAX_DISPLAYED);

        for (int i = 0; i < totalSize; i++) {
            ProgressInfoItem item = createNewItem(infos[i]);
            item.setColor(i);
        }

        control.layout(true);
        updateForShowingProgress();
    }

    /**
     * Update for the progress being displayed.
     */
    private void updateForShowingProgress() {
        if (control.getChildren().length > 0) {
            scrolled.setContent(control);
        } else {
            scrolled.setContent(noEntryArea);
        }
    }

    /**
     * Create a new item for info.
     *
     * @param info
     * @return ProgressInfoItem
     */
    private ProgressInfoItem createNewItem(JobTreeElement info) {
        final ProgressInfoItem item = new ProgressInfoItem(control, SWT.NONE, info, progressService, finishedJobs);

        item.setIndexListener(new ProgressInfoItem.IndexListener() {
            @Override
            public void selectNext() {
                DetailedProgressViewer.this.selectNext(item);

            }

            @Override
            public void selectPrevious() {
                DetailedProgressViewer.this.selectPrevious(item);

            }

            @Override
            public void select() {

                Control[] children = control.getChildren();
                for (int i = 0; i < children.length; i++) {
                    ProgressInfoItem child = (ProgressInfoItem) children[i];
                    if (!item.equals(child)) {
                        child.selectWidgets(false);
                    }
                }
                item.selectWidgets(true);

            }
        });

        // Refresh to populate with the current tasks
        item.refresh();
        return item;
    }

    /**
     * Select the previous item in the receiver.
     *
     * @param item
     */
    protected void selectPrevious(ProgressInfoItem item) {
        Control[] children = control.getChildren();
        for (int i = 0; i < children.length; i++) {
            ProgressInfoItem child = (ProgressInfoItem) children[i];
            if (item.equals(child)) {
                ProgressInfoItem previous;
                if (i == 0) {
                    previous = (ProgressInfoItem) children[children.length - 1];
                } else {
                    previous = (ProgressInfoItem) children[i - 1];
                }

                item.selectWidgets(false);
                previous.selectWidgets(true);
                return;
            }
        }
    }

    /**
     * Select the next item in the receiver.
     *
     * @param item
     */
    protected void selectNext(ProgressInfoItem item) {
        Control[] children = control.getChildren();
        for (int i = 0; i < children.length; i++) {
            ProgressInfoItem child = (ProgressInfoItem) children[i];
            if (item.equals(child)) {
                ProgressInfoItem next;
                if (i == children.length - 1) {
                    next = (ProgressInfoItem) children[0];
                } else {
                    next = (ProgressInfoItem) children[i + 1];
                }
                item.selectWidgets(false);
                next.selectWidgets(true);

                return;
            }
        }

    }

    @Override
    protected Widget doFindInputItem(Object element) {
        return null;
    }

    @Override
    protected Widget doFindItem(Object element) {
        Control[] existingChildren = control.getChildren();
        for (int i = 0; i < existingChildren.length; i++) {
            if (existingChildren[i].isDisposed() || existingChildren[i].getData() == null) {
                continue;
            }
            if (existingChildren[i].getData().equals(element)) {
                return existingChildren[i];
            }
        }
        return null;
    }

    @Override
    protected void doUpdateItem(Widget item, Object element, boolean fullMap) {
        if (usingElementMap()) {
            unmapElement(item);
        }
        item.dispose();
        add(new Object[] { element });
    }

    @Override
    public Control getControl() {
        return scrolled;
    }

    @Override
    protected List<Object> getSelectionFromWidget() {
        return new ArrayList<>(0);
    }

    @Override
    protected void inputChanged(Object input, Object oldInput) {
        super.inputChanged(input, oldInput);
        refreshAll();
        updateForShowingProgress();
    }

    @Override
    protected void internalRefresh(Object element) {
        if (element == null) {
            return;
        }

        if (element.equals(getRoot())) {
            refreshAll();
            return;
        }
        Widget widget = findItem(element);
        if (widget == null) {
            add(new Object[] { element });
            return;
        }
        ((ProgressInfoItem) widget).refresh();

        // Update the minimum size
        Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        size.x += IDialogConstants.HORIZONTAL_SPACING;
        size.y += IDialogConstants.VERTICAL_SPACING;

        scrolled.setMinSize(size);
    }

    @Override
    public void remove(Object[] elements) {

        for (int i = 0; i < elements.length; i++) {
            JobTreeElement treeElement = (JobTreeElement) elements[i];
            // Make sure we are not keeping this one
            if (finishedJobs.isKept(treeElement)) {
                Widget item = doFindItem(elements[i]);
                if (item != null) {
                    ((ProgressInfoItem) item).refresh();
                }

            } else {
                Widget item = doFindItem(treeElement);
                if (item == null) {
                    // Is the parent showing?
                    Object parent = treeElement.getParent();
                    if (parent != null)
                        item = doFindItem(parent);
                }
                if (item != null) {
                    unmapElement(elements[i]);
                    item.dispose();
                }
            }
        }

        Control[] existingChildren = control.getChildren();
        for (int i = 0; i < existingChildren.length; i++) {
            ProgressInfoItem item = (ProgressInfoItem) existingChildren[i];
            item.setColor(i);
        }
        control.layout(true);
        updateForShowingProgress();
    }

    @Override
    public void reveal(Object element) {

    }

    @Override
    protected void setSelectionToWidget(@SuppressWarnings("rawtypes") List l, boolean reveal) {

    }

    /**
     * Cancel the current selection
     *
     */
    public void cancelSelection() {

    }

    /**
     * Set focus on the current selection.
     *
     */
    public void setFocus() {
        Control[] children = control.getChildren();
        if (children.length > 0) {
            ((ProgressInfoItem) children[0]).setButtonFocus();
        } else {
            noEntryArea.setFocus();
        }
    }

    /**
     * Refresh everything as the root is being refreshed.
     */
    private void refreshAll() {

        Object[] infos = getSortedChildren(getRoot());
        Control[] existingChildren = control.getChildren();

        for (int i = 0; i < existingChildren.length; i++) {
            existingChildren[i].dispose();

        }

        int maxLength = Math.min(infos.length, MAX_DISPLAYED);
        // Create new ones if required
        for (int i = 0; i < maxLength; i++) {
            ProgressInfoItem item = createNewItem((JobTreeElement) infos[i]);
            item.setColor(i);
        }

        control.layout(true);
        updateForShowingProgress();

    }

    /**
     * Set the virtual items to be visible or not depending on the displayed
     * area.
     */
    private void updateVisibleItems() {
        Control[] children = control.getChildren();
        int top = scrolled.getOrigin().y;
        int bottom = top + scrolled.getParent().getBounds().height;
        for (int i = 0; i < children.length; i++) {
            ProgressInfoItem item = (ProgressInfoItem) children[i];
            item.setDisplayed(top, bottom);

        }
    }

    public ProgressInfoItem[] getProgressInfoItems() {
        Control[] children = control.getChildren();
        ProgressInfoItem[] progressInfoItems = new ProgressInfoItem[children.length];
        System.arraycopy(children, 0, progressInfoItems, 0, children.length);
        return progressInfoItems;
    }

}