org.xmind.ui.internal.dialogs.ProgressDialogPart.java Source code

Java tutorial

Introduction

Here is the source code for org.xmind.ui.internal.dialogs.ProgressDialogPart.java

Source

/*
 * *****************************************************************************
 * * 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.ui.internal.dialogs;

import java.util.Arrays;
import java.util.Comparator;

import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchImages;
import org.eclipse.ui.internal.progress.DetailedProgressViewer;
import org.eclipse.ui.internal.progress.FinishedJobs;
import org.eclipse.ui.internal.progress.JobInfo;
import org.eclipse.ui.internal.progress.JobTreeElement;
import org.eclipse.ui.internal.progress.ProgressManager;
import org.eclipse.ui.internal.progress.ProgressMessages;
import org.eclipse.ui.internal.progress.ProgressViewerContentProvider;
import org.eclipse.ui.internal.util.PrefUtil;
import org.xmind.ui.internal.MindMapMessages;
import org.xmind.ui.internal.e4models.ModelPart;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.resources.ColorUtils;
import org.xmind.ui.resources.FontUtils;

public class ProgressDialogPart extends ModelPart {

    @SuppressWarnings("unchecked")
    private static class ProgressViewerComparator extends ViewerComparator {

        @Override
        @SuppressWarnings("rawtypes")
        public int compare(Viewer testViewer, Object e1, Object e2) {
            return ((Comparable) e1).compareTo(e2);
        }

        @Override
        public void sort(final Viewer viewer, Object[] elements) {
            /*
             * https://bugs.eclipse.org/371354 This ordering is inherently
             * unstable, since it relies on modifiable properties of the
             * elements: E.g. the default implementation in JobTreeElement
             * compares getDisplayString(), many of whose implementations use
             * getPercentDone(). JavaSE 7+'s TimSort introduced a breaking
             * change: It now throws a new IllegalArgumentException for bad
             * comparators. Workaround is to retry a few times.
             */
            for (int retries = 3; retries > 0; retries--) {
                try {
                    Arrays.sort(elements, new Comparator<Object>() {

                        @Override
                        public int compare(Object a, Object b) {
                            return ProgressViewerComparator.this.compare(viewer, a, b);
                        }
                    });
                    return; // success
                } catch (IllegalArgumentException e) {
                    // retry
                }
            }

            // One last try that will log and throw TimSort's IAE if it happens:
            super.sort(viewer, elements);
        }
    }

    private class ProgressViewer extends DetailedProgressViewer {

        private Control nullContentArea;

        public ProgressViewer(Composite parent, int style) {
            super(parent, style);
        }

        @Override
        public void add(Object[] elements) {
            super.add(elements);
            updateForShowingContent();
        }

        @Override
        public void remove(Object[] elements) {
            super.remove(elements);
            updateForShowingContent();
        }

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

        @Override
        protected void internalRefresh(Object element) {
            super.internalRefresh(element);
            updateForShowingContent();
        }

        private void updateForShowingContent() {
            Control control = getControl();
            if (control == null || control.isDisposed()) {
                return;
            }

            if (getContentProvider() == null) {
                return;
            }

            Object[] elements = ((IStructuredContentProvider) getContentProvider()).getElements(getInput());
            if (elements.length != 0) {
                //show content viewer
                if (nullContentArea != null) {
                    nullContentArea.setVisible(false);
                    ((GridData) nullContentArea.getLayoutData()).exclude = true;
                }

                control.setVisible(true);
                ((GridData) control.getLayoutData()).exclude = false;

                if (removeAllHyperlink != null && !removeAllHyperlink.isDisposed()) {
                    removeAllHyperlink.setEnabled(true);
                }

            } else {
                //show null content area
                control.setVisible(false);
                ((GridData) control.getLayoutData()).exclude = true;

                if (nullContentArea == null) {
                    nullContentArea = createNullContentArea(control.getParent());
                }
                nullContentArea.setVisible(true);
                ((GridData) nullContentArea.getLayoutData()).exclude = false;

                if (removeAllHyperlink != null && !removeAllHyperlink.isDisposed()) {
                    removeAllHyperlink.setEnabled(false);
                }
            }

            getControl().getParent().layout();
        }

        private Composite createNullContentArea(Composite parent) {
            Composite composite = new Composite(parent, SWT.NONE);
            composite.setBackground(composite.getParent().getBackground());
            final GridData layoutData = new GridData(GridData.FILL_BOTH);
            composite.setLayoutData(layoutData);
            GridLayout layout = new GridLayout(1, false);
            layout.marginWidth = 0;
            layout.marginHeight = 0;
            layout.verticalSpacing = 0;
            composite.setLayout(layout);

            createNullContent(composite);

            return composite;
        }

        private void createNullContent(Composite parent) {
            Composite composite = new Composite(parent, SWT.NONE);
            composite.setBackground(composite.getParent().getBackground());
            composite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
            GridLayout layout = new GridLayout(1, false);
            layout.marginWidth = 0;
            layout.marginHeight = 0;
            layout.verticalSpacing = 20;
            composite.setLayout(layout);

            Label label = new Label(composite, SWT.NONE);
            label.setBackground(label.getParent().getBackground());
            label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
            label.setImage((Image) resources.get(MindMapUI.getImages().get("progress_no_operations.png", true))); //$NON-NLS-1$

            Composite composite2 = new Composite(composite, SWT.NONE);
            composite2.setBackground(composite2.getParent().getBackground());
            composite2.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
            GridLayout layout2 = new GridLayout(1, false);
            layout2.marginWidth = 0;
            layout2.marginHeight = 0;
            layout2.verticalSpacing = 0;
            composite2.setLayout(layout2);

            Label label2 = new Label(composite2, SWT.NONE);
            label2.setBackground(label2.getParent().getBackground());
            label2.setForeground(resources.createColor(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$
            label2.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
            label2.setText(MindMapMessages.ProgressDialog_NullContet_message);
            label2.setFont(resources.createFont(
                    FontDescriptor.createFrom(FontUtils.relativeHeight(label2.getFont().getFontData(), 1))));
        }
    }

    public static final String CONTEXT_MENU_ID = "org.xmind.ui.ProgressDialog"; //$NON-NLS-1$

    private ResourceManager resources;

    private DetailedProgressViewer viewer;

    private Control control;

    private Hyperlink removeAllHyperlink;

    private Action clearAllAction;

    private Action cancelAction;

    @Override
    protected void createContent(Composite parent) {
        resources = new LocalResourceManager(JFaceResources.getResources(), parent);

        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setBackground((Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$

        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        composite.setLayout(layout);

        createContentsSection(composite);
        createBottomSection(composite);

        this.control = composite;
    }

    private void createContentsSection(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setBackground((Color) resources.get(ColorUtils.toDescriptor("#d8d8d8"))); //$NON-NLS-1$

        GridLayout layout = new GridLayout();
        layout.marginHeight = 1;
        layout.marginWidth = 1;
        layout.verticalSpacing = 0;
        composite.setLayout(layout);

        Composite composite2 = new Composite(composite, SWT.NONE);
        composite2.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite2.setBackground(parent.getBackground());

        GridLayout layout2 = new GridLayout();
        layout2.marginHeight = 0;
        layout2.marginWidth = 0;
        layout2.marginBottom = 0;
        layout2.verticalSpacing = 0;
        layout2.horizontalSpacing = 0;
        composite2.setLayout(layout2);

        createProgressViewerSection(composite2);
        createShowOperationsCheck(composite2);
    }

    protected void createProgressViewerSection(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setBackground(parent.getBackground());

        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.marginBottom = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        composite.setLayout(layout);

        createProgressViewer(composite);
    }

    private void createProgressViewer(Composite parent) {
        viewer = new ProgressViewer(parent, SWT.MULTI | SWT.H_SCROLL);
        viewer.setComparator(new ProgressViewerComparator());
        viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IWorkbenchHelpContextIds.RESPONSIVE_UI);

        initContentProvider();
        createClearAllAction();
        createCancelAction();
        initContextMenu();
        setSelectionProvider(viewer);
    }

    private void createShowOperationsCheck(Composite parent) {
        Composite border = new Composite(parent, SWT.NONE);
        border.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        border.setBackground((Color) resources.get(ColorUtils.toDescriptor("#d8d8d8"))); //$NON-NLS-1$

        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.marginTop = 1;
        layout.marginBottom = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        border.setLayout(layout);

        Composite composite = new Composite(border, SWT.NONE);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        composite.setBackground((Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$

        GridLayout layout2 = new GridLayout();
        layout2.marginHeight = 8;
        layout2.marginWidth = 0;
        layout2.marginTop = 0;
        layout2.marginBottom = 0;
        layout2.verticalSpacing = 0;
        layout2.horizontalSpacing = 0;
        composite.setLayout(layout2);

        Composite composite2 = new Composite(composite, SWT.NONE);
        composite2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        composite2.setBackground(composite.getBackground());

        GridLayout layout3 = new GridLayout(2, false);
        layout3.marginHeight = 0;
        layout3.marginWidth = 15;
        layout3.verticalSpacing = 0;
        layout3.horizontalSpacing = 0;
        composite2.setLayout(layout3);

        final Button showSystemCheck = new Button(composite2, SWT.CHECK);
        showSystemCheck.setBackground(composite2.getBackground());
        showSystemCheck.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
        showSystemCheck.setText(MindMapMessages.ProgressDialog_ShowSystem_check);
        showSystemCheck.setForeground((Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$

        //set initial selection
        boolean showSystemJobs = PrefUtil.getAPIPreferenceStore()
                .getBoolean(IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS);
        showSystemCheck.setSelection(showSystemJobs);

        showSystemCheck.addSelectionListener(new SelectionListener() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                boolean showSystem = showSystemCheck.getSelection();
                PrefUtil.getAPIPreferenceStore().setValue(IWorkbenchPreferenceConstants.SHOW_SYSTEM_JOBS,
                        showSystem);
                viewer.refresh();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
    }

    private void createBottomSection(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        composite.setBackground((Color) resources.get(ColorUtils.toDescriptor("#f3f3f3"))); //$NON-NLS-1$

        GridLayout layout = new GridLayout(2, false);
        layout.marginHeight = 14;
        layout.marginWidth = 0;
        layout.marginRight = 13;
        layout.marginBottom = 1;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        composite.setLayout(layout);

        createRemoveAllHyperlink(composite);
        createButtonBar(composite);
    }

    private void createRemoveAllHyperlink(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        composite.setBackground(parent.getBackground());

        GridLayout layout = new GridLayout(1, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.marginLeft = 35;
        composite.setLayout(layout);

        removeAllHyperlink = new Hyperlink(composite, SWT.NONE);
        removeAllHyperlink.setBackground(composite.getBackground());
        removeAllHyperlink.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false));
        removeAllHyperlink.setText(MindMapMessages.ProgressDialog_RemoveAll_hyperlink);
        removeAllHyperlink.setUnderlined(false);
        removeAllHyperlink.setForeground((Color) resources.get(ColorUtils.toDescriptor("#6484fc"))); //$NON-NLS-1$
        removeAllHyperlink.setFont((Font) resources.get(FontDescriptor
                .createFrom(FontUtils.relativeHeight(removeAllHyperlink.getFont().getFontData(), -1))));

        removeAllHyperlink.addHyperlinkListener(new IHyperlinkListener() {

            public void linkExited(HyperlinkEvent e) {
            }

            public void linkEntered(HyperlinkEvent e) {
            }

            public void linkActivated(HyperlinkEvent e) {
                clearAllAction.run();
            }
        });

        //set hyperlink enabled
        Object[] elements = ((IStructuredContentProvider) viewer.getContentProvider())
                .getElements(viewer.getInput());
        removeAllHyperlink.setEnabled(elements.length != 0);
    }

    private void createButtonBar(Composite parent) {
        Composite buttonBar = new Composite(parent, SWT.NONE);
        buttonBar.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
        buttonBar.setBackground(parent.getBackground());

        GridLayout layout = new GridLayout();
        layout.numColumns = 0;
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 6;
        buttonBar.setLayout(layout);

        createButton(buttonBar, IDialogConstants.CANCEL_ID, IDialogConstants.CLOSE_LABEL, false);
    }

    private Button createButton(Composite parent, int id, String label, boolean defaultButton) {
        // increment the number of columns in the button bar
        ((GridLayout) parent.getLayout()).numColumns++;
        Button button = new Button(parent, SWT.PUSH);
        button.setBackground(parent.getBackground());
        button.setText(label);
        button.setFont(JFaceResources.getDialogFont());
        button.setData(Integer.valueOf(id));
        button.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                buttonPressed(((Integer) event.widget.getData()).intValue());
            }
        });
        if (defaultButton) {
            Shell shell = parent.getShell();
            if (shell != null) {
                shell.setDefaultButton(button);
            }
        }
        setButtonLayoutData(button);
        return button;
    }

    private void setButtonLayoutData(Button button) {
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        data.widthHint = 92;
        button.setLayoutData(data);
    }

    private void buttonPressed(int buttonId) {
        if (IDialogConstants.CANCEL_ID == buttonId) {
            cancelPressed();
        }
    }

    private void cancelPressed() {
        close();
    }

    private void close() {
        if (control != null && !control.isDisposed()) {
            control.getShell().close();
        }
    }

    @Override
    public void setFocus() {
        if (viewer != null) {
            viewer.setFocus();
        }
    }

    /**
     * Sets the content provider for the viewer.
     */
    private void initContentProvider() {
        ProgressViewerContentProvider provider = new ProgressViewerContentProvider(viewer, true, true);
        viewer.setContentProvider(provider);
        viewer.setInput(ProgressManager.getInstance());
    }

    /**
     * Initialize the context menu for the receiver.
     */
    private void initContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        menuMgr.add(cancelAction);
        menuMgr.addMenuListener(new IMenuListener() {

            @Override
            public void menuAboutToShow(IMenuManager manager) {
                JobInfo info = getSelectedInfo();
                if (info == null) {
                    return;
                }
            }
        });
        menuMgr.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        viewer.getControl().setMenu(menu);

        //todo: this may have bug.
        registerContextMenu(viewer.getControl(), CONTEXT_MENU_ID);
    }

    /**
     * Get the currently selected job info. Only return it if it is the only
     * item selected and it is a JobInfo.
     *
     * @return JobInfo
     */
    private JobInfo getSelectedInfo() {
        IStructuredSelection selection = getSelection();
        if (selection != null && selection.size() == 1) {
            JobTreeElement element = (JobTreeElement) selection.getFirstElement();
            if (element instanceof JobInfo) {
                return (JobInfo) element;
            }
        }
        return null;
    }

    /**
     * Return the selected objects. If any of the selections are not JobInfos or
     * there is no selection then return null.
     *
     * @return JobInfo[] or <code>null</code>.
     */
    private IStructuredSelection getSelection() {
        ESelectionService selectionService = getAdapter(ESelectionService.class);
        if (selectionService != null) {
            Object selection = selectionService.getSelection();
            return selection instanceof IStructuredSelection ? (IStructuredSelection) selection : null;
        }

        return null;
    }

    /**
     * Create the cancel action for the receiver.
     */
    private void createCancelAction() {
        cancelAction = new Action(ProgressMessages.ProgressView_CancelAction) {

            @Override
            public void run() {
                viewer.cancelSelection();
            }
        };
    }

    /**
     * Create the clear all action for the receiver.
     */
    private void createClearAllAction() {
        clearAllAction = new Action(ProgressMessages.ProgressView_ClearAllAction) {

            @Override
            public void run() {
                FinishedJobs.getInstance().clearAll();
            }
        };
        clearAllAction.setToolTipText(ProgressMessages.NewProgressView_RemoveAllJobsToolTip);
        ImageDescriptor id = WorkbenchImages.getWorkbenchImageDescriptor("/elcl16/progress_remall.png"); //$NON-NLS-1$
        if (id != null) {
            clearAllAction.setImageDescriptor(id);
        }
        id = WorkbenchImages.getWorkbenchImageDescriptor("/dlcl16/progress_remall.png"); //$NON-NLS-1$
        if (id != null) {
            clearAllAction.setDisabledImageDescriptor(id);
        }
    }

    @Override
    public <T> T getAdapter(Class<T> adapter) {
        if (adapter.isAssignableFrom(DetailedProgressViewer.class)) {
            return adapter.cast(viewer);
        }
        return super.getAdapter(adapter);
    }

}