| /******************************************************************************* |
| * Copyright (c) 2002, 2004 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.cheatsheets.actions; |
| |
| import java.text.Collator; |
| import java.util.*; |
| import java.util.List; |
| |
| import org.eclipse.jface.action.ContributionItem; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.*; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.ui.*; |
| |
| import org.eclipse.ui.cheatsheets.*; |
| import org.eclipse.ui.internal.cheatsheets.*; |
| import org.eclipse.ui.internal.cheatsheets.registry.*; |
| import org.eclipse.ui.internal.cheatsheets.views.CheatSheetView; |
| |
| /** |
| * A menu for cheatsheet selection. |
| * <p> |
| * A <code>CheatSheetMenu</code> is used to populate a menu with |
| * cheatsheet items. If the user selects one of these items |
| * an action is performed to launch the selected cheatsheet. |
| * </p><p> |
| * The visible cheatsheet items within the menu are dynamic and reflect the |
| * available set. The available set consists of a limited combination of |
| * the most recently used cheatsheet list and the currently available |
| * cheatsheet. |
| * </p> |
| */ |
| public class CheatSheetMenu extends ContributionItem { |
| private static final int MAX_CHEATSHEET_ITEMS = 5; |
| private static CheatSheetRegistryReader reg; |
| |
| private boolean showActive = false; |
| |
| private Comparator comparator = new Comparator() { |
| private Collator collator = Collator.getInstance(); |
| |
| public int compare(Object ob1, Object ob2) { |
| if(ob1 == null || ob2 == null) { |
| return -1; |
| } |
| CheatSheetElement d1 = (CheatSheetElement) ob1; |
| CheatSheetElement d2 = (CheatSheetElement) ob2; |
| return collator.compare(d1.getLabel(null), d2.getLabel(null)); |
| } |
| }; |
| |
| /** |
| * Constructs a new instance of <code>CheatSheetMenu</code>. |
| */ |
| public CheatSheetMenu() { |
| super("LaunchCheatSheetMenu"); //$NON-NLS-1$ |
| |
| if (reg == null) |
| reg = CheatSheetRegistryReader.getInstance(); |
| |
| showActive(true); |
| } |
| |
| /* (non-Javadoc) |
| * Creates a menu item for a cheatsheet. |
| */ |
| private void createMenuItem(Menu menu, int index, final CheatSheetElement element, boolean bCheck) { |
| |
| MenuItem mi = new MenuItem(menu, bCheck ? SWT.RADIO : SWT.PUSH, index); |
| mi.setText(element.getLabel(null)); |
| mi.setImage(CheatSheetPlugin.getPlugin().getImageRegistry().get(ICheatSheetResource.CHEATSHEET_OBJ)); |
| mi.setSelection(bCheck); |
| mi.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| run(element, e); |
| } |
| }); |
| } |
| |
| /* (non-Javadoc) |
| * Creates a menu item for "Other...". |
| */ |
| private void createOtherItem(Menu menu, int index) { |
| MenuItem mi = new MenuItem(menu, SWT.PUSH, index); |
| mi.setText(Messages.CHEAT_SHEET_OTHER_MENU); |
| mi.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| runOther(e); |
| } |
| }); |
| } |
| |
| /* (non-Javadoc) |
| * Fills the menu with cheatsheet items. |
| */ |
| public void fill(Menu menu, int index) { |
| // Get the checked cheatsheet. |
| String checkID = null; |
| if (showActive) { |
| checkID = getActiveCheatSheetID(); |
| } |
| |
| // Collect and sort cheatsheet items. |
| ArrayList cheatsheets = getCheatSheetItems(); |
| Collections.sort(cheatsheets, comparator); |
| |
| // Add cheatsheet shortcuts |
| for (int i = 0; i < cheatsheets.size(); i++) { |
| CheatSheetElement element = (CheatSheetElement) cheatsheets.get(i); |
| if (element != null) { |
| createMenuItem(menu, index++, element, element.getID().equals(checkID)); |
| } |
| } |
| |
| // Add others item.. |
| if (cheatsheets.size() > 0) { |
| new MenuItem(menu, SWT.SEPARATOR, index++); |
| } |
| createOtherItem(menu, index); |
| } |
| |
| /** |
| * Method getActiveCheatSheetID returns the id of the active |
| * cheatsheet or null. |
| * |
| * @return String |
| */ |
| private String getActiveCheatSheetID() { |
| //get the active cheatsheet view, if opened |
| IWorkbenchPage page = getActiveWorkbenchPage(); |
| |
| if( page != null ) { |
| CheatSheetView view = (CheatSheetView) page.findView(ICheatSheetResource.CHEAT_SHEET_VIEW_ID); |
| if (view != null) { |
| CheatSheetElement content = view.getContent(); |
| if (content != null) { |
| return content.getID(); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Method getActiveWorkbenchPage returns the active |
| * workbench page or null. |
| * |
| * @return IWorkbenchPage |
| */ |
| private IWorkbenchPage getActiveWorkbenchPage() { |
| IWorkbench workbench = CheatSheetPlugin.getPlugin().getWorkbench(); |
| IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); |
| |
| //get the active cheatsheet view, if opened |
| return window.getActivePage(); |
| } |
| |
| /** |
| * Returns the available list of cheatsheets to display |
| * in the menu. |
| * <p> |
| * By default, the list contains the most recently used cheatsheets |
| * and then random cheatsheets until there are 5 present in the list. |
| * </p><p> |
| * Care should be taken to keep this list to a minimum (7 +/- 2 items |
| * is a good guideline to follow). |
| * </p> |
| * |
| * @return an <code>ArrayList<code> of cheatsheet items <code>CheatSheetElement</code> |
| */ |
| protected ArrayList getCheatSheetItems() { |
| ArrayList list = new ArrayList(MAX_CHEATSHEET_ITEMS); |
| int emptySlots = MAX_CHEATSHEET_ITEMS; |
| |
| // Add cheatsheets from MRU list |
| if (emptySlots > 0) { |
| ArrayList mru = new ArrayList(MAX_CHEATSHEET_ITEMS); |
| int count = getCheatSheetMru(mru, 0, MAX_CHEATSHEET_ITEMS); |
| for (int i = 0; i < count && emptySlots > 0; i++) { |
| if (!list.contains(mru.get(i))) { |
| list.add(mru.get(i)); |
| emptySlots--; |
| } |
| } |
| } |
| |
| // Add random cheatsheets until the list is filled. |
| CheatSheetCollectionElement cheatSheetsCollection = (CheatSheetCollectionElement)reg.getCheatSheets(); |
| emptySlots = addCheatSheets(list, cheatSheetsCollection, emptySlots); |
| |
| return list; |
| } |
| |
| /** |
| * Method addCheatSheets fills a list with cheatsheet elements until there |
| * are no more empty slots. |
| * |
| * @param list - the list to file |
| * @param cheatSheetsCollection - the collection to get the elements from |
| * @param emptySlots - number of empty slots remaining |
| * @return int - number of empty slots remaining |
| */ |
| private int addCheatSheets(ArrayList list, CheatSheetCollectionElement cheatSheetsCollection, int emptySlots) { |
| Object[] cheatSheets = cheatSheetsCollection.getCheatSheets(); |
| for (int i = 0; i < cheatSheets.length && emptySlots > 0; i++) { |
| if (!list.contains(cheatSheets[i])) { |
| list.add(cheatSheets[i]); |
| emptySlots--; |
| } |
| } |
| |
| Object[] cheatSheetsFromCollection = cheatSheetsCollection.getChildren(); |
| for (int nX = 0; nX < cheatSheetsFromCollection.length && emptySlots > 0; nX++) { |
| CheatSheetCollectionElement collection = (CheatSheetCollectionElement) cheatSheetsFromCollection[nX]; |
| emptySlots = addCheatSheets(list, collection, emptySlots); |
| } |
| |
| return emptySlots; |
| } |
| |
| /* (non-Javadoc) |
| * Gets the most recently used (MRU) shortcut cheatsheets |
| * (<code>CheatSheetElement</code> items) |
| * <p> |
| * The list is formed from the global cheatsheet history. |
| * </p> |
| * @param dest destination list to contain the items |
| * @param destStart index in destination list to start copying items at |
| * @param count number of items to copy from history |
| * @return the number of items actually copied |
| */ |
| private int getCheatSheetMru(List dest, int destStart, int count) { |
| CheatSheetHistory history = CheatSheetPlugin.getPlugin().getCheatSheetHistory(); |
| return history.copyItems(dest, destStart, count); |
| } |
| |
| /** |
| * Returns whether the menu item representing the active cheatsheet |
| * will have a check mark. |
| * |
| * @return <code>true</code> if a check mark is shown, <code>false</code> otherwise |
| */ |
| protected boolean getShowActive() { |
| return showActive; |
| } |
| |
| /* (non-Javadoc) |
| * Returns whether this menu is dynamic. |
| */ |
| public boolean isDynamic() { |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.action.IContributionItem#isVisible() |
| */ |
| public boolean isVisible() { |
| return getActiveWorkbenchPage() != null; |
| } |
| |
| /** |
| * Runs an action to launch the cheatsheet. |
| * |
| * @param element the selected cheatsheet |
| * @param event SelectionEvent - the event send along with the selection callback |
| */ |
| protected void run(CheatSheetElement element, SelectionEvent event) { |
| new OpenCheatSheetAction(element.getID()).run(); |
| } |
| |
| /* (non-Javadoc) |
| * Show the "other" dialog, select a cheatsheet, and launch it. Pass on the selection |
| * event should the meny need it. |
| */ |
| private void runOther(SelectionEvent event) { |
| new CheatSheetCategoryBasedSelectionAction().run(); |
| } |
| |
| /** |
| * Sets the showActive flag. If <code>showActive == true</code> then the |
| * active cheatsheet is hilighted with a check mark. |
| * |
| * @param the new showActive flag |
| */ |
| protected void showActive(boolean b) { |
| showActive = b; |
| } |
| } |