/******************************************************************************* * Copyright (C) 2003-2007, 2013, Guillaume Brocker * * 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: * Guillaume Brocker - Initial API and implementation * ******************************************************************************/ package eclox.ui.editor.advanced; import java.util.Stack; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import eclox.core.doxyfiles.Setting; /** * Implements an action that trigger the navigation in the selection history. * This class is used to contribute to the form's action bar manager. * * @author Guillaume Brocker */ class HistoryAction extends Action { /** * Implements a menu listener used to trigger selection changes */ private class MySelectionListener implements SelectionListener { /** * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } /** * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) */ public void widgetSelected(SelectionEvent e) { assert e.widget instanceof MenuItem; MenuItem menuItem = (MenuItem) e.widget; NavigableSelection selection = (NavigableSelection) menuItem.getData(); masterPart.setSelection(selection, true); } } /** * Implements the menu creator tha will create the menu for the action. */ private class MyMenuCreator implements IMenuCreator { private Menu menu; /** * @see org.eclipse.jface.action.IMenuCreator#dispose() */ public void dispose() { if( menu != null ) { menu.dispose(); } } /** * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control) */ public Menu getMenu(Control parent) { if( menu == null ) { menu = new Menu(parent); } fill(menu); return menu; } /** * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu) */ public Menu getMenu(Menu parent) { if( menu == null ) { menu = new Menu(parent); } fill(menu); return menu; } /** * Fills the menu with navigation history. * * @param menu the menu to full */ private void fill(Menu menu) { // Clears the menu content. MenuItem [] items = menu.getItems(); for( int i = 0; i != items.length; ++i ) { items[i].dispose(); } // Fills the menu content. NavigableSelection currentSelection = getFollowingSelection(selection); while(currentSelection != null) { Setting setting = (Setting) currentSelection.getFirstElement(); MenuItem menuItem = new MenuItem(menu, 0); menuItem.setText( setting.hasProperty(Setting.TEXT) ? setting.getProperty(Setting.TEXT) : setting.getIdentifier() ); menuItem.setData(currentSelection); menuItem.addSelectionListener(new MySelectionListener()); currentSelection = getFollowingSelection(currentSelection); } } /** * Retrieves the selection following the given one, according * to the current action's direction. * * @param selection a reference selection * * @return the following selection or null if none */ private NavigableSelection getFollowingSelection( NavigableSelection selection ) { return (direction == BACK) ? selection.getPreviousSelection() : selection.getNextSelection(); } } /** defines the back navigation direction */ public static final int BACK = 0; /** defines the forward navigation direction */ public static final int FORWARD = 1; /** the direction of the navigation assigned to the action */ private int direction; /** the master part that holds the nivation history */ private MasterPart masterPart; /** the current selection */ private NavigableSelection selection; /** * Constructor * * @param direction the navigation direction for the action * @param masterPart the master part that manage the action */ public HistoryAction(int direction, MasterPart masterPart) { super(new String(), IAction.AS_DROP_DOWN_MENU); assert masterPart != null; this.direction = direction; this.masterPart = masterPart; setMenuCreator(new MyMenuCreator()); } /** * @see org.eclipse.jface.action.Action#run() */ public void run() { switch(direction) { case BACK: masterPart.setSelection( selection.getPreviousSelection(), true ); break; case FORWARD: masterPart.setSelection( selection.getNextSelection(), true ); break; } } /** * Tells the action that the selection changed * * @param newSelection the new selection */ public void selectionChanged(ISelection newSelection) { assert newSelection instanceof NavigableSelection; selection = (NavigableSelection) newSelection; Stack<Object> sideElements = direction == BACK ? selection.getPreviousElements() : selection.getNextElements(); if( sideElements.isEmpty() ) { setEnabled(false); setText(new String()); } else { Setting setting = (Setting) sideElements.peek(); setEnabled(true); setText("Go to " + setting.getProperty(Setting.TEXT)); } } }