blob: 6b5578df811234c50678b89234fbe58293eda1b9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 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 org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.osgi.util.NLS;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
/**
* A dynamic menu item which supports to switch to other Windows.
*/
public class ReopenEditorMenu extends ContributionItem {
private IWorkbenchWindow window;
private EditorHistory history;
private boolean showSeparator;
private boolean dirty = true;
private IMenuListener menuListener = new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
manager.markDirty();
dirty = true;
}
};
// the maximum length for a file name; must be >= 4
private static final int MAX_TEXT_LENGTH = 40;
// only assign mnemonic to the first nine items
private static final int MAX_MNEMONIC_SIZE = 9;
/**
* Create a new instance.
* @param window the window on which the menu is to be created
* @param id menu's id
* @param showSeparator whether or not to show a separator
*/
public ReopenEditorMenu(IWorkbenchWindow window, String id,
boolean showSeparator) {
super(id);
this.window = window;
this.showSeparator = showSeparator;
history = ((Workbench) window.getWorkbench()).getEditorHistory();
}
/**
* Returns the text for a history item. This may be truncated to fit
* within the MAX_TEXT_LENGTH.
*/
private String calcText(int index, EditorHistoryItem item) {
StringBuffer sb = new StringBuffer();
int mnemonic = index + 1;
sb.append(mnemonic);
if (mnemonic <= MAX_MNEMONIC_SIZE) {
sb.insert(sb.length() - (mnemonic + "").length(), '&'); //$NON-NLS-1$
}
sb.append(" "); //$NON-NLS-1$
// IMPORTANT: avoid accessing the item's input since
// this can require activating plugins.
// Instead, ask the item for the info, which can
// consult its memento if it is not restored yet.
String fileName = item.getName();
String pathName = item.getToolTipText();
if (pathName.equals(fileName)) {
// tool tip text isn't necessarily a path;
// sometimes it's the same as name, so it shouldn't be treated as a path then
pathName = ""; //$NON-NLS-1$
}
IPath path = new Path(pathName);
// if last segment in path is the fileName, remove it
if (path.segmentCount() > 1
&& path.segment(path.segmentCount() - 1).equals(fileName)) {
path = path.removeLastSegments(1);
pathName = path.toString();
}
if ((fileName.length() + pathName.length()) <= (MAX_TEXT_LENGTH - 4)) {
// entire item name fits within maximum length
sb.append(fileName);
if (pathName.length() > 0) {
sb.append(" ["); //$NON-NLS-1$
sb.append(pathName);
sb.append("]"); //$NON-NLS-1$
}
} else {
// need to shorten the item name
int length = fileName.length();
if (length > MAX_TEXT_LENGTH) {
// file name does not fit within length, truncate it
sb.append(fileName.substring(0, MAX_TEXT_LENGTH - 3));
sb.append("..."); //$NON-NLS-1$
} else if (length > MAX_TEXT_LENGTH - 7) {
sb.append(fileName);
} else {
sb.append(fileName);
int segmentCount = path.segmentCount();
if (segmentCount > 0) {
length += 7; // 7 chars are taken for " [...]"
sb.append(" ["); //$NON-NLS-1$
// Add first n segments that fit
int i = 0;
while (i < segmentCount && length < MAX_TEXT_LENGTH) {
String segment = path.segment(i);
if (length + segment.length() < MAX_TEXT_LENGTH) {
sb.append(segment);
sb.append(IPath.SEPARATOR);
length += segment.length() + 1;
i++;
} else if (i == 0) {
// append at least part of the first segment
sb.append(segment.substring(0, MAX_TEXT_LENGTH
- length));
length = MAX_TEXT_LENGTH;
break;
} else {
break;
}
}
sb.append("..."); //$NON-NLS-1$
i = segmentCount - 1;
// Add last n segments that fit
while (i > 0 && length < MAX_TEXT_LENGTH) {
String segment = path.segment(i);
if (length + segment.length() < MAX_TEXT_LENGTH) {
sb.append(IPath.SEPARATOR);
sb.append(segment);
length += segment.length() + 1;
i--;
} else {
break;
}
}
sb.append("]"); //$NON-NLS-1$
}
}
}
return TextProcessor.process(sb.toString(), TextProcessor.getDefaultDelimiters() + "[]");//$NON-NLS-1$
}
/**
* Fills the given menu with
* menu items for all windows.
*/
public void fill(final Menu menu, int index) {
if (window.getActivePage() == null
|| window.getActivePage().getPerspective() == null) {
return;
}
if (getParent() instanceof MenuManager) {
((MenuManager) getParent()).addMenuListener(menuListener);
}
int itemsToShow = WorkbenchPlugin.getDefault().getPreferenceStore()
.getInt(IPreferenceConstants.RECENT_FILES);
if (itemsToShow == 0) {
return;
}
// Get items.
EditorHistoryItem[] historyItems = history.getItems();
int n = Math.min(itemsToShow, historyItems.length);
if (n <= 0) {
return;
}
if (showSeparator) {
new MenuItem(menu, SWT.SEPARATOR, index);
++index;
}
final int menuIndex[] = new int[] { index };
for (int i = 0; i < n; i++) {
final EditorHistoryItem item = historyItems[i];
final int historyIndex = i;
SafeRunner.run(new SafeRunnable() {
public void run() throws Exception {
String text = calcText(historyIndex, item);
MenuItem mi = new MenuItem(menu, SWT.PUSH, menuIndex[0]);
++menuIndex[0];
mi.setText(text);
mi.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
open(item);
}
});
}
public void handleException(Throwable e) {
// just skip the item if there's an error,
// e.g. in the calculation of the shortened name
WorkbenchPlugin.log(getClass(), "fill", e); //$NON-NLS-1$
}
});
}
dirty = false;
}
/**
* Overridden to always return true and force dynamic menu building.
*/
public boolean isDirty() {
return dirty;
}
/**
* Overridden to always return true and force dynamic menu building.
*/
public boolean isDynamic() {
return true;
}
/**
* Reopens the editor for the given history item.
*/
private void open(EditorHistoryItem item) {
IWorkbenchPage page = window.getActivePage();
if (page != null) {
try {
String itemName = item.getName();
if (!item.isRestored()) {
item.restoreState();
}
IEditorInput input = item.getInput();
IEditorDescriptor desc = item.getDescriptor();
if (input == null || desc == null) {
String title = WorkbenchMessages.OpenRecent_errorTitle;
String msg = NLS.bind(WorkbenchMessages.OpenRecent_unableToOpen, itemName );
MessageDialog.openWarning(window.getShell(), title, msg);
history.remove(item);
} else {
page.openEditor(input, desc.getId());
}
} catch (PartInitException e2) {
String title = WorkbenchMessages.OpenRecent_errorTitle;
MessageDialog.openWarning(window.getShell(), title, e2
.getMessage());
history.remove(item);
}
}
}
}