org.jboss.tools.runtime.ui.internal.dialogs.RuntimeCheckboxTreeViewer.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.runtime.ui.internal.dialogs.RuntimeCheckboxTreeViewer.java

Source

/*************************************************************************************
 * Copyright (c) 2013 Red Hat, Inc. 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:
 *     JBoss by Red Hat - Initial implementation.
 ************************************************************************************/
package org.jboss.tools.runtime.ui.internal.dialogs;

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

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
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.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.jboss.tools.runtime.core.internal.RuntimeExtensionManager;
import org.jboss.tools.runtime.core.model.IRuntimeDetectionResolution;
import org.jboss.tools.runtime.core.model.RuntimeDefinition;
import org.jboss.tools.runtime.core.model.RuntimeDetectionProblem;
import org.jboss.tools.runtime.core.model.RuntimePath;
import org.jboss.tools.runtime.ui.RuntimeUIActivator;
import org.jboss.tools.runtime.ui.internal.Messages;

public class RuntimeCheckboxTreeViewer extends CheckboxTreeViewer {
    // content assist
    private Shell popupShell;
    private Table popupTable;

    public RuntimeCheckboxTreeViewer(Composite parent, final Set<RuntimePath> runtimePaths2, int heightHint) {
        this(parent, runtimePaths2.toArray(new RuntimePath[runtimePaths2.size()]), heightHint);
    }

    public RuntimeCheckboxTreeViewer(Composite parent, final RuntimePath[] runtimePaths2, int heightHint) {
        super(parent, SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE);

        GridData gd;
        Tree tree = getTree();
        gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        GC gc = new GC(parent);
        FontMetrics fontMetrics = gc.getFontMetrics();
        gc.dispose();
        gd.minimumHeight = Dialog.convertHeightInCharsToPixels(fontMetrics, heightHint);
        tree.setLayoutData(gd);
        tree.setHeaderVisible(true);
        tree.setLinesVisible(true);

        String[] columnNames = new String[] { Messages.RuntimeCheckboxTreeViewer_Name,
                Messages.RuntimeCheckboxTreeViewer_Type, Messages.RuntimeCheckboxTreeViewer_Version,
                Messages.RuntimeCheckboxTreeViewer_Errors, Messages.RuntimeCheckboxTreeViewer_Location };
        int[] columnWidths = new int[] { 200, 70, 60, 150, 150 };

        for (int i = 0; i < columnNames.length; i++) {
            TreeViewerColumn tc = new TreeViewerColumn(this, SWT.NONE);
            tc.getColumn().setText(columnNames[i]);
            tc.getColumn().setWidth(columnWidths[i]);
        }

        setLabelProvider(new RuntimeLabelProvider());
        List<RuntimeDefinition> runtimeDefinitions = new ArrayList<RuntimeDefinition>();
        for (RuntimePath runtimePath : runtimePaths2) {
            runtimeDefinitions.addAll(Arrays.asList(runtimePath.getRuntimeDefinitions()));
        }
        setContentProvider(new RuntimeContentProvider(runtimeDefinitions));
        setInput(runtimeDefinitions);
        for (RuntimeDefinition definition : runtimeDefinitions) {
            setChecked(definition, definition.isEnabled());
        }

        addContentAssist();
    }

