net.sourceforge.docfetcher.view.ViewerMenuManager.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.docfetcher.view.ViewerMenuManager.java

Source

/*******************************************************************************
 * Copyright (c) 2008 Tran Nam Quang.
 * 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:
 *    Tran Nam Quang - initial API and implementation
 *******************************************************************************/

package net.sourceforge.docfetcher.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sourceforge.docfetcher.enumeration.Key;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;

/**
 * A convenience method for easily adding entries to the context menu of a
 * <tt>TreeViewer</tt>.
 * 
 * @author Tran Nam Quang
 */
public class ViewerMenuManager {

    public interface RootChecker {
        /**
         * Returns whether the given object is a root element.
         */
        public boolean isRoot(Object obj);
    }

    private MenuManager contextMenu;
    private RootChecker rootChecker;
    private List<Action> rootActions = new ArrayList<Action>();
    private List<Action> nonEmptyActions = new ArrayList<Action>();
    private List<Action> singleElementActions = new ArrayList<Action>();
    private Map<Key, Action> keyActionMap = new HashMap<Key, Action>();

    public ViewerMenuManager(Viewer viewer) {
        contextMenu = new MenuManager();
        viewer.getControl().setMenu(contextMenu.createContextMenu(viewer.getControl()));

        // Update enabled state of actions according to current selection
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                StructuredSelection selection = (StructuredSelection) event.getSelection();

                setEnabled(nonEmptyActions, !selection.isEmpty());
                setEnabled(singleElementActions, selection.size() == 1);

                if (rootChecker != null) {
                    List<Object> rootSelection = new ArrayList<Object>(selection.size());
                    Iterator<?> it = selection.iterator();
                    while (it.hasNext()) {
                        Object item = it.next();
                        if (rootChecker.isRoot(item)) // Only enable action for RootScopes (not for other Scopes)
                            rootSelection.add(item);
                    }
                    setEnabled(rootActions, rootSelection.size() > 0);
                }
            }

            private void setEnabled(List<Action> actions, boolean enabled) {
                for (Action action : actions)
                    action.setEnabled(enabled);
            }
        });

        // Activate context menu entries through keyboard shortcuts
        viewer.getControl().addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                Key key = Key.getKey(e.stateMask, e.keyCode);
                if (key == null)
                    return;
                Action action = keyActionMap.get(key);
                if (action != null && action.isEnabled())
                    action.run();
            }
        });
    }

    /**
     * Sets the <tt>RootChecker</tt> to be used to determine whether an element
     * in the <tt>TreeViewer</tt> is a root element. Can be null.
     */
    public void setRootChecker(RootChecker rootChecker) {
        this.rootChecker = rootChecker;
    }

    /**
     * Adds an <tt>Action</tt> to the context menu whose enabled state does not
     * change with the selection on the <tt>TreeViewer</tt>.
     * <p>
     * The <tt>Key</tt> parameter specifies a key to be pressed to activate the
     * given <tt>Action</tt> object. It may be null.
     */
    public void addUnmanagedAction(Action action, Key key) {
        contextMenu.add(action);
        if (key != null)
            keyActionMap.put(key, action);
    }

    /**
     * Adds an <tt>Action</tt> to the context menu that is enabled only if at
     * least one root element of the tree viewer is selected.
     * <p>
     * The <tt>Key</tt> parameter specifies a key to be pressed to activate the
     * given <tt>Action</tt> object. It may be null.
     */
    public void addRootAction(Action action, Key key) {
        rootActions.add(action);
        contextMenu.add(action);
        if (key != null)
            keyActionMap.put(key, action);
    }

    /**
     * Adds an <tt>Action</tt> to the context menu that is enabled only if the
     * current selection on the <tt>TreeViewer</tt> is not empty.
     * <p>
     * The <tt>Key</tt> parameter specifies a key to be pressed to activate the
     * given <tt>Action</tt> object. It may be null.
     */
    public void addNonEmptyAction(Action action, Key key) {
        nonEmptyActions.add(action);
        contextMenu.add(action);
        if (key != null)
            keyActionMap.put(key, action);
    }

    /**
     * Adds an <tt>Action</tt> to the context menu that is enabled only if
     * exactly one element on the <tt>TreeViewer</tt> is selected.
     * <p>
     * The <tt>Key</tt> parameter specifies a key to be pressed to activate the
     * given <tt>Action</tt> object. It may be null.
     */
    public void addSingleElementAction(Action action, Key key) {
        singleElementActions.add(action);
        contextMenu.add(action);
        if (key != null)
            keyActionMap.put(key, action);
    }

    /**
     * Adds a separator to the context menu.
     */
    public void addSeparator() {
        contextMenu.add(new Separator());
    }

    /**
     * Sets the enabled state of all <tt>Action</tt> objects whose enabled
     * states change according to the current selection on the
     * <tt>TreeViewer</tt>.
     */
    public void setManagedActionsEnabled(boolean enabled) {
        for (Action action : rootActions)
            action.setEnabled(enabled);
        for (Action action : nonEmptyActions)
            action.setEnabled(enabled);
        for (Action action : singleElementActions)
            action.setEnabled(enabled);
    }

}