org.jboss.tools.openshift.internal.common.ui.utils.UIUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.openshift.internal.common.ui.utils.UIUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2011-2016 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is 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:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.jboss.tools.openshift.internal.common.ui.utils;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.action.ContributionManager;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.menus.IMenuService;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.jboss.tools.foundation.ui.widget.IWidgetVisitor;
import org.jboss.tools.foundation.ui.widget.WidgetVisitorUtility;

/**
 * @author Andr Dietisheim
 */
public class UIUtils {

    public static final String PACKAGE_EXPLORER_ID = "org.eclipse.jdt.ui.PackageExplorer";
    public static final String PROJECT_EXPLORER_ID = "org.eclipse.ui.navigator.ProjectExplorer";
    public static final String RESOURCE_NAVIGATOR_ID = "org.eclipse.ui.views.ResourceNavigator";

    public static void selectAllOnFocus(final Text text) {
        final FocusListener onFocus = new FocusAdapter() {

            @Override
            public void focusGained(FocusEvent e) {
                text.selectAll();
            }
        };
        text.addFocusListener(onFocus);
        text.addDisposeListener(new DisposeListener() {

            @Override
            public void widgetDisposed(DisposeEvent e) {
                text.removeFocusListener(onFocus);
            }
        });
    }

    /**
     * Ensures that the given text gets the focus if the given button is
     * selected.
     * 
     * @param button
     * @param text
     */
    public static void focusOnSelection(final Button button, final Text text) {
        final Listener onSelect = new Listener() {

            @Override
            public void handleEvent(Event event) {
                if (!button.getSelection()) {
                    // button was deselected, got selected
                    text.selectAll();
                    text.setFocus();
                }
            }
        };
        button.addListener(SWT.Selection, onSelect);
        button.addDisposeListener(new DisposeListener() {

            @Override
            public void widgetDisposed(DisposeEvent e) {
                button.removeListener(SWT.Selection, onSelect);
            }
        });
    }