    private void addContentAssist() {

        // content assist
        popupShell = new Shell(getTree().getShell(), SWT.ON_TOP | SWT.RESIZE);
        popupShell.setLayout(new FillLayout());
        popupTable = new Table(popupShell, SWT.SINGLE);
        popupShell.setVisible(false);
        getTree().addMouseListener(new MouseAdapter() {
            public void mouseDown(MouseEvent event) {
                if (popupShell.getVisible()) {
                    popupShell.setVisible(false);
                } else {
                    showContentAssist(event);
                }
            }
        });

        getTree().addListener(SWT.KeyDown, new Listener() {
            public void handleEvent(Event event) {
                switch (event.keyCode) {
                case SWT.ARROW_DOWN:
                    int index = (popupTable.getSelectionIndex() + 1) % popupTable.getItemCount();
                    popupTable.setSelection(index);
                    event.doit = false;
                    break;
                case SWT.ARROW_UP:
                    index = popupTable.getSelectionIndex() - 1;
                    if (index < 0)
                        index = popupTable.getItemCount() - 1;
                    popupTable.setSelection(index);
                    event.doit = false;
                    break;
                case SWT.CR:
                    if (popupShell.isVisible() && popupTable.getSelectionIndex() != -1) {
                        event.doit = false;
                        contentAssistChosen();
                    }
                    break;
                case SWT.ESC:
                    popupShell.setVisible(false);
                    break;
                }
            }
        });
        getTree().getShell().addListener(SWT.KeyDown, new Listener() {
            public void handleEvent(Event event) {
                if (popupShell.isVisible()) {
                    if (event.keyCode == SWT.CR || event.keyCode == SWT.ESC) {
                        // pre-empt the wizard from closing
                        event.doit = false;
                    }
                }
            }
        });
        getTree().getShell().addListener(SWT.Traverse, new Listener() {
            public void handleEvent(Event event) {
                if (popupShell.isVisible()) {
                    if (event.detail == SWT.TRAVERSE_ESCAPE) {
                        // pre-empt the wizard from closing
                        event.doit = false;
                    }
                }
            }

        });

        Listener hideUnfocusedPopup = new Listener() {
            public void handleEvent(final Event event) {
                Display.getDefault().asyncExec(new Runnable() {
                    public void run() {
                        Widget w = event.widget;
                        Control control = Display.getDefault().getFocusControl();
                        if (control == null || (control != getTree() && control != popupTable)) {
                            popupShell.setVisible(false);
                        }
                    }
                });
            }
        };
        popupTable.addListener(SWT.KeyDown, new Listener() {
            public void handleEvent(Event event) {
                if (event.keyCode == SWT.ESC) {
                    popupShell.setVisible(false);
                }
            }
        });
        //getTree().addListener(SWT.FocusOut, hideUnfocusedPopup);
        popupTable.addListener(SWT.FocusOut, hideUnfocusedPopup);

        Listener hidePopup = new Listener() {
            public void handleEvent(Event event) {
                popupShell.setVisible(false);
            }
        };
        getTree().getShell().addListener(SWT.Dispose, hidePopup);
        getTree().getShell().addListener(SWT.Move, hidePopup);

        popupTable.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseDoubleClick(MouseEvent e) {
                contentAssistChosen();
            }
        });
    }

    private void contentAssistChosen() {
        int problemIndex = popupTable.getSelectionIndex();
        if (problemIndex != -1) {
            RuntimeDefinition sel = getSelectedDefinition();
            RuntimeDetectionProblem[] s = sel.getProblems();
            if (problemIndex < s.length) {
                // TODO  run the content assist action
                // We now have the runtime definition and the chosen problem to be fixed
                final RuntimeDetectionProblem problem = s[problemIndex];
                IRuntimeDetectionResolution[] resolutions = RuntimeExtensionManager.getDefault()
                        .findResolutions(problem, sel);
                if (resolutions.length > 0) {
                    // For now just execute the first one...  TODO expand
                    resolutions[0].run(problem, sel);

                    // The solution may have fixed several problems, not just one
                    Object[] all = ((ITreeContentProvider) getContentProvider()).getElements(null);
                    for (int i = 0; i < all.length; i++) {
                        if (all[i] instanceof RuntimeDefinition) {
                            ((RuntimeDefinition) all[i]).refreshProblems();
                        }
                    }
                    refresh();
                } else {
                    // Show an error that no resolution could be found
                    popupShell.setVisible(false);
                    StatusDialog d = new StatusDialog(getTree().getShell()) {
                        protected Control createDialogArea(Composite parent) {
                            Composite composite = (Composite) super.createDialogArea(parent);

                            Label label = new Label(composite, SWT.WRAP);
                            GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
                            layoutData.widthHint = convertWidthInCharsToPixels(80);
                            label.setLayoutData(layoutData);
                            label.setText("No quickfixes were found for the problem: " + problem.getDescription());
                            updateStatus(new Status(IStatus.ERROR, RuntimeUIActivator.PLUGIN_ID,
                                    "No quickfixes found for the selected problem"));
                            Dialog.applyDialogFont(composite);
                            return composite;
                        }
                    };
                    d.setTitle("No quickfix available");
                    d.open();
                }
            }
        }
        popupShell.setVisible(false);
    }

    private void showContentAssist(MouseEvent event) {
        Rectangle itemBounds = findItemBounds(event, 3);

        if (itemBounds != null) {
            popupTable.removeAll();
            RuntimeDefinition selected = getSelectedDefinition();
            if (selected != null) {
                RuntimeDetectionProblem[] s = selected.getProblems();
                for (int i = 0; i < s.length; i++) {
                    String text = s[i].getLabel();
                    if (text != null) {
                        int sev = s[i].getSeverity();
                        TableItem ti = new TableItem(popupTable, SWT.NONE);
                        ti.setText(text);
                        Image sevImage = null;
                        if (sev == IStatus.ERROR) {
                            sevImage = PlatformUI.getWorkbench().getSharedImages()
                                    .getImage(ISharedImages.IMG_DEC_FIELD_ERROR);
                        } else if (sev == IStatus.WARNING) {
                            sevImage = PlatformUI.getWorkbench().getSharedImages()
                                    .getImage(ISharedImages.IMG_DEC_FIELD_WARNING);
                        }
                        if (sevImage != null)
                            ti.setImage(sevImage);
                    }
                }
            }

            String[] text = getQuickfixTextForCurrentSelection();
            // Don't show it if we have no errors
            if (text == null || text.length == 0) {
                return;
            }
            for (int i = 0; i < text.length; i++) {
            }
            Rectangle textBounds = Display.getDefault().map(getTree(), null, itemBounds);
            popupShell.setBounds(textBounds.x, textBounds.y + (textBounds.height),
                    textBounds.width > 250 ? textBounds.width : 250, 150);
            popupTable.setEnabled(true);
            popupShell.setVisible(true);
        }
    }

    private String[] getQuickfixTextForCurrentSelection() {
        // TODO Delete this
        RuntimeDefinition selected = getSelectedDefinition();
        if (selected != null) {
            RuntimeDetectionProblem[] s = selected.getProblems();
            ArrayList<String> ret = new ArrayList<String>();
            for (int i = 0; i < s.length; i++) {
                ret.add(s[i].getLabel());
            }
            return (String[]) ret.toArray(new String[ret.size()]);
        }
        return new String[] {};
    }

    private RuntimeDefinition getSelectedDefinition() {
        ISelection sel = getSelection();
        if (sel instanceof IStructuredSelection) {
            Object f = ((IStructuredSelection) sel).getFirstElement();
            if (f instanceof RuntimeDefinition) {
                return ((RuntimeDefinition) f);
            }
        }
        return null;
    }

    private Rectangle findItemBounds(MouseEvent event, int soughtColumn) {
        Point pt = new Point(event.x, event.y);

        TreeItem item = getTree().getItem(pt);
        if (item != null) {
            for (int i = 0, n = getTree().getColumnCount(); i < n; i++) {
                Rectangle rect = item.getBounds(i);
                if (rect.contains(pt)) {
                    if (i == soughtColumn) {
                        return rect;
                    }
                }
            }
        }
        return null;
    }

    // Refresh your input given the following RuntimePath[]
    public void updateInput(RuntimePath[] runtimePaths) {
        setInput(null);
        List<RuntimeDefinition> runtimeDefinitions = new ArrayList<RuntimeDefinition>();
        for (RuntimePath runtimePath : runtimePaths) {
            runtimeDefinitions.addAll(Arrays.asList(runtimePath.getRuntimeDefinitions()));
        }
        setInput(runtimeDefinitions);
        for (RuntimeDefinition runtimeDefinition : runtimeDefinitions) {
            setChecked(runtimeDefinition, runtimeDefinition.isEnabled());
        }
    }
}