blob: eb3a1067b5172be6abc7923c3275ae4c355d018f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
/**
* The <code>NavigationHistoryAction</code> moves navigation history
* back and forward.
*/
public class NavigationHistoryAction extends PageEventAction {
private boolean recreateMenu;
private boolean forward;
private Menu historyMenu;
private int MAX_HISTORY_LENGTH = 9;
private class MenuCreator implements IMenuCreator {
public void dispose() {
}
public Menu getMenu(Menu parent) {
setMenu(new Menu(parent));
fillMenu(historyMenu);
initMenu();
return historyMenu;
}
public Menu getMenu(Control parent) {
setMenu(new Menu(parent));
fillMenu(historyMenu);
initMenu();
return historyMenu;
}
}
private void setMenu(Menu menu) {
historyMenu = menu;
}
private void initMenu() {
historyMenu.addMenuListener(new MenuAdapter() {
public void menuShown(MenuEvent e) {
if (recreateMenu) {
Menu m = (Menu) e.widget;
MenuItem[] items = m.getItems();
for (int i = 0; i < items.length; i++) {
items[i].dispose();
}
fillMenu(m);
}
}
});
}
private void fillMenu(Menu menu) {
IWorkbenchPage page = getWorkbenchWindow().getActivePage();
if (page == null) {
return;
}
final NavigationHistory history = (NavigationHistory) getWorkbenchWindow()
.getActivePage().getNavigationHistory();
NavigationHistoryEntry[] entries;
if (forward) {
entries = history.getForwardEntries();
} else {
entries = history.getBackwardEntries();
}
int entriesCount[] = new int[entries.length];
for (int i = 0; i < entriesCount.length; i++) {
entriesCount[i] = 1;
}
entries = collapseEntries(entries, entriesCount);
for (int i = 0; i < entries.length; i++) {
if (i > MAX_HISTORY_LENGTH) {
break;
}
String text = entries[i].getHistoryText();
if (text != null) {
MenuItem item = new MenuItem(menu, SWT.NONE);
item.setData(entries[i]);
if (entriesCount[i] > 1) {
text = NLS.bind(WorkbenchMessages.NavigationHistoryAction_locations,text, new Integer(entriesCount[i]));
}
item.setText(text);
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
history
.shiftCurrentEntry(
(NavigationHistoryEntry) e.widget
.getData(), forward);
}
});
}
}
recreateMenu = false;
}
public void dispose() {
super.dispose();
if (historyMenu != null) {
for (int i = 0; i < historyMenu.getItemCount(); i++) {
MenuItem menuItem = historyMenu.getItem(i);
menuItem.dispose();
}
historyMenu.dispose();
historyMenu = null;
}
}
/**
* Create a new instance of <code>NavigationHistoryAction</code>
*
* @param window
* the workbench window this action applies to
* @param forward
* if this action should move history forward of backward
*/
public NavigationHistoryAction(IWorkbenchWindow window, boolean forward) {
super("", window); //$NON-NLS-1$
ISharedImages sharedImages = window.getWorkbench().getSharedImages();
if (forward) {
setText(WorkbenchMessages.NavigationHistoryAction_forward_text);
setToolTipText(WorkbenchMessages.NavigationHistoryAction_forward_toolTip);
// @issue missing action id
window.getWorkbench().getHelpSystem().setHelp(this,
IWorkbenchHelpContextIds.NAVIGATION_HISTORY_FORWARD);
setImageDescriptor(sharedImages
.getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD));
setDisabledImageDescriptor(sharedImages
.getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD_DISABLED));
setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_FORWARD_HISTORY);
} else {
setText(WorkbenchMessages.NavigationHistoryAction_backward_text);
setToolTipText(WorkbenchMessages.NavigationHistoryAction_backward_toolTip);
// @issue missing action id
window.getWorkbench().getHelpSystem().setHelp(this,
IWorkbenchHelpContextIds.NAVIGATION_HISTORY_BACKWARD);
setImageDescriptor(sharedImages
.getImageDescriptor(ISharedImages.IMG_TOOL_BACK));
setDisabledImageDescriptor(sharedImages
.getImageDescriptor(ISharedImages.IMG_TOOL_BACK_DISABLED));
setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_BACKWARD_HISTORY);
}
// WorkbenchHelp.setHelp(this, IHelpContextIds.CLOSE_ALL_PAGES_ACTION);
setEnabled(false);
this.forward = forward;
setMenuCreator(new MenuCreator());
}
/* (non-Javadoc)
* Method declared on PageEventAction.
*/
public void pageClosed(IWorkbenchPage page) {
super.pageClosed(page);
setEnabled(false);
}
private NavigationHistoryEntry[] collapseEntries(
NavigationHistoryEntry[] entries, int entriesCount[]) {
ArrayList allEntries = new ArrayList(Arrays.asList(entries));
NavigationHistoryEntry previousEntry = null;
int i = -1;
for (Iterator iter = allEntries.iterator(); iter.hasNext();) {
NavigationHistoryEntry entry = (NavigationHistoryEntry) iter.next();
if (previousEntry != null) {
String text = previousEntry.getHistoryText();
if (text != null) {
if (text.equals(entry.getHistoryText())
&& previousEntry.editorInfo == entry.editorInfo) {
iter.remove();
entriesCount[i]++;
continue;
}
}
}
previousEntry = entry;
i++;
}
entries = new NavigationHistoryEntry[allEntries.size()];
return (NavigationHistoryEntry[]) allEntries.toArray(entries);
}
/* (non-Javadoc)
* Method declared on PageEventAction.
*/
public void pageActivated(IWorkbenchPage page) {
super.pageActivated(page);
NavigationHistory nh = (NavigationHistory) page.getNavigationHistory();
if (forward) {
nh.setForwardAction(this);
} else {
nh.setBackwardAction(this);
}
}
/* (non-Javadoc)
* Method declared on IAction.
*/
public void run() {
if (getWorkbenchWindow() == null) {
// action has been disposed
return;
}
IWorkbenchPage page = getActivePage();
if (page != null) {
NavigationHistory nh = (NavigationHistory) page
.getNavigationHistory();
if (forward) {
nh.forward();
} else {
nh.backward();
}
recreateMenu = true;
}
}
public void update() {
// Set the enabled state of the action and set the tool tip text. The tool tip
// text is set to reflect the item that one will move back/forward to.
WorkbenchPage page = (WorkbenchPage) getActivePage();
if (page == null) {
return;
}
NavigationHistory history = (NavigationHistory) page
.getNavigationHistory();
NavigationHistoryEntry[] entries;
if (forward) {
setEnabled(history.canForward());
entries = history.getForwardEntries();
if (entries.length > 0) {
NavigationHistoryEntry entry = entries[0];
String text = NLS.bind(WorkbenchMessages.NavigationHistoryAction_forward_toolTipName, entry.getHistoryText() );
setToolTipText(text);
} else {
setToolTipText(WorkbenchMessages.NavigationHistoryAction_forward_toolTip);
}
} else {
setEnabled(history.canBackward());
entries = history.getBackwardEntries();
if (entries.length > 0) {
NavigationHistoryEntry entry = entries[0];
String text = NLS.bind(WorkbenchMessages.NavigationHistoryAction_backward_toolTipName, entry.getHistoryText() );
setToolTipText(text);
} else {
setToolTipText(WorkbenchMessages.NavigationHistoryAction_backward_toolTip);
}
}
recreateMenu = true;
}
}