    /**
     * Register a {@link ContributionManager}. The contribution manager gets
     * unregistered on control disposal
     * 
     * @param id
     *            the id
     * @param contributionManager
     *            the contribution manager
     * @param control
     *            the control
     * 
     * @see ContributionManager
     * @see IMenuService
     * @see DisposeListener
     */
    public static void registerContributionManager(final String id, final IContributionManager contributionManager,
            final Control control) {
        Assert.isNotNull(id);
        Assert.isNotNull(contributionManager);
        Assert.isTrue(control != null && !control.isDisposed());

        final IMenuService menuService = (IMenuService) PlatformUI.getWorkbench().getService(IMenuService.class);
        menuService.populateContributionManager((ContributionManager) contributionManager, id);
        contributionManager.update(true);
        control.addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent e) {
                menuService.releaseContributions((ContributionManager) contributionManager);
            }
        });
    }

    /**
     * Creates context menu to a given control.
     * 
     * @param control
     *            the control
     * 
     * @return the i menu manager
     */
    public static IMenuManager createContextMenu(final Control control) {
        Assert.isTrue(control != null && !control.isDisposed());

        MenuManager menuManager = new MenuManager();
        menuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

        Menu menu = menuManager.createContextMenu(control);
        control.setMenu(menu);
        return menuManager;
    }

    public static void doForAllChildren(IWidgetVisitor visitor, Composite composite) {
        // assuming it is intentional to not visit the root composite
        new WidgetVisitorUtility(false).accept(composite, visitor);
    }

    public static void enableAllChildren(boolean enabled, Composite composite) {
        // Calling in this fashion to avoid change in behavior. I'm unsure if 
        // it was intentionally coded to avoid visiting root element, or if that was
        // just by chance. 
        new WidgetVisitorUtility(false).setEnablementRecursive(composite, enabled);
    }

    public static Shell getShell() {
        Shell shell = null;
        final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window != null) {
            shell = window.getShell();
        }
        return shell;
    }

    public static boolean isFirstElementOfType(Class<?> clazz, ISelection selection) {
        return getFirstElement(selection, clazz) != null;
    }

    public static <E> E getFirstElement(ISelection selection, Class<E> clazz) {
        return adapt(getFirstElement(selection), clazz);
    }

    public static <E> E adapt(Object object, Class<E> clazz) {
        return Adapters.adapt(object, clazz);
    }

    @SuppressWarnings("unchecked")
    public static <E> E[] getElements(ISelection selection, Class<E> clazz) {
        ArrayList<E> elements = new ArrayList<>();

        for (Object element : getElements(selection)) {
            E adapted = Adapters.adapt(element, clazz);
            if (adapted != null)
                elements.add(adapted);
        }
        return elements.toArray((E[]) Array.newInstance(clazz, 0));
    }

    public static Object getFirstElement(ISelection selection) {
        if (!(selection instanceof IStructuredSelection)) {
            return null;
        }
        return ((IStructuredSelection) selection).getFirstElement();
    }

    public static Object[] getElements(ISelection selection) {
        if (!(selection instanceof IStructuredSelection)) {
            return new Object[0];
        }
        return ((IStructuredSelection) selection).toArray();
    }

    public static boolean areNumOfElementsSelected(int numOf, ISelection selection) {
        if (!(selection instanceof IStructuredSelection)) {
            return false;
        }

        return ((IStructuredSelection) selection).size() == numOf;
    }

    public static boolean isSingleSelection(ISelection selection) {
        return areNumOfElementsSelected(1, selection);
    }

    /**
     * Returns the first selected element that's of the given type, in the view identified by the given id.
     * Returns {@code null} if the view is not opened, doesn't exist or the selected element is not of the requested type.
     * 
     * @param viewId the id of the view whose selection we'll look at
     * @param clazz the type of selected item that you get
     * @return the selected item of the given type in the given view. 
     */
    public static <T> T getFirstSelectedElement(String viewId, Class<T> clazz) {
        IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        ISelection selection = workbenchWindow.getSelectionService().getSelection(viewId);
        return getFirstElement(selection, clazz);
    }

    /**
     * Returns the 1st project that's selected in the following views (in a fallback order):
     * <ul>
     * <li>package explorer</li>
     * <li>project explorer</li>
     * <li>resource navigator</li>
     * </ul>
     * @return the project selected in package-, project-explorer or navigator (in this order of prescedence).
     */
    public static IProject getFirstSelectedWorkbenchProject() {
        IViewPart part = getVisibleProjectsView();
        if (part == null) {
            return null;
        }
        return getFirstSelectedElement(part.getSite().getId(), IProject.class);
    }

    /**
     * Returns the 1st visible part among the following ones:
     * <ul>
     * <li>package explorer</li>
     * <li>project explorer</li>
     * <li>resource navigator</li>
     * </ul>
     * @return
     */
    public static IViewPart getVisibleProjectsView() {
        return getFirstVisibleViewPart(PACKAGE_EXPLORER_ID, PROJECT_EXPLORER_ID, RESOURCE_NAVIGATOR_ID);
    }

    public static IViewPart getFirstVisibleViewPart(String... partIds) {
        List<IViewPart> parts = getVisibleViewParts(partIds);
        if (parts.isEmpty()) {
            return null;
        }
        return parts.get(0);
    }

    /**
     * Returns the visible workbench parts which match the given ids. If no ids
     * are given all visible parts are returned.
     * 
     * @param partIds
     * @return
     * 
     * @see IWorkbenchPart
     */
    public static List<IViewPart> getVisibleViewParts(String... partIds) {
        IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        IWorkbenchPage page = workbenchWindow.getActivePage();
        final List<String> partIdsList = new ArrayList<>();
        List<IViewPart> parts = null;
        if (partIds != null) {
            parts = new ArrayList<>(partIds.length);
        }

        for (IViewReference viewReference : page.getViewReferences()) {
            String partId = viewReference.getId();
            if (partIdsList == null || partIdsList.isEmpty() || partIdsList.contains(partId)) {
                IViewPart part = viewReference.getView(false);
                if (part != null && page.isPartVisible(part)) {
                    parts.add(part);
                }
            }
        }

        parts.stream().sorted((part1, part2) -> {
            int indexPart1 = partIdsList.indexOf(part1.getSite().getId());
            int indexPart2 = partIdsList.indexOf(part1.getSite().getId());
            if (indexPart1 > indexPart2) {
                return 1;
            } else {
                return -1;
            }
        });

        return parts;
    }

    public static void copyBackground(Control source, Control destination) {
        destination.setBackground(source.getBackground());
    }

    public static void copyMenuOf(Control source, final Control target) {
        Menu menu = source.getMenu();
        if (menu != null) {
            target.setMenu(menu);
        }
    }

    public static void ensureDisplayExec(Runnable runnable) {
        Display display = Display.getCurrent();
        if (display == null) {
            Display.getDefault().asyncExec(runnable);
        } else {
            runnable.run();
        }
    }

    public static Text createSearchText(Composite parent) {
        final Text searchText = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL | SWT.ICON_SEARCH);
        searchText.setMessage("type filter text");
        searchText.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
                if (e.detail == SWT.CANCEL) {
                    searchText.setText("");
                }
            }
        });
        return searchText;
    }

    /**
     * Sets the visibility of the given control, its {@link GridData#exclude} and relayouts its parent.
     * 
     * @param visible
     * @param control
     */
    public static void setVisibleAndExclude(boolean visible, final Control control) {
        Assert.isLegal(control != null && !control.isDisposed());
        Assert.isLegal(control.getLayoutData() instanceof GridData);

        control.setVisible(visible);
        ((GridData) control.getLayoutData()).exclude = !visible;
        control.getParent().layout();
    }

    public static <T> ISelection createSelection(T selectedObject) {
        ISelection selection = new StructuredSelection();
        if (selectedObject != null) {
            selection = new StructuredSelection(selectedObject);
        }
        return selection;
    }

    /**
     * Sets the standard width to the given button if it's layouted via
     * {@code GridLayout}}.
     * 
     * @param button
     */
    public static void setDefaultButtonWidth(Button button) {
        assertCanSetGridData(button);
        ((GridData) button.getLayoutData()).widthHint = convertHorizontalDLUsToPixels(button,
                IDialogConstants.BUTTON_WIDTH);
    }

    /**
     * Sets equal width to all buttons in the array, which is the maximum
     * of the standard default button width and the required (computed) button width
     * for the most wide of the buttons.
     * Throws IllegalArgumentException if a button is disposed or does not have GridData.
     * 
     * @param button
     */
    public static void setEqualButtonWidth(Button... buttons) {
        if (buttons == null || buttons.length == 0) {
            return;
        }
        int width = convertHorizontalDLUsToPixels(buttons[0], IDialogConstants.BUTTON_WIDTH);
        for (Button button : buttons) {
            assertCanSetGridData(button);
            int w = button.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
            if (width < w) {
                width = w;
            }
        }
        for (Button button : buttons) {
            ((GridData) button.getLayoutData()).widthHint = width;
        }
    }

    private static void assertCanSetGridData(Button button) {
        Assert.isLegal(!DisposeUtils.isDisposed(button), "Button is disposed");
        Assert.isLegal(button.getLayoutData() instanceof GridData,
                "Button " + button.getText() + " is not layouted with a GridLayout");
    }

    private static int convertHorizontalDLUsToPixels(Control control, int dlus) {
        GC gc = new GC(control);
        gc.setFont(control.getFont());
        int averageWidth = gc.getFontMetrics().getAverageCharWidth();
        gc.dispose();

        double horizontalDialogUnitSize = averageWidth * 0.25;

        return (int) Math.round(dlus * horizontalDialogUnitSize);
    }

    /**
     * Create a file selection dialog.
     * 
     * @param selectedFile the initial selected file. May be null
     * @param title the title of the dialog
     * @param message the message of the dialog
     * @param extension the extension to filter. If null or empty, all files are accepted
     * @param initialSelection the initial selection resource (used if selectedFile is null)
     * @return the dialog
     */
    public static ElementTreeSelectionDialog createFileDialog(String selectedFile, String title, String message,
            String extension, IResource initialSelection) {
        ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(),
                new WorkbenchContentProvider());
        dialog.setTitle(title);
        dialog.setMessage(message);
        dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
        dialog.addFilter(new ViewerFilter() {

            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
                return element instanceof IContainer || (element instanceof IFile && (StringUtils.isEmpty(extension)
                        || extension.equals(((IFile) element).getFileExtension())));
            }
        });
        dialog.setAllowMultiple(false);
        if (StringUtils.isNotBlank(selectedFile)) {
            String prefix = "${workspace_loc:";
            String path = selectedFile;
            if (selectedFile.startsWith(prefix) && selectedFile.endsWith("}")) {
                path = path.substring(prefix.length(), path.length() - 1);
            }
            initialSelection = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
        }
        if (initialSelection != null) {
            dialog.setInitialSelection(initialSelection);
        }

        return dialog;
    }

}