blob: c3553cef259dbf737785430c05b03b10bba6e19b [file] [log] [blame]
/*******************************************************************************
* 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;
}
}