com.rcpcompany.utils.selection.ControlSelectionProvider.java Source code

Java tutorial

Introduction

Here is the source code for com.rcpcompany.utils.selection.ControlSelectionProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2013 The RCP Company 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:
 *     The RCP Company - initial API and implementation
 *******************************************************************************/
package com.rcpcompany.utils.selection;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.forms.widgets.Section;

/**
 * A selection provider for view parts with more that one viewer. Tracks the
 * focus of the viewers to provide the correct selection.
 */
public class ControlSelectionProvider implements IPostSelectionProvider {

    /**
     * Whether debug is enabled for this provider.
     */
    public static boolean DEBUG = false;

    /**
     * All round listener.
     */
    private class MyListener implements ISelectionChangedListener, FocusListener, Listener {
        private final Control myControl;

        public MyListener(Control control) {
            myControl = control;
        }

        /*
         * @see ISelectionChangedListener#selectionChanged
         */
        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            if (myControl == controlInFocus) {
                fireSelectionChanged();
            }
        }

        @Override
        public void focusGained(FocusEvent e) {
            setFocusControl(myControl);
        }

        @Override
        public void focusLost(FocusEvent e) {
            // do not reset due to focus behavior on GTK
            // fViewerInFocus= null;
        }

        @Override
        public void handleEvent(Event event) {
            if (event.type == SWT.Activate) {
                setFocusControl(myControl);
            }
        }
    }

    private class PostSelectionListener implements ISelectionChangedListener {
        private final Control myControl;

        public PostSelectionListener(Control control) {
            myControl = control;
        }

        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            if (myControl == controlInFocus) {
                firePostSelectionChanged();
            }
        }

    }

    private final Map<Control, ISelectionProvider> selectionProviders = new HashMap<Control, ISelectionProvider>();

    private Control controlInFocus;

    private final ListenerList selectionChangedListeners = new ListenerList();;

    private final ListenerList postSelectionChangedListeners = new ListenerList();;

    public ControlSelectionProvider() {
        debug("created"); //$NON-NLS-1$
    }

    protected void debug(String message) {
        if (DEBUG) {
            System.out.println(this + ": " + message); //$NON-NLS-1$
        }
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + ":" + hashCode(); //$NON-NLS-1$
    }

    /**
     * @param viewers
     *            All viewers that can provide a selection
     * @param viewerInFocus
     *            the viewer currently in focus or <code>null</code>
     */
    public ControlSelectionProvider(StructuredViewer[] viewers, StructuredViewer viewerInFocus) {
        for (final StructuredViewer viewer : viewers) {
            addViewer(viewer);
        }
        if (viewerInFocus != null) {
            setFocusControl(viewerInFocus.getControl());
        }
    }

    /**
     * @param controls
     * @param providers
     */
    public ControlSelectionProvider(Control[] controls, ISelectionProvider[] providers) {
        this();
        Assert.isNotNull(controls);
        Assert.isNotNull(providers);
        Assert.isTrue(controls.length == providers.length);

        for (int i = 0; i < controls.length; i++) {
            addControl(controls[i], providers[i]);
        }
    }

    /**
     * Returns the control that currently has focus.
     * 
     * @return the control or <code>null</code>
     */
    public Control getFocusControl() {
        return controlInFocus;
    }

    /**
     * Returns the selection provider of the current control.
     * 
     * @return the provider or <code>null</code>
     */
    public ISelectionProvider getCurrentSelectionProvider() {
        if (controlInFocus == null)
            return null;

        return selectionProviders.get(controlInFocus);
    }

    /**
     * Adds a new control with a specific provider.
     * 
     * @param control
     *            the control
     * @param provider
     *            the provider
     */
    public void addControl(Control control, ISelectionProvider provider) {
        debug("added(" + control + ", " + provider + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        final MyListener listener = new MyListener(control);
        provider.addSelectionChangedListener(listener);
        selectionProviders.put(control, provider);
        control.addFocusListener(listener);
        control.addListener(SWT.Activate, listener);
        if (control instanceof Section) {
            final Section s = (Section) control;
            for (final Control c : s.getChildren()) {
                c.addListener(SWT.Activate, listener);
            }
        }
        if (provider instanceof IPostSelectionProvider) {
            final IPostSelectionProvider post = (IPostSelectionProvider) provider;
            post.addPostSelectionChangedListener(new PostSelectionListener(control));
        }
    }

    public void addViewer(StructuredViewer viewer) {
        addControl(viewer.getControl(), viewer);
    }

    /**
     * @param control
     */
    public void setFocusControl(Control control) {
        Assert.isNotNull(control);
        if (control == controlInFocus)
            return;
        debug("focus: " + control); //$NON-NLS-1$

        controlInFocus = control;

        if (!control.isFocusControl()) {
            control.setFocus();
        }

        final ISelectionProvider provider = selectionProviders.get(control);
        if (provider == null)
            return;
        fireSelectionChanged();
        firePostSelectionChanged();
    }

    private void fireSelectionChanged() {
        debug("selectionChanged(" + getCurrentSelectionProvider() + ": " + getSelection() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        if (selectionChangedListeners != null) {
            final SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());

            final Object[] listeners = selectionChangedListeners.getListeners();
            for (final Object listener2 : listeners) {
                final ISelectionChangedListener listener = (ISelectionChangedListener) listener2;
                listener.selectionChanged(event);
            }
        }
    }

    private void firePostSelectionChanged() {
        if (postSelectionChangedListeners != null) {
            final SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());

            final Object[] listeners = postSelectionChangedListeners.getListeners();
            for (final Object listener2 : listeners) {
                final ISelectionChangedListener listener = (ISelectionChangedListener) listener2;
                listener.selectionChanged(event);
            }
        }
    }

    @Override
    public void addSelectionChangedListener(ISelectionChangedListener listener) {
        selectionChangedListeners.add(listener);
    }

    @Override
    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
        selectionChangedListeners.remove(listener);
    }

    @Override
    public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
        postSelectionChangedListeners.add(listener);
    }

    @Override
    public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
        postSelectionChangedListeners.remove(listener);
    }

    @Override
    public ISelection getSelection() {
        final ISelectionProvider provider = getCurrentSelectionProvider();
        if (provider == null)
            return StructuredSelection.EMPTY;

        final ISelection selection = provider.getSelection();
        debug("getSelection()=" + selection); //$NON-NLS-1$
        return selection;
    }

    /*
     * @see ISelectionProvider#setSelection
     */
    @Override
    public void setSelection(ISelection selection) {
        final ISelectionProvider provider = getCurrentSelectionProvider();
        if (provider == null)
            return;

        provider.setSelection(selection);
    }
}