package org.xmind.ui.internal.actions; import java.io.File; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.MenuListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.eclipse.ui.internal.IPreferenceConstants; import org.eclipse.ui.internal.WorkbenchPlugin; import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.dialogs.DialogMessages; import org.xmind.ui.internal.editor.WorkbookHistory; import org.xmind.ui.internal.editor.WorkbookHistoryItem; import org.xmind.ui.util.Logger; /** * * @author Frank Shaka * @deprecated Use {@link RecentFileListContributionItem} instead */ public class ReopenWorkbookMenu extends Action implements IWorkbenchAction { private static final String MODIFIED_TIME_KEY = "org.xmind.ui.workbookHistory.lastModifiedTime"; //$NON-NLS-1$ private class WorkbookHistoryMenuCreator implements IMenuCreator, MenuListener { private Menu menu; public void dispose() { if (menu != null) { menu.dispose(); menu = null; } } public Menu getMenu(Control parent) { if (menu != null && !menu.isDisposed()) return menu; menu = new Menu(parent); menu.addMenuListener(this); return menu; } public Menu getMenu(Menu parent) { if (menu != null && !menu.isDisposed()) return menu; menu = new Menu(parent); menu.addMenuListener(this); return menu; } public void menuHidden(MenuEvent e) { } public void menuShown(MenuEvent e) { refreshMenu((Menu) e.widget); } } private IWorkbenchWindow window; public ReopenWorkbookMenu(IWorkbenchWindow window) { this(window, ActionConstants.REOPEN_WORKBOOK_MENU_ID); } public ReopenWorkbookMenu(IWorkbenchWindow window, String id) { super(MindMapMessages.ReopenWorkbookMenu_text); this.window = window; setId(id); setToolTipText(MindMapMessages.ReopenWorkbookMenu_toolTip); setMenuCreator(new WorkbookHistoryMenuCreator()); } public void dispose() { this.window = null; } @Override public void runWithEvent(Event event) { if (event.widget instanceof ToolItem) { showDropDownMenu((ToolItem) event.widget, event); } } private void showDropDownMenu(ToolItem ti, Event e) { IMenuCreator mc = getMenuCreator(); if (mc == null) return; Menu m = mc.getMenu(ti.getParent()); if (m != null) { // position the menu below the drop down item Rectangle r = ti.getBounds(); Point point = ti.getParent() .toDisplay(new Point(r.x, r.y + r.height)); m.setLocation(point.x, point.y); // waiting // for SWT // 0.42 m.setVisible(true); return; // we don't fire the action } } private void refreshMenu(Menu menu) { long lastModifiedTime = WorkbookHistory.getInstance() .getLastModifiedTime(); Object cachedLastModifiedTime = menu.getData(MODIFIED_TIME_KEY); if (cachedLastModifiedTime instanceof Long && ((Long) cachedLastModifiedTime) .longValue() >= lastModifiedTime) return; rebuildMenu(menu); menu.setData(MODIFIED_TIME_KEY, Long.valueOf(lastModifiedTime)); } private void rebuildMenu(Menu menu) { removeAll(menu); fillMenu(menu); if (menu.getItemCount() == 0) { MenuItem placeholder = new MenuItem(menu, SWT.PUSH, 0); placeholder.setText( MindMapMessages.ReopenWorkbookMenu_NoItemsPlaceholder_text); placeholder.setEnabled(false); } } private void removeAll(Menu menu) { int total = menu.getItemCount(); for (int i = total; i > 0; i--) { menu.getItem(i - 1).dispose(); } } private void fillMenu(Menu menu) { if (window == null || window.getActivePage() == null) return; int itemsToShow = WorkbenchPlugin.getDefault().getPreferenceStore() .getInt(IPreferenceConstants.RECENT_FILES); if (itemsToShow <= 0) return; WorkbookHistoryItem[] items = WorkbookHistory.getInstance() .getTopItems(itemsToShow); if (items.length == 0) return; int index = fillWithItems(menu, 0, items); if (menu.getItemCount() > 0) { new MenuItem(menu, SWT.SEPARATOR, index); ++index; fillClearItem(menu, index); } } private int fillWithItems(Menu menu, int index, WorkbookHistoryItem[] items) { Object[] paths = getDisambiguatedPaths(items); for (int i = 0; i < items.length; i++) { WorkbookHistoryItem item = items[i]; fillWithItem(menu, index, item, i, paths[i].toString()); ++index; } return index; } private void fillWithItem(Menu menu, int menuItemIndex, final WorkbookHistoryItem item, int itemIndex, String path) { MenuItem mi = new MenuItem(menu, SWT.PUSH, menuItemIndex); mi.setText(path); mi.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { reopen(item); } }); } private int fillClearItem(Menu menu, int index) { MenuItem mi = new MenuItem(menu, SWT.PUSH, index); mi.setText(MindMapMessages.ReopenWorkbookMenu_ClearListAction_text); mi.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { clear(); } }); ++index; return index; } private static class FileDissection { String head; String neck; File body; public FileDissection(File file) { this.head = file.getName(); this.neck = null; this.body = file.getParentFile(); } public void increaseNeck() { if (body == null) return; String name = body.getName(); body = body.getParentFile(); if (neck == null) { neck = name; } else { neck = name + File.separator + neck; } } public boolean canDisambiguateWith(FileDissection that) { return that != null && this.head.equals(that.head) && (this.neck == null || this.neck == that.neck || (this.neck != null && this.neck.equals(that.neck))) && (this.body != null || that.body != null); } @Override public String toString() { return neck == null ? head : String.format("%2$s - %3$s", File.separator, head, neck); //$NON-NLS-1$ } } private Object[] getDisambiguatedPaths(WorkbookHistoryItem[] items) { Object[] paths = new Object[items.length]; List<FileDissection> files = new ArrayList<FileDissection>( items.length); for (int i = 0; i < items.length; i++) { WorkbookHistoryItem item = items[i]; String uri = item.getURI(); String path = item.getPath(); if (uri.equals(path)) { // Workbook loaded from a URL: paths[i] = uri; } else { // Workbook loaded form a local file: FileDissection file = new FileDissection(new File(path)); paths[i] = file; files.add(file); } } for (int i = 1; i < files.size(); i++) { FileDissection file1 = files.get(i); for (int j = 0; j < i; j++) { FileDissection file2 = files.get(j); while (file1.canDisambiguateWith(file2)) { file1.increaseNeck(); file2.increaseNeck(); } } } return paths; } private void reopen(final WorkbookHistoryItem item) { if (window == null) return; IWorkbenchPage page = window.getActivePage(); if (page == null) return; if (item.getExistingEditorInput() != null) { IEditorPart editor = page.findEditor(item.getExistingEditorInput()); if (editor != null) { page.activate(editor); return; } } try { item.reopen(page); } catch (CoreException e) { Logger.log(e); } } private void clear() { if (window == null) return; if (!MessageDialog.openConfirm(window.getShell(), DialogMessages.ConfirmClearRecentFileListDialog_title, DialogMessages.ConfirmClearRecentFileListDialog_message)) return; WorkbookHistory.getInstance().clear(); } }