blob: 4e307e78efc378d1c4f1d5f7ac4e9b008abf0263 [file] [log] [blame]
package org.eclipse.ui.internal;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import org.eclipse.core.runtime.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
/**
* A dynamic menu item which supports to switch to other Windows.
*/
public class ReopenEditorMenu extends ContributionItem {
private WorkbenchWindow fWindow;
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.
*/
public ReopenEditorMenu(WorkbenchWindow window, EditorHistory history, boolean showSeparator) {
super("Reopen Editor"); //$NON-NLS-1$
fWindow = window;
this.history = history;
this.showSeparator = showSeparator;
}
/**
* 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 = "";
}
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 sb.toString();
}
/**
* Fills the given menu with
* menu items for all windows.
*/
public void fill(final Menu menu, int index) {
if (fWindow.getActivePage() == null
|| fWindow.getActivePage().getPerspective() == null)
return;
if(getParent() instanceof MenuManager)
((MenuManager)getParent()).addMenuListener(menuListener);
if(!dirty)
return;
// Get items.
EditorHistoryItem[] array = history.getItems();
// If no items return.
if (array.length <= 0) {
return;
}
// Add separator.
if (showSeparator) {
new MenuItem(menu, SWT.SEPARATOR, index);
++index;
}
final int menuIndex[] = new int[]{index};
// Add one item for each item.
for (int i = 0; i < array.length; i++) {
final EditorHistoryItem item = array[i];
final int historyIndex = i;
Platform.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("Error in ReopenEditorMenu.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.
*/
void open(EditorHistoryItem item) {
IWorkbenchPage page = fWindow.getActivePage();
if (page != null) {
try {
// Fix for 1GF6HQ1: ITPUI:WIN2000 - NullPointerException: opening a .ppt file
// Descriptor is null if opened on OLE editor.
if (!item.isRestored()) {
item.restoreState();
}
IEditorInput input = item.getInput();
IEditorDescriptor desc = item.getDescriptor();
if (input == null) {
String title = WorkbenchMessages.getString("OpenRecent.errorTitle"); //$NON-NLS-1$
MessageDialog.openWarning(fWindow.getShell(), title, "");
history.remove(item);
}
else {
if (desc == null) {
// There's no openEditor(IEditorInput) call, and openEditor(IEditorInput, String)
// doesn't allow null id.
// However, if id is null, the editor input must be an IFileEditorInput,
// so we can use openEditor(IFile).
// Do nothing if for some reason input was not an IFileEditorInput.
if (input instanceof IFileEditorInput) {
page.openEditor(((IFileEditorInput) input).getFile());
}
} else {
page.openEditor(input, desc.getId());
}
}
} catch (PartInitException e2) {
String title = WorkbenchMessages.getString("OpenRecent.errorTitle"); //$NON-NLS-1$
MessageDialog.openWarning(fWindow.getShell(), title, e2.getMessage());
history.remove(item);
}
}
}
}