0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.ui.internal.dialogs;
0011:
0012: import java.net.URL;
0013: import java.util.ArrayList;
0014: import java.util.Arrays;
0015: import java.util.Hashtable;
0016: import java.util.Iterator;
0017: import java.util.List;
0018: import java.util.Map;
0019:
0020: import org.eclipse.core.runtime.CoreException;
0021: import org.eclipse.jface.action.ContributionManager;
0022: import org.eclipse.jface.action.CoolBarManager;
0023: import org.eclipse.jface.action.IAction;
0024: import org.eclipse.jface.action.IContributionItem;
0025: import org.eclipse.jface.action.ICoolBarManager;
0026: import org.eclipse.jface.action.IMenuManager;
0027: import org.eclipse.jface.action.IStatusLineManager;
0028: import org.eclipse.jface.action.IToolBarManager;
0029: import org.eclipse.jface.action.MenuManager;
0030: import org.eclipse.jface.action.StatusLineManager;
0031: import org.eclipse.jface.action.ToolBarManager;
0032: import org.eclipse.jface.dialogs.TrayDialog;
0033: import org.eclipse.jface.internal.provisional.action.IToolBarContributionItem;
0034: import org.eclipse.jface.internal.provisional.action.ToolBarContributionItem2;
0035: import org.eclipse.jface.resource.ImageDescriptor;
0036: import org.eclipse.jface.viewers.AbstractTreeViewer;
0037: import org.eclipse.jface.viewers.ArrayContentProvider;
0038: import org.eclipse.jface.viewers.CheckStateChangedEvent;
0039: import org.eclipse.jface.viewers.CheckboxTableViewer;
0040: import org.eclipse.jface.viewers.CheckboxTreeViewer;
0041: import org.eclipse.jface.viewers.ICheckStateListener;
0042: import org.eclipse.jface.viewers.ISelectionChangedListener;
0043: import org.eclipse.jface.viewers.IStructuredContentProvider;
0044: import org.eclipse.jface.viewers.IStructuredSelection;
0045: import org.eclipse.jface.viewers.ITableLabelProvider;
0046: import org.eclipse.jface.viewers.ITreeContentProvider;
0047: import org.eclipse.jface.viewers.LabelProvider;
0048: import org.eclipse.jface.viewers.SelectionChangedEvent;
0049: import org.eclipse.jface.viewers.StructuredSelection;
0050: import org.eclipse.jface.viewers.TreeViewer;
0051: import org.eclipse.jface.viewers.Viewer;
0052: import org.eclipse.jface.window.DefaultToolTip;
0053: import org.eclipse.jface.window.ToolTip;
0054: import org.eclipse.osgi.util.NLS;
0055: import org.eclipse.swt.SWT;
0056: import org.eclipse.swt.custom.SashForm;
0057: import org.eclipse.swt.events.KeyEvent;
0058: import org.eclipse.swt.events.KeyListener;
0059: import org.eclipse.swt.events.ModifyEvent;
0060: import org.eclipse.swt.events.ModifyListener;
0061: import org.eclipse.swt.events.SelectionAdapter;
0062: import org.eclipse.swt.events.SelectionEvent;
0063: import org.eclipse.swt.events.SelectionListener;
0064: import org.eclipse.swt.graphics.Image;
0065: import org.eclipse.swt.graphics.Point;
0066: import org.eclipse.swt.layout.GridData;
0067: import org.eclipse.swt.layout.GridLayout;
0068: import org.eclipse.swt.widgets.Combo;
0069: import org.eclipse.swt.widgets.Composite;
0070: import org.eclipse.swt.widgets.Control;
0071: import org.eclipse.swt.widgets.Event;
0072: import org.eclipse.swt.widgets.Label;
0073: import org.eclipse.swt.widgets.Shell;
0074: import org.eclipse.swt.widgets.TabFolder;
0075: import org.eclipse.swt.widgets.TabItem;
0076: import org.eclipse.swt.widgets.Table;
0077: import org.eclipse.swt.widgets.TableColumn;
0078: import org.eclipse.ui.IActionBars2;
0079: import org.eclipse.ui.IPerspectiveDescriptor;
0080: import org.eclipse.ui.IPerspectiveRegistry;
0081: import org.eclipse.ui.PlatformUI;
0082: import org.eclipse.ui.activities.WorkbenchActivityHelper;
0083: import org.eclipse.ui.application.ActionBarAdvisor;
0084: import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
0085: import org.eclipse.ui.internal.ActionSetActionBars;
0086: import org.eclipse.ui.internal.ActionSetContributionItem;
0087: import org.eclipse.ui.internal.ActionSetMenuManager;
0088: import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
0089: import org.eclipse.ui.internal.Perspective;
0090: import org.eclipse.ui.internal.PluginActionContributionItem;
0091: import org.eclipse.ui.internal.PluginActionCoolBarContributionItem;
0092: import org.eclipse.ui.internal.PluginActionSet;
0093: import org.eclipse.ui.internal.PluginActionSetBuilder;
0094: import org.eclipse.ui.internal.WorkbenchMessages;
0095: import org.eclipse.ui.internal.WorkbenchPage;
0096: import org.eclipse.ui.internal.WorkbenchPlugin;
0097: import org.eclipse.ui.internal.WorkbenchWindow;
0098: import org.eclipse.ui.internal.intro.IIntroConstants;
0099: import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2;
0100: import org.eclipse.ui.internal.registry.ActionSetDescriptor;
0101: import org.eclipse.ui.internal.registry.ActionSetRegistry;
0102: import org.eclipse.ui.internal.registry.IActionSetDescriptor;
0103: import org.eclipse.ui.internal.util.BundleUtility;
0104: import org.eclipse.ui.model.WorkbenchLabelProvider;
0105: import org.eclipse.ui.model.WorkbenchViewerComparator;
0106: import org.eclipse.ui.services.IServiceLocator;
0107: import org.eclipse.ui.views.IViewCategory;
0108: import org.eclipse.ui.views.IViewDescriptor;
0109: import org.eclipse.ui.views.IViewRegistry;
0110: import org.eclipse.ui.wizards.IWizardCategory;
0111:
0112: /**
0113: * Dialog to allow users the ability to customize the perspective. This includes
0114: * customizing menus and toolbars by adding, removing, or re-arranging commands
0115: * or groups of commands.
0116: *
0117: */
0118: // @issue need to break this not to show menu specific page
0119: public class CustomizePerspectiveDialog extends TrayDialog {
0120: private DefaultToolTip actionSetMenuViewerTooltip;
0121:
0122: private DefaultToolTip actionSetToolbarViewerTooltip;
0123:
0124: private DefaultToolTip actionSetsViewerTooltip;
0125:
0126: private Perspective perspective;
0127:
0128: WorkbenchWindow window;
0129:
0130: private TabFolder tabFolder;
0131:
0132: private CheckboxTableViewer actionSetsViewer;
0133:
0134: private TreeViewer actionSetMenuViewer;
0135:
0136: private TreeViewer actionSetToolbarViewer;
0137:
0138: private Combo menusCombo;
0139:
0140: private CheckboxTreeViewer menuCategoriesViewer;
0141:
0142: private CheckboxTableViewer menuItemsViewer;
0143:
0144: private static int lastSelectedTab = -1;
0145:
0146: private static int lastSelectedMenuIndex = 0;
0147:
0148: private static String lastSelectedActionSetId = null;
0149:
0150: private final static int TAB_WIDTH_IN_DLUS = 490;
0151:
0152: private final static int TAB_HEIGHT_IN_DLUS = 230;
0153:
0154: private final String shortcutMenuColumnHeaders[] = {
0155: WorkbenchMessages.ActionSetSelection_menuColumnHeader,
0156: WorkbenchMessages.ActionSetSelection_descriptionColumnHeader };
0157:
0158: private int[] shortcutMenuColumnWidths = { 125, 300 };
0159:
0160: private ActionSetDescriptor selectedActionSet = null;
0161:
0162: private ShortcutMenu selectedMenuCategory = null;
0163:
0164: ImageDescriptor menuImageDescriptor = null;
0165:
0166: ImageDescriptor submenuImageDescriptor = null;
0167:
0168: ImageDescriptor toolbarImageDescriptor = null;
0169:
0170: ShortcutMenu rootMenu;
0171:
0172: private ArrayList actionSets = new ArrayList();
0173:
0174: private Hashtable actionSetStructures = new Hashtable();
0175:
0176: private IWorkbenchWindowConfigurer configurer;
0177:
0178: private List initiallyActive = new ArrayList();
0179:
0180: class ActionSetDisplayItem extends Object {
0181: /**
0182: * Tree representation for action set menu and toolbar items.
0183: */
0184: ArrayList children = new ArrayList();
0185:
0186: ActionSetDisplayItem parent = null;
0187:
0188: private String id = null;
0189:
0190: private String text = ""; //$NON-NLS-1$
0191:
0192: String description = ""; //$NON-NLS-1$
0193:
0194: ImageDescriptor imageDescriptor;
0195:
0196: int type = MENUITEM;
0197:
0198: private final static int MENUITEM = 0;
0199:
0200: private final static int TOOLITEM = 1;
0201:
0202: ActionSetDisplayItem(String id) {
0203: this (null, id, "", MENUITEM); //$NON-NLS-1$
0204: }
0205:
0206: private ActionSetDisplayItem(ActionSetDisplayItem parent,
0207: String id, String text, int type) {
0208: if (parent != null) {
0209: parent.children.add(this );
0210: this .parent = parent;
0211: }
0212: this .id = id;
0213: this .type = type;
0214: this .text = removeShortcut(text);
0215: this .text = DialogUtil.removeAccel(this .text);
0216: }
0217:
0218: private ActionSetDisplayItem find(String itemId) {
0219: for (int i = 0; i < children.size(); i++) {
0220: ActionSetDisplayItem child = (ActionSetDisplayItem) children
0221: .get(i);
0222: if (itemId.equals(child.id)) {
0223: return child;
0224: }
0225: }
0226: return null;
0227: }
0228:
0229: /**
0230: * @param actionSetId the action to fill
0231: * @param item the item to fill
0232: */
0233: public void fillMenusFor(String actionSetId,
0234: IContributionItem item) {
0235: if (item instanceof ContributionManager) {
0236: ContributionManager mgr = (ContributionManager) item;
0237: IContributionItem[] items = mgr.getItems();
0238: for (int i = 0; i < items.length; i++) {
0239: IContributionItem mgrItem = items[i];
0240: if (mgrItem instanceof ActionSetContributionItem) {
0241: ActionSetContributionItem actionSetItem = (ActionSetContributionItem) mgrItem;
0242: if (actionSetItem.getActionSetId().equals(
0243: actionSetId)) {
0244: IContributionItem innerItem = actionSetItem
0245: .getInnerItem();
0246: if (innerItem instanceof MenuManager) {
0247: MenuManager inner = (MenuManager) actionSetItem
0248: .getInnerItem();
0249: ActionSetDisplayItem node = new ActionSetDisplayItem(
0250: this , inner.getId(), inner
0251: .getMenuText(),
0252: MENUITEM);
0253: node.fillMenusFor(actionSetId, inner);
0254: } else if (innerItem instanceof ActionSetMenuManager) {
0255: ActionSetMenuManager inner = (ActionSetMenuManager) actionSetItem
0256: .getInnerItem();
0257: MenuManager parentMgr = (MenuManager) inner
0258: .getParent();
0259: ActionSetDisplayItem node = new ActionSetDisplayItem(
0260: this , inner.getId(), parentMgr
0261: .getMenuText(),
0262: MENUITEM);
0263: node.fillMenusFor(actionSetId,
0264: parentMgr);
0265: } else if (innerItem instanceof PluginActionContributionItem) {
0266: PluginActionContributionItem inner = (PluginActionContributionItem) actionSetItem
0267: .getInnerItem();
0268: ActionSetDisplayItem node = new ActionSetDisplayItem(
0269: this , inner.getId(), inner
0270: .getAction().getText(),
0271: MENUITEM);
0272: IAction action = inner.getAction();
0273: if (action != null) {
0274: node.imageDescriptor = action
0275: .getImageDescriptor();
0276: node.description = action
0277: .getDescription();
0278: }
0279: }
0280: }
0281: } else if (mgrItem instanceof MenuManager) {
0282: MenuManager menuMgr = (MenuManager) mgrItem;
0283: boolean found = containsActionSet(menuMgr,
0284: actionSetId);
0285: if (found) {
0286: ActionSetDisplayItem node = new ActionSetDisplayItem(
0287: this , menuMgr.getId(), menuMgr
0288: .getMenuText(), MENUITEM);
0289: node.fillMenusFor(actionSetId, menuMgr);
0290: }
0291: }
0292: }
0293: }
0294: }
0295:
0296: /**
0297: * @param actionSetId the action set to fill
0298: * @param mgr the manager to fill into
0299: */
0300: public void fillToolsFor(String actionSetId, CoolBarManager mgr) {
0301: IContributionItem[] items = mgr.getItems();
0302: for (int i = 0; i < items.length; i++) {
0303: if (items[i] instanceof IToolBarContributionItem) {
0304: IToolBarContributionItem cbItem = (IToolBarContributionItem) items[i];
0305: IContributionItem[] subItems = cbItem
0306: .getToolBarManager().getItems();
0307: for (int j = 0; j < subItems.length; j++) {
0308: IContributionItem subItem = subItems[j];
0309: if (subItem instanceof PluginActionCoolBarContributionItem) {
0310: PluginActionCoolBarContributionItem actionItem = (PluginActionCoolBarContributionItem) subItem;
0311: if (actionItem.getActionSetId().equals(
0312: actionSetId)) {
0313: String toolbarId = cbItem.getId();
0314: ActionSetDisplayItem toolbar = find(toolbarId);
0315: if (toolbar == null) {
0316: String toolbarText = window
0317: .getToolbarLabel(toolbarId);
0318: toolbar = new ActionSetDisplayItem(
0319: this , toolbarId,
0320: toolbarText, TOOLITEM);
0321: }
0322: IAction action = actionItem.getAction();
0323: String toolItemText = action
0324: .getToolTipText();
0325: if (toolItemText == null) {
0326: toolItemText = action.getText();
0327: }
0328: ActionSetDisplayItem toolItem = new ActionSetDisplayItem(
0329: toolbar, action.getId(),
0330: toolItemText, TOOLITEM);
0331: toolItem.imageDescriptor = action
0332: .getImageDescriptor();
0333: toolItem.description = action
0334: .getDescription();
0335: }
0336: }
0337: }
0338: }
0339: }
0340: }
0341:
0342: int getDepth() {
0343: if (parent == null) {
0344: return 0;
0345: }
0346: return parent.getDepth() + 1;
0347: }
0348:
0349: String getDisplayText() {
0350: if (type == MENUITEM) {
0351: if (children.size() > 0) {
0352: if (parent.id.equals("Root")) { //$NON-NLS-1$
0353: return NLS
0354: .bind(
0355: WorkbenchMessages.ActionSetSelection_menubarLocation,
0356: text);
0357: }
0358: }
0359: return text;
0360: }
0361: if (children.size() > 0) {
0362: return NLS
0363: .bind(
0364: WorkbenchMessages.ActionSetSelection_toolbarLocation,
0365: text);
0366: }
0367:
0368: return text;
0369: }
0370:
0371: protected boolean isTopLevelMenu() {
0372: if (parent == null) {
0373: return false;
0374: }
0375: return parent.parent == null;
0376: }
0377:
0378: public String toString() {
0379: StringBuffer sb = new StringBuffer();
0380: for (int i = getDepth(); --i >= 0;) {
0381: sb.append(" "); //$NON-NLS-1$
0382: }
0383: sb.append("id: "); //$NON-NLS-1$
0384: sb.append(id);
0385: sb.append(" text: "); //$NON-NLS-1$
0386: sb.append(text);
0387: sb.append('\n');
0388: for (int i = 0; i < children.size(); ++i) {
0389: sb.append(children.get(i));
0390: }
0391: return sb.toString();
0392:
0393: }
0394: }
0395:
0396: /**
0397: * The proxy IActionBarConfigurer that gets passed to the application's
0398: * ActionBarAdvisor. This is used to construct a representation of the
0399: * window's hardwired menus and toolbars in order to display their
0400: * structure properly in the preview panes.
0401: */
0402: public class CustomizeActionBars implements IActionBarConfigurer2,
0403: IActionBars2 {
0404:
0405: IWorkbenchWindowConfigurer configurer;
0406:
0407: /**
0408: * Fake action bars to use to build the menus and toolbar contributions for the
0409: * workbench. We cannot use the actual workbench action bars, since doing so would
0410: * make the action set items visible.
0411: */
0412: MenuManager menuManager = new MenuManager();
0413: CoolBarManager coolBarManager = new CoolBarManager();
0414: StatusLineManager statusLineManager = new StatusLineManager();
0415:
0416: /**
0417: * Create a new instance of this class.
0418: *
0419: * @param configurer the configurer
0420: */
0421: public CustomizeActionBars(IWorkbenchWindowConfigurer configurer) {
0422: this .configurer = configurer;
0423: }
0424:
0425: /* (non-Javadoc)
0426: * @see org.eclipse.ui.application.IActionBarConfigurer#getWindowConfigurer()
0427: */
0428: public IWorkbenchWindowConfigurer getWindowConfigurer() {
0429: return configurer;
0430: }
0431:
0432: /*
0433: * (non-Javadoc)
0434: * @see org.eclipse.ui.application.IActionBarConfigurer#getMenuManager()
0435: */
0436: public IMenuManager getMenuManager() {
0437: return menuManager;
0438: }
0439:
0440: /*
0441: * (non-Javadoc)
0442: * @see org.eclipse.ui.application.IActionBarConfigurer#getStatusLineManager()
0443: */
0444: public IStatusLineManager getStatusLineManager() {
0445: return statusLineManager;
0446: }
0447:
0448: /* (non-Javadoc)
0449: * @see org.eclipse.ui.internal.AbstractActionBarConfigurer#getCoolBarManager()
0450: */
0451: public ICoolBarManager getCoolBarManager() {
0452: return coolBarManager;
0453: }
0454:
0455: /* (non-Javadoc)
0456: * @see org.eclipse.ui.IActionBars#getToolBarManager()
0457: */
0458: public IToolBarManager getToolBarManager() {
0459: return null;
0460: }
0461:
0462: public void setGlobalActionHandler(String actionID,
0463: IAction handler) {
0464: }
0465:
0466: public void updateActionBars() {
0467: }
0468:
0469: /* (non-Javadoc)
0470: * @see org.eclipse.ui.IActionBars#clearGlobalActionHandlers()
0471: */
0472: public void clearGlobalActionHandlers() {
0473: }
0474:
0475: /* (non-Javadoc)
0476: * @see org.eclipse.ui.IActionBars#getGlobalActionHandler(java.lang.String)
0477: */
0478: public IAction getGlobalActionHandler(String actionId) {
0479: return null;
0480: }
0481:
0482: /* (non-Javadoc)
0483: * @see org.eclipse.ui.application.IActionBarConfigurer#registerGlobalAction(org.eclipse.jface.action.IAction)
0484: */
0485: public void registerGlobalAction(IAction action) {
0486: }
0487:
0488: /**
0489: * Clean up the action bars.
0490: */
0491: public void dispose() {
0492: coolBarManager.dispose();
0493: menuManager.dispose();
0494: statusLineManager.dispose();
0495: }
0496:
0497: public final IServiceLocator getServiceLocator() {
0498: return configurer.getWindow();
0499: }
0500:
0501: /* (non-Javadoc)
0502: * @see org.eclipse.ui.application.IActionBarConfigurer#createToolBarContributionItem(org.eclipse.jface.action.IToolBarManager, java.lang.String)
0503: */
0504: public IToolBarContributionItem createToolBarContributionItem(
0505: IToolBarManager toolBarManager, String id) {
0506: return new ToolBarContributionItem2(toolBarManager, id);
0507: }
0508:
0509: /* (non-Javadoc)
0510: * @see org.eclipse.ui.application.IActionBarConfigurer#createToolBarManager(int)
0511: */
0512: public IToolBarManager createToolBarManager() {
0513: return new ToolBarManager();
0514: }
0515: }
0516:
0517: class ShortcutMenuItemContentProvider implements
0518: IStructuredContentProvider {
0519:
0520: ShortcutMenuItemContentProvider() {
0521: }
0522:
0523: public Object[] getElements(Object input) {
0524: if (input instanceof ShortcutMenu) {
0525: return ((ShortcutMenu) input).getItems().toArray();
0526: }
0527: return new Object[0];
0528: }
0529:
0530: public void inputChanged(Viewer viewer, Object oldInput,
0531: Object newInput) {
0532: }
0533:
0534: public void dispose() {
0535: }
0536: }
0537:
0538: class ShortcutMenuItemLabelProvider extends LabelProvider implements
0539: ITableLabelProvider {
0540: private Map imageTable = new Hashtable();
0541:
0542: private final static int COLUMN_ID = 0;
0543:
0544: private final static int COLUMN_DESCRIPTION = 1;
0545:
0546: ShortcutMenuItemLabelProvider() {
0547: }
0548:
0549: public final void dispose() {
0550: for (Iterator i = imageTable.values().iterator(); i
0551: .hasNext();) {
0552: ((Image) i.next()).dispose();
0553: }
0554: imageTable = null;
0555: }
0556:
0557: public Image getColumnImage(Object element, int index) {
0558: if (index != COLUMN_ID) {
0559: return null;
0560: }
0561: ImageDescriptor descriptor = null;
0562: if (element instanceof IPerspectiveDescriptor) {
0563: descriptor = ((IPerspectiveDescriptor) element)
0564: .getImageDescriptor();
0565: } else if (element instanceof IViewDescriptor) {
0566: descriptor = ((IViewDescriptor) element)
0567: .getImageDescriptor();
0568: } else if (element instanceof WorkbenchWizardElement) {
0569: descriptor = ((WorkbenchWizardElement) element)
0570: .getImageDescriptor();
0571: }
0572: if (descriptor == null) {
0573: return null;
0574: }
0575: //obtain the cached image corresponding to the descriptor
0576: if (imageTable == null) {
0577: imageTable = new Hashtable(40);
0578: }
0579: Image image = (Image) imageTable.get(descriptor);
0580: if (image == null) {
0581: image = descriptor.createImage();
0582: imageTable.put(descriptor, image);
0583: }
0584: return image;
0585: }
0586:
0587: public String getColumnText(Object element, int columnIndex) {
0588: String text = null;
0589: switch (columnIndex) {
0590: case COLUMN_ID:
0591: text = getText(element);
0592: break;
0593: case COLUMN_DESCRIPTION:
0594: if (element instanceof IPerspectiveDescriptor) {
0595: text = ((IPerspectiveDescriptor) element)
0596: .getDescription();
0597: } else if (element instanceof IViewDescriptor) {
0598: text = ((IViewDescriptor) element).getDescription();
0599: } else if (element instanceof WorkbenchWizardElement) {
0600: text = ((WorkbenchWizardElement) element)
0601: .getDescription();
0602: }
0603: break;
0604: }
0605: if (text == null) {
0606: text = ""; //$NON-NLS-1$
0607: }
0608: return text;
0609: }
0610:
0611: public String getText(Object element) {
0612: String text = null;
0613: if (element instanceof IPerspectiveDescriptor) {
0614: text = ((IPerspectiveDescriptor) element).getLabel();
0615: } else if (element instanceof IViewDescriptor) {
0616: text = ((IViewDescriptor) element).getLabel();
0617: } else if (element instanceof WorkbenchWizardElement) {
0618: text = ((WorkbenchWizardElement) element)
0619: .getLabel(element);
0620: }
0621: if (text == null) {
0622: text = ""; //$NON-NLS-1$
0623: }
0624: return text;
0625: }
0626: }
0627:
0628: class ShortcutMenu extends Object {
0629: /**
0630: * Tree representation for the shortcut items.
0631: */
0632: private final static String ID_VIEW = "org.eclipse.ui.views"; //$NON-NLS-1$
0633:
0634: private final static String ID_WIZARD = "org.eclipse.ui.wizards"; //$NON-NLS-1$
0635:
0636: private final static String ID_PERSP = "org.eclipse.ui.perspectives"; //$NON-NLS-1$
0637:
0638: String id;
0639:
0640: String label;
0641:
0642: private ArrayList items = new ArrayList();
0643:
0644: private ArrayList checkedItems = new ArrayList();
0645:
0646: ArrayList children = new ArrayList();
0647:
0648: ShortcutMenu parent = null;
0649:
0650: ShortcutMenu(ShortcutMenu parent, String id, String label) {
0651: super ();
0652: this .id = id;
0653: this .parent = parent;
0654: this .label = removeShortcut(label);
0655: this .label = DialogUtil.removeAccel(this .label);
0656: if (parent != null) {
0657: parent.children.add(this );
0658: }
0659: }
0660:
0661: void addItem(Object item) {
0662: items.add(item);
0663: }
0664:
0665: void addCheckedItem(Object item) {
0666: checkedItems.add(item);
0667: }
0668:
0669: public String toString() {
0670: return label;
0671: }
0672:
0673: ArrayList getCheckedItems() {
0674: return checkedItems;
0675: }
0676:
0677: ArrayList getCheckedItemIds() {
0678: ArrayList ids = new ArrayList();
0679: if (getMenuId() == ID_PERSP) {
0680: for (int i = 0; i < checkedItems.size(); i++) {
0681: IPerspectiveDescriptor item = (IPerspectiveDescriptor) checkedItems
0682: .get(i);
0683: ids.add(item.getId());
0684: }
0685: } else if (getMenuId() == ID_VIEW) {
0686: for (int i = 0; i < checkedItems.size(); i++) {
0687: IViewDescriptor item = (IViewDescriptor) checkedItems
0688: .get(i);
0689: ids.add(item.getId());
0690: }
0691: } else if (getMenuId() == ID_WIZARD) {
0692: for (int i = 0; i < checkedItems.size(); i++) {
0693: WorkbenchWizardElement item = (WorkbenchWizardElement) checkedItems
0694: .get(i);
0695: ids.add(item.getId());
0696: }
0697: }
0698: for (int i = 0; i < children.size(); i++) {
0699: ShortcutMenu menu = (ShortcutMenu) children.get(i);
0700: ids.addAll(menu.getCheckedItemIds());
0701: }
0702: return ids;
0703: }
0704:
0705: ArrayList getChildren() {
0706: return children;
0707: }
0708:
0709: ArrayList getItems() {
0710: return items;
0711: }
0712:
0713: private String getMenuId() {
0714: if (parent == rootMenu) {
0715: return id;
0716: }
0717:
0718: return parent.getMenuId();
0719: }
0720:
0721: ArrayList getSubtreeItems() {
0722: ArrayList subtreeItems = new ArrayList();
0723: subtreeItems.add(this );
0724: for (int i = 0; i < children.size(); i++) {
0725: ShortcutMenu child = (ShortcutMenu) children.get(i);
0726: subtreeItems.addAll(child.getSubtreeItems());
0727: }
0728: return subtreeItems;
0729: }
0730:
0731: Object getItem(String menuItemId) {
0732: for (int i = 0; i < items.size(); i++) {
0733: Object item = items.get(i);
0734: String itemId = null;
0735: if (id == ID_PERSP) {
0736: itemId = ((IPerspectiveDescriptor) item).getId();
0737: } else if (id == ID_VIEW) {
0738: itemId = ((IViewDescriptor) item).getId();
0739: } else if (id == ID_WIZARD) {
0740: itemId = ((WorkbenchWizardElement) item).getId();
0741: }
0742: if (menuItemId.equals(itemId)) {
0743: return item;
0744: }
0745: }
0746: return null;
0747: }
0748:
0749: boolean isFullyChecked() {
0750: if (getItems().size() != getCheckedItems().size()) {
0751: return false;
0752: }
0753: for (int i = 0; i < children.size(); i++) {
0754: ShortcutMenu child = (ShortcutMenu) children.get(i);
0755: if (!child.isFullyChecked()) {
0756: return false;
0757: }
0758: }
0759: return true;
0760: }
0761:
0762: boolean isFullyUnchecked() {
0763: if (getCheckedItems().size() != 0) {
0764: return false;
0765: }
0766: for (int i = 0; i < children.size(); i++) {
0767: ShortcutMenu child = (ShortcutMenu) children.get(i);
0768: if (!child.isFullyUnchecked()) {
0769: return false;
0770: }
0771: }
0772: return true;
0773: }
0774:
0775: void removeCheckedItem(Object item) {
0776: checkedItems.remove(item);
0777: }
0778:
0779: void checked(boolean checked) {
0780: checkedItems = new ArrayList();
0781: if (checked) {
0782: checkedItems.addAll(items);
0783: }
0784: for (int i = 0; i < children.size(); i++) {
0785: ShortcutMenu child = (ShortcutMenu) children.get(i);
0786: child.checked(checked);
0787: }
0788: }
0789: }
0790:
0791: class TreeContentProvider implements ITreeContentProvider {
0792: public void dispose() {
0793: }
0794:
0795: public Object[] getChildren(Object element) {
0796: if (element instanceof ActionSetDisplayItem) {
0797: ActionSetDisplayItem node = (ActionSetDisplayItem) element;
0798: return node.children.toArray();
0799: } else if (element instanceof ShortcutMenu) {
0800: ShortcutMenu node = (ShortcutMenu) element;
0801: return node.children.toArray();
0802: } else if (element instanceof ArrayList) {
0803: return ((ArrayList) element).toArray();
0804: }
0805: return new Object[0];
0806: }
0807:
0808: public Object[] getElements(Object element) {
0809: return getChildren(element);
0810: }
0811:
0812: public Object getParent(Object element) {
0813: if (element instanceof ActionSetDisplayItem) {
0814: ActionSetDisplayItem node = (ActionSetDisplayItem) element;
0815: return node.parent;
0816: } else if (element instanceof ShortcutMenu) {
0817: ShortcutMenu node = (ShortcutMenu) element;
0818: return node.parent;
0819: }
0820: return null;
0821: }
0822:
0823: public boolean hasChildren(Object element) {
0824: if (element instanceof ActionSetDisplayItem) {
0825: ActionSetDisplayItem node = (ActionSetDisplayItem) element;
0826: return node.children.size() > 0;
0827: } else if (element instanceof ShortcutMenu) {
0828: ShortcutMenu node = (ShortcutMenu) element;
0829: return node.children.size() > 0;
0830: }
0831: return false;
0832: }
0833:
0834: public void inputChanged(Viewer viewer, Object oldInput,
0835: Object newInput) {
0836: }
0837: }
0838:
0839: class ActionSetLabelProvider extends LabelProvider {
0840: private Map imageTable = new Hashtable();
0841:
0842: public void dispose() {
0843: for (Iterator i = imageTable.values().iterator(); i
0844: .hasNext();) {
0845: ((Image) i.next()).dispose();
0846: }
0847: imageTable = null;
0848: }
0849:
0850: public Image getImage(Object element) {
0851: ActionSetDisplayItem item = (ActionSetDisplayItem) element;
0852: ImageDescriptor descriptor = item.imageDescriptor;
0853: if (descriptor == null) {
0854: if (item.type == ActionSetDisplayItem.MENUITEM) {
0855: if (item.children.size() > 0) {
0856: if (item.isTopLevelMenu()) {
0857: descriptor = menuImageDescriptor;
0858: } else {
0859: descriptor = submenuImageDescriptor;
0860: }
0861: } else {
0862: return null;
0863: }
0864: } else if (item.type == ActionSetDisplayItem.TOOLITEM) {
0865: if (item.children.size() > 0) {
0866: descriptor = toolbarImageDescriptor;
0867: } else {
0868: return null;
0869: }
0870: } else {
0871: return null;
0872: }
0873: }
0874: //obtain the cached image corresponding to the descriptor
0875: if (imageTable == null) {
0876: imageTable = new Hashtable(40);
0877: }
0878: Image image = (Image) imageTable.get(descriptor);
0879: if (image == null) {
0880: image = descriptor.createImage();
0881: imageTable.put(descriptor, image);
0882: }
0883: return image;
0884: }
0885:
0886: public String getText(Object element) {
0887: if (element instanceof ActionSetDisplayItem) {
0888: ActionSetDisplayItem item = (ActionSetDisplayItem) element;
0889: String text = item.getDisplayText();
0890: if ((item.type == ActionSetDisplayItem.MENUITEM)
0891: && (item.children.size() > 0)) {
0892: text = text + " >"; //$NON-NLS-1$
0893: }
0894: return text;
0895: }
0896: return ""; //$NON-NLS-1$
0897: }
0898: }
0899:
0900: /**
0901: * Create an instance of this Dialog.
0902: *
0903: * @param configurer the configurer
0904: * @param persp the perspective
0905: */
0906: public CustomizePerspectiveDialog(
0907: IWorkbenchWindowConfigurer configurer, Perspective persp) {
0908: super (configurer.getWindow().getShell());
0909: this .configurer = configurer;
0910: perspective = persp;
0911: window = (WorkbenchWindow) configurer.getWindow();
0912:
0913: initializeActionSetInput();
0914: initializeShortcutMenuInput();
0915: }
0916:
0917: /**
0918: * Adds listeners for the Commands tab.
0919: *
0920: * @since 3.0
0921: */
0922: private void addActionSetsListeners() {
0923: tabFolder.addSelectionListener(new SelectionAdapter() {
0924: public void widgetSelected(SelectionEvent event) {
0925: handleTabSelected(event);
0926: }
0927: });
0928: actionSetsViewer
0929: .addSelectionChangedListener(new ISelectionChangedListener() {
0930: public void selectionChanged(
0931: SelectionChangedEvent event) {
0932: handleActionSetSelected(event);
0933: }
0934: });
0935: actionSetsViewer.getControl().addKeyListener(new KeyListener() {
0936: public void keyPressed(KeyEvent e) {
0937: handleActionSetViewerKeyPressed(e);
0938: }
0939:
0940: public void keyReleased(KeyEvent e) {
0941: }
0942: });
0943: actionSetMenuViewer.getControl().addKeyListener(
0944: new KeyListener() {
0945: public void keyPressed(KeyEvent e) {
0946: handleActionSetMenuViewerKeyPressed(e);
0947: }
0948:
0949: public void keyReleased(KeyEvent e) {
0950: }
0951: });
0952: actionSetToolbarViewer.getControl().addKeyListener(
0953: new KeyListener() {
0954: public void keyPressed(KeyEvent e) {
0955: handleActionSetToolbarViewerKeyPressed(e);
0956: }
0957:
0958: public void keyReleased(KeyEvent e) {
0959: }
0960: });
0961: }
0962:
0963: /**
0964: * Adds listeners for the Shortcuts tab.
0965: *
0966: * @since 3.0
0967: */
0968: private void addShortcutListeners() {
0969: menusCombo.addSelectionListener(new SelectionListener() {
0970: public void widgetDefaultSelected(SelectionEvent e) {
0971: // do nothing
0972: }
0973:
0974: public void widgetSelected(SelectionEvent e) {
0975: handleMenuSelected();
0976: }
0977: });
0978: menusCombo.addModifyListener(new ModifyListener() {
0979: public void modifyText(ModifyEvent e) {
0980: handleMenuModified();
0981: }
0982: });
0983: menuCategoriesViewer
0984: .addSelectionChangedListener(new ISelectionChangedListener() {
0985: public void selectionChanged(
0986: SelectionChangedEvent event) {
0987: handleMenuCategorySelected(event);
0988: }
0989: });
0990: menuCategoriesViewer
0991: .addCheckStateListener(new ICheckStateListener() {
0992: public void checkStateChanged(
0993: CheckStateChangedEvent event) {
0994: handleMenuCategoryChecked(event);
0995: }
0996: });
0997: menuItemsViewer
0998: .addCheckStateListener(new ICheckStateListener() {
0999: public void checkStateChanged(
1000: CheckStateChangedEvent event) {
1001: handleMenuItemChecked(event);
1002: }
1003: });
1004: }
1005:
1006: private void buildMenusAndToolbarsFor(
1007: CustomizeActionBars customizeActionBars,
1008: ActionSetDescriptor actionSetDesc) {
1009: String id = actionSetDesc.getId();
1010: ActionSetActionBars bars = new ActionSetActionBars(
1011: customizeActionBars, window, customizeActionBars, id);
1012: PluginActionSetBuilder builder = new PluginActionSetBuilder();
1013: PluginActionSet actionSet = null;
1014: try {
1015: actionSet = (PluginActionSet) actionSetDesc
1016: .createActionSet();
1017: actionSet.init(null, bars);
1018: } catch (CoreException ex) {
1019: WorkbenchPlugin
1020: .log(
1021: "Unable to create action set " + actionSetDesc.getId(), ex); //$NON-NLS-1$
1022: return;
1023: }
1024: builder.buildMenuAndToolBarStructure(actionSet, window);
1025: }
1026:
1027: private void checkInitialActionSetSelections() {
1028: // Check off the action sets that are active for the perspective.
1029: IActionSetDescriptor[] actionSetDescriptors = ((WorkbenchPage) window
1030: .getActivePage()).getActionSets();
1031: initiallyActive = Arrays.asList(actionSetDescriptors);
1032: if (actionSets != null) {
1033: for (int i = 0; i < actionSetDescriptors.length; i++) {
1034: actionSetsViewer.setChecked(actionSetDescriptors[i],
1035: true);
1036: }
1037: }
1038: }
1039:
1040: private void checkInitialMenuCategorySelections(ShortcutMenu menu) {
1041: // Check off the shortcut categories that are active for the perspective.
1042: if (menu.children.size() == 0) {
1043: updateMenuCategoryCheckedState(menu);
1044: } else {
1045: for (int i = 0; i < menu.children.size(); i++) {
1046: ShortcutMenu child = (ShortcutMenu) menu.children
1047: .get(i);
1048: checkInitialMenuCategorySelections(child);
1049: }
1050: }
1051: }
1052:
1053: public boolean close() {
1054: if (showShortcutTab()) {
1055: lastSelectedMenuIndex = menusCombo.getSelectionIndex();
1056: }
1057: lastSelectedTab = tabFolder.getSelectionIndex();
1058: IStructuredSelection selection = (IStructuredSelection) actionSetsViewer
1059: .getSelection();
1060: if (selection.isEmpty()) {
1061: lastSelectedActionSetId = null;
1062: } else {
1063: lastSelectedActionSetId = ((ActionSetDescriptor) selection
1064: .getFirstElement()).getId();
1065: }
1066: return super .close();
1067: }
1068:
1069: protected void configureShell(Shell shell) {
1070: super .configureShell(shell);
1071: String title = perspective.getDesc().getLabel();
1072:
1073: title = NLS.bind(
1074: WorkbenchMessages.ActionSetSelection_customize, title);
1075: shell.setText(title);
1076: window.getWorkbench().getHelpSystem().setHelp(shell,
1077: IWorkbenchHelpContextIds.ACTION_SET_SELECTION_DIALOG);
1078: }
1079:
1080: boolean containsActionSet(MenuManager mgr, String actionSetId) {
1081: // Return whether or not the given menuManager contains items for the
1082: // given actionSetId.
1083: IContributionItem[] menuItems = mgr.getItems();
1084: for (int j = 0; j < menuItems.length; j++) {
1085: IContributionItem menuItem = menuItems[j];
1086: if (menuItem instanceof ActionSetContributionItem) {
1087: ActionSetContributionItem actionSetItem = (ActionSetContributionItem) menuItem;
1088: if (actionSetItem.getActionSetId().equals(actionSetId)) {
1089: return true;
1090: }
1091: } else if (menuItem instanceof MenuManager) {
1092: MenuManager childMgr = (MenuManager) menuItem;
1093: boolean found = containsActionSet(childMgr, actionSetId);
1094: if (found) {
1095: return true;
1096: }
1097: }
1098: }
1099: return false;
1100: }
1101:
1102: private Composite createActionSetsPage(Composite parent) {
1103: GridData data;
1104:
1105: Composite actionSetsComposite = new Composite(parent, SWT.NONE);
1106: GridLayout layout = new GridLayout();
1107: actionSetsComposite.setLayout(layout);
1108:
1109: // Select... label
1110: Label label = new Label(actionSetsComposite, SWT.WRAP);
1111: label
1112: .setText(NLS
1113: .bind(
1114: WorkbenchMessages.ActionSetSelection_selectActionSetsLabel,
1115: perspective.getDesc().getLabel()));
1116: data = new GridData(SWT.FILL, SWT.CENTER, true, false);
1117: label.setLayoutData(data);
1118:
1119: Label sep = new Label(actionSetsComposite, SWT.HORIZONTAL
1120: | SWT.SEPARATOR);
1121: sep.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1122: false));
1123:
1124: SashForm sashComposite = new SashForm(actionSetsComposite,
1125: SWT.HORIZONTAL);
1126: data = new GridData(SWT.FILL, SWT.FILL, true, true);
1127: sashComposite.setLayoutData(data);
1128:
1129: // Action Set List Composite
1130: Composite actionSetGroup = new Composite(sashComposite,
1131: SWT.NONE);
1132: layout = new GridLayout();
1133: layout.marginHeight = 0;
1134: layout.marginWidth = 0;
1135: actionSetGroup.setLayout(layout);
1136: actionSetGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
1137: true, true));
1138:
1139: label = new Label(actionSetGroup, SWT.WRAP);
1140: label
1141: .setText(WorkbenchMessages.ActionSetSelection_availableActionSets);
1142: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1143: false));
1144:
1145: actionSetsViewer = CheckboxTableViewer.newCheckList(
1146: actionSetGroup, SWT.BORDER | SWT.H_SCROLL
1147: | SWT.V_SCROLL);
1148: actionSetsViewer.getTable().setLayoutData(
1149: new GridData(SWT.FILL, SWT.FILL, true, true));
1150: actionSetsViewer.setLabelProvider(new WorkbenchLabelProvider());
1151: actionSetsViewer.setContentProvider(new ArrayContentProvider());
1152: actionSetsViewer.setComparator(new ActionSetComparator());
1153: actionSetsViewerTooltip = new DefaultToolTip(actionSetsViewer
1154: .getControl(), ToolTip.RECREATE, true) {
1155:
1156: public Point getLocation(Point tipSize, Event event) {
1157: return getShell().getDisplay().getCursorLocation();
1158: }
1159:
1160: };
1161:
1162: // Menu and toolbar composite
1163: Composite actionGroup = new Composite(sashComposite, SWT.NONE);
1164: layout = new GridLayout();
1165: layout.numColumns = 2;
1166: layout.makeColumnsEqualWidth = true;
1167: layout.marginHeight = 0;
1168: layout.marginWidth = 0;
1169: layout.horizontalSpacing = 0;
1170: actionGroup.setLayout(layout);
1171: actionGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
1172: true, true));
1173:
1174: Composite menubarGroup = new Composite(actionGroup, SWT.NONE);
1175: layout = new GridLayout();
1176: layout.marginHeight = 0;
1177: layout.marginWidth = 0;
1178: menubarGroup.setLayout(layout);
1179: menubarGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
1180: true, true));
1181:
1182: label = new Label(menubarGroup, SWT.WRAP);
1183: label
1184: .setText(WorkbenchMessages.ActionSetSelection_menubarActions);
1185: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1186: false));
1187:
1188: actionSetMenuViewer = new TreeViewer(menubarGroup);
1189: actionSetMenuViewer
1190: .setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
1191: actionSetMenuViewer.getControl().setLayoutData(
1192: new GridData(SWT.FILL, SWT.FILL, true, true));
1193: actionSetMenuViewer
1194: .setLabelProvider(new ActionSetLabelProvider());
1195: actionSetMenuViewer
1196: .setContentProvider(new TreeContentProvider());
1197: actionSetMenuViewerTooltip = new DefaultToolTip(
1198: actionSetMenuViewer.getControl(), ToolTip.RECREATE,
1199: true) {
1200:
1201: public Point getLocation(Point tipSize, Event event) {
1202: return getShell().getDisplay().getCursorLocation();
1203: }
1204:
1205: };
1206:
1207: Composite toolbarGroup = new Composite(actionGroup, SWT.NONE);
1208: layout = new GridLayout();
1209: layout.marginHeight = 0;
1210: layout.marginWidth = 0;
1211: toolbarGroup.setLayout(layout);
1212: toolbarGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
1213: true, true));
1214:
1215: label = new Label(toolbarGroup, SWT.WRAP);
1216: label
1217: .setText(WorkbenchMessages.ActionSetSelection_toolbarActions);
1218: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1219: false));
1220:
1221: actionSetToolbarViewer = new TreeViewer(toolbarGroup);
1222: actionSetToolbarViewer
1223: .setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
1224: actionSetToolbarViewer.getControl().setLayoutData(
1225: new GridData(SWT.FILL, SWT.FILL, true, true));
1226: actionSetToolbarViewer
1227: .setLabelProvider(new ActionSetLabelProvider());
1228: actionSetToolbarViewer
1229: .setContentProvider(new TreeContentProvider());
1230: actionSetToolbarViewerTooltip = new DefaultToolTip(
1231: actionSetToolbarViewer.getControl(), ToolTip.RECREATE,
1232: true) {
1233:
1234: public Point getLocation(Point tipSize, Event event) {
1235: return getShell().getDisplay().getCursorLocation();
1236: }
1237:
1238: };
1239:
1240: sashComposite.setWeights(new int[] { 30, 70 });
1241:
1242: // Use F2... label
1243: label = new Label(actionSetsComposite, SWT.WRAP);
1244: label
1245: .setText(WorkbenchMessages.ActionSetSelection_selectActionSetsHelp);
1246: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1247: false));
1248:
1249: return actionSetsComposite;
1250: }
1251:
1252: /**
1253: * Returns whether the shortcut tab should be shown.
1254: *
1255: * @return <code>true</code> if the shortcut tab should be shown,
1256: * and <code>false</code> otherwise
1257: * @since 3.0
1258: */
1259: private boolean showShortcutTab() {
1260: return window
1261: .containsSubmenu(WorkbenchWindow.NEW_WIZARD_SUBMENU)
1262: || window
1263: .containsSubmenu(WorkbenchWindow.OPEN_PERSPECTIVE_SUBMENU)
1264: || window
1265: .containsSubmenu(WorkbenchWindow.SHOW_VIEW_SUBMENU);
1266: }
1267:
1268: protected Control createDialogArea(Composite parent) {
1269: Composite composite = (Composite) super
1270: .createDialogArea(parent);
1271:
1272: // tab folder
1273: tabFolder = new TabFolder(composite, SWT.NONE);
1274:
1275: GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
1276: gd.widthHint = convertHorizontalDLUsToPixels(TAB_WIDTH_IN_DLUS);
1277: gd.heightHint = convertVerticalDLUsToPixels(TAB_HEIGHT_IN_DLUS);
1278: tabFolder.setLayoutData(gd);
1279:
1280: // Shortcuts tab
1281: if (showShortcutTab()) {
1282: TabItem item1 = new TabItem(tabFolder, SWT.NONE);
1283: item1.setText(WorkbenchMessages.ActionSetSelection_menuTab);
1284: item1.setControl(createMenusPage(tabFolder));
1285: addShortcutListeners();
1286: ArrayList children = rootMenu.getChildren();
1287: String[] itemNames = new String[children.size()];
1288: for (int i = 0; i < children.size(); i++) {
1289: itemNames[i] = ((ShortcutMenu) children.get(i)).label;
1290: }
1291: menusCombo.setItems(itemNames);
1292: }
1293:
1294: // Commands tab
1295: TabItem item = new TabItem(tabFolder, SWT.NONE);
1296: item
1297: .setText(WorkbenchMessages.ActionSetSelection_actionSetsTab);
1298: item.setControl(createActionSetsPage(tabFolder));
1299: applyDialogFont(tabFolder);
1300: addActionSetsListeners();
1301: actionSetsViewer.setInput(actionSets);
1302: checkInitialActionSetSelections();
1303:
1304: // now that both tabs are set up, initialize selections
1305: setInitialSelections();
1306:
1307: return composite;
1308: }
1309:
1310: private Composite createMenusPage(Composite parent) {
1311: GridData data;
1312:
1313: Composite menusComposite = new Composite(parent, SWT.NONE);
1314: GridLayout layout = new GridLayout();
1315: menusComposite.setLayout(layout);
1316:
1317: // Select... label
1318: Label label = new Label(menusComposite, SWT.WRAP);
1319: label.setText(NLS.bind(
1320: WorkbenchMessages.ActionSetSelection_selectMenusLabel,
1321: perspective.getDesc().getLabel()));
1322: data = new GridData(SWT.FILL, SWT.CENTER, true, false);
1323: label.setLayoutData(data);
1324:
1325: Label sep = new Label(menusComposite, SWT.HORIZONTAL
1326: | SWT.SEPARATOR);
1327: sep.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1328: false));
1329:
1330: SashForm sashComposite = new SashForm(menusComposite,
1331: SWT.HORIZONTAL);
1332: data = new GridData(SWT.FILL, SWT.FILL, true, true);
1333: sashComposite.setLayoutData(data);
1334:
1335: // Menus List
1336: Composite menusGroup = new Composite(sashComposite, SWT.NONE);
1337: layout = new GridLayout();
1338: layout.marginHeight = 0;
1339: layout.marginWidth = 0;
1340: menusGroup.setLayout(layout);
1341: menusGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
1342: true));
1343:
1344: label = new Label(menusGroup, SWT.WRAP);
1345: label
1346: .setText(WorkbenchMessages.ActionSetSelection_availableMenus);
1347: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1348: false));
1349:
1350: menusCombo = new Combo(menusGroup, SWT.READ_ONLY);
1351: menusCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER,
1352: true, false));
1353:
1354: // Categories Tree
1355: label = new Label(menusGroup, SWT.WRAP);
1356: label
1357: .setText(WorkbenchMessages.ActionSetSelection_availableCategories);
1358: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1359: false));
1360:
1361: menuCategoriesViewer = new CheckboxTreeViewer(menusGroup);
1362: menuCategoriesViewer.getControl().setLayoutData(
1363: new GridData(SWT.FILL, SWT.FILL, true, true));
1364: menuCategoriesViewer.setLabelProvider(new LabelProvider());
1365: menuCategoriesViewer
1366: .setContentProvider(new TreeContentProvider());
1367: menuCategoriesViewer
1368: .setComparator(new WorkbenchViewerComparator());
1369:
1370: // Menu items list
1371: Composite menuItemsGroup = new Composite(sashComposite,
1372: SWT.NONE);
1373: layout = new GridLayout();
1374: layout.marginHeight = 0;
1375: layout.marginWidth = 0;
1376: menuItemsGroup.setLayout(layout);
1377: menuItemsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
1378: true, true));
1379:
1380: label = new Label(menuItemsGroup, SWT.WRAP);
1381: label.setText(WorkbenchMessages.ActionSetSelection_menuItems);
1382: label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
1383: false));
1384:
1385: menuItemsViewer = CheckboxTableViewer.newCheckList(
1386: menuItemsGroup, SWT.BORDER | SWT.H_SCROLL
1387: | SWT.V_SCROLL);
1388: Table menuTable = menuItemsViewer.getTable();
1389: menuTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
1390: true));
1391: menuItemsViewer
1392: .setLabelProvider(new ShortcutMenuItemLabelProvider());
1393: menuItemsViewer
1394: .setContentProvider(new ShortcutMenuItemContentProvider());
1395: menuItemsViewer.setComparator(new WorkbenchViewerComparator());
1396:
1397: menuTable.setHeaderVisible(true);
1398: int[] columnWidths = new int[shortcutMenuColumnWidths.length];
1399: for (int i = 0; i < shortcutMenuColumnWidths.length; i++) {
1400: columnWidths[i] = convertHorizontalDLUsToPixels(shortcutMenuColumnWidths[i]);
1401: }
1402: for (int i = 0; i < shortcutMenuColumnHeaders.length; i++) {
1403: TableColumn tc = new TableColumn(menuTable, SWT.NONE, i);
1404: tc.setResizable(true);
1405: tc.setText(shortcutMenuColumnHeaders[i]);
1406: tc.setWidth(columnWidths[i]);
1407: }
1408: sashComposite.setWeights(new int[] { 30, 70 });
1409: return menusComposite;
1410: }
1411:
1412: void handleActionSetMenuViewerKeyPressed(KeyEvent event) {
1413: // popup the description for the selected action set menu item
1414: if (event.keyCode == SWT.F2 && event.stateMask == 0) {
1415: IStructuredSelection sel = (IStructuredSelection) actionSetMenuViewer
1416: .getSelection();
1417: ActionSetDisplayItem element = (ActionSetDisplayItem) sel
1418: .getFirstElement();
1419: if (element != null) {
1420: String desc = element.description;
1421: if (desc == null || desc.equals("")) { //$NON-NLS-1$
1422: desc = WorkbenchMessages.ActionSetSelection_noDesc;
1423: }
1424: actionSetMenuViewerTooltip.setText(desc);
1425: // Passing 0,0 because tooltip is always opened on current cursor position
1426: actionSetMenuViewerTooltip.show(new Point(0, 0));
1427: }
1428: }
1429: }
1430:
1431: void handleActionSetSelected(SelectionChangedEvent event) {
1432: IStructuredSelection sel = (IStructuredSelection) event
1433: .getSelection();
1434: ActionSetDescriptor element = (ActionSetDescriptor) sel
1435: .getFirstElement();
1436: if (element == selectedActionSet) {
1437: return;
1438: }
1439: String actionSetId = element.getId();
1440: // Hash table is used to cache previous selections
1441: ArrayList structures = (ArrayList) actionSetStructures
1442: .get(actionSetId);
1443: ActionSetDisplayItem menubarStructure = null;
1444: ActionSetDisplayItem toolbarStructure = null;
1445: // If the actionset has never been selected then we need to populate the structures
1446: if (structures == null) {
1447: structures = new ArrayList(2);
1448: menubarStructure = new ActionSetDisplayItem("Menubar"); //$NON-NLS-1$
1449: toolbarStructure = new ActionSetDisplayItem("Toolbar"); //$NON-NLS-1$
1450:
1451: // Build the menus and toolbars for it using our fake action bars.
1452: // Can't reuse customizeActionBars between action sets due to action set menu reuse. See bug 94827 for details.
1453: CustomizeActionBars customizeActionBars = new CustomizeActionBars(
1454: configurer);
1455: // Fill current actionBars in the "fake" workbench action bars
1456: window.fillActionBars(customizeActionBars,
1457: ActionBarAdvisor.FILL_PROXY
1458: | ActionBarAdvisor.FILL_MENU_BAR
1459: | ActionBarAdvisor.FILL_COOL_BAR);
1460: // Populate the action bars with the action set
1461: buildMenusAndToolbarsFor(customizeActionBars, element);
1462: // Build the representation to show
1463: menubarStructure.fillMenusFor(actionSetId,
1464: customizeActionBars.menuManager);
1465: toolbarStructure.fillToolsFor(actionSetId,
1466: customizeActionBars.coolBarManager);
1467: // Be sure to dispose the custom bars or we'll leak
1468: customizeActionBars.dispose();
1469:
1470: // Add menubarStructure and toolbarStructure to arrayList
1471: structures.add(menubarStructure);
1472: structures.add(toolbarStructure);
1473: // Add the structure to the hash table with key actionSetId
1474: actionSetStructures.put(actionSetId, structures);
1475: }
1476: // retrieve the actionsets from the arraylist
1477: if (menubarStructure == null) {
1478: menubarStructure = (ActionSetDisplayItem) structures.get(0);
1479: }
1480: if (toolbarStructure == null) {
1481: toolbarStructure = (ActionSetDisplayItem) structures.get(1);
1482: }
1483:
1484: // fill the menu structure table
1485: actionSetMenuViewer.setInput(menubarStructure);
1486: if (menubarStructure.children.size() > 0) {
1487: actionSetMenuViewer
1488: .reveal(menubarStructure.children.get(0));
1489: }
1490:
1491: // fill the toolbar structure table
1492: actionSetToolbarViewer.setInput(toolbarStructure);
1493: if (toolbarStructure.children.size() > 0) {
1494: actionSetToolbarViewer.reveal(toolbarStructure.children
1495: .get(0));
1496: }
1497: selectedActionSet = element;
1498: }
1499:
1500: void handleActionSetToolbarViewerKeyPressed(KeyEvent event) {
1501: // popup the description for the selected action set toolbar item
1502: if (event.keyCode == SWT.F2 && event.stateMask == 0) {
1503: IStructuredSelection sel = (IStructuredSelection) actionSetToolbarViewer
1504: .getSelection();
1505: ActionSetDisplayItem element = (ActionSetDisplayItem) sel
1506: .getFirstElement();
1507: if (element != null) {
1508: String desc = element.description;
1509: if (desc == null || desc.equals("")) { //$NON-NLS-1$
1510: desc = WorkbenchMessages.ActionSetSelection_noDesc;
1511: }
1512: actionSetToolbarViewerTooltip.setText(desc);
1513: // Passing 0,0 because tooltip is always opened on current cursor position
1514: actionSetToolbarViewerTooltip.show(new Point(0, 0));
1515: }
1516: }
1517: }
1518:
1519: void handleActionSetViewerKeyPressed(KeyEvent event) {
1520: // popup the description for the selected action set
1521: if (event.keyCode == SWT.F2 && event.stateMask == 0) {
1522: IStructuredSelection sel = (IStructuredSelection) actionSetsViewer
1523: .getSelection();
1524: ActionSetDescriptor element = (ActionSetDescriptor) sel
1525: .getFirstElement();
1526: if (element != null) {
1527: String desc = element.getDescription();
1528: if (desc == null || desc.equals("")) { //$NON-NLS-1$
1529: desc = WorkbenchMessages.ActionSetSelection_noDesc;
1530: }
1531: actionSetsViewerTooltip.setText(desc);
1532: // Passing 0,0 because tooltip is always opened on current cursor position
1533: actionSetsViewerTooltip.show(new Point(0, 0));
1534: }
1535: }
1536: }
1537:
1538: void handleMenuCategoryChecked(CheckStateChangedEvent event) {
1539: ShortcutMenu checkedCategory = (ShortcutMenu) event
1540: .getElement();
1541: boolean checked = event.getChecked();
1542: checkedCategory.checked(checked);
1543: // check/uncheck the element's category subtree
1544: menuCategoriesViewer
1545: .setSubtreeChecked(checkedCategory, checked);
1546: // set gray state of the element's category subtree, all items should
1547: // not be grayed
1548: ArrayList subtree = checkedCategory.getSubtreeItems();
1549: ShortcutMenu menuItemInput = (ShortcutMenu) menuItemsViewer
1550: .getInput();
1551: for (int i = 0; i < subtree.size(); i++) {
1552: Object child = subtree.get(i);
1553: menuCategoriesViewer.setGrayed(child, false);
1554: if (child == menuItemInput) {
1555: menuItemsViewer.setAllChecked(checked);
1556: }
1557: }
1558: menuCategoriesViewer.setGrayed(checkedCategory, false);
1559: updateMenuCategoryCheckedState(checkedCategory.parent);
1560: }
1561:
1562: void handleMenuCategorySelected(SelectionChangedEvent event) {
1563: IStructuredSelection sel = (IStructuredSelection) event
1564: .getSelection();
1565: ShortcutMenu element = (ShortcutMenu) sel.getFirstElement();
1566: if (element == selectedMenuCategory) {
1567: return;
1568: }
1569: if (element != menuItemsViewer.getInput()) {
1570: menuItemsViewer.setInput(element);
1571: }
1572: if (element != null) {
1573: menuItemsViewer.setCheckedElements(element
1574: .getCheckedItems().toArray());
1575: }
1576: }
1577:
1578: void handleMenuItemChecked(CheckStateChangedEvent event) {
1579: ShortcutMenu selectedMenu = (ShortcutMenu) menuItemsViewer
1580: .getInput();
1581: boolean itemChecked = event.getChecked();
1582: Object item = event.getElement();
1583: if (itemChecked) {
1584: selectedMenu.addCheckedItem(item);
1585: } else {
1586: selectedMenu.removeCheckedItem(item);
1587: }
1588: updateMenuCategoryCheckedState(selectedMenu);
1589: }
1590:
1591: void handleMenuModified() {
1592: String text = menusCombo.getText();
1593: String[] items = menusCombo.getItems();
1594: int itemIndex = -1;
1595: for (int i = 0; i < items.length; i++) {
1596: if (items[i].equals(text)) {
1597: itemIndex = i;
1598: break;
1599: }
1600: }
1601: if (itemIndex == -1) {
1602: return;
1603: }
1604: ShortcutMenu element = (ShortcutMenu) rootMenu.children
1605: .get(itemIndex);
1606: handleMenuSelected(element);
1607: }
1608:
1609: void handleMenuSelected() {
1610: int i = menusCombo.getSelectionIndex();
1611: ShortcutMenu element = (ShortcutMenu) rootMenu.children.get(i);
1612: handleMenuSelected(element);
1613: }
1614:
1615: void handleMenuSelected(ShortcutMenu element) {
1616: if (element != menuCategoriesViewer.getInput()) {
1617: menuCategoriesViewer.setInput(element);
1618: menuCategoriesViewer.expandAll();
1619: if (element != null) {
1620: if (element.getChildren().size() > 0) {
1621: StructuredSelection sel = new StructuredSelection(
1622: element.getChildren().get(0));
1623: menuCategoriesViewer.setSelection(sel, true);
1624: } else {
1625: menuItemsViewer.setInput(element);
1626: menuItemsViewer.setCheckedElements(element
1627: .getCheckedItems().toArray());
1628: }
1629: } else {
1630: menuCategoriesViewer.setInput(element);
1631: menuItemsViewer.setInput(element);
1632: }
1633: checkInitialMenuCategorySelections(rootMenu);
1634: }
1635: }
1636:
1637: void handleTabSelected(SelectionEvent event) {
1638: TabItem item = (TabItem) event.item;
1639: Control control = item.getControl();
1640: if (control != null) {
1641: control.setFocus();
1642: }
1643: }
1644:
1645: private void initializeActionSetInput() {
1646: // Just get the action sets at this point. Do not load the action set until it
1647: // is actually selected in the dialog.
1648: ActionSetRegistry reg = WorkbenchPlugin.getDefault()
1649: .getActionSetRegistry();
1650: IActionSetDescriptor[] sets = reg.getActionSets();
1651: for (int i = 0; i < sets.length; i++) {
1652: ActionSetDescriptor actionSetDesc = (ActionSetDescriptor) sets[i];
1653: if (WorkbenchActivityHelper.filterItem(actionSetDesc)) {
1654: continue;
1655: }
1656: actionSets.add(actionSetDesc);
1657: }
1658: String iconPath = "$nl$/icons/full/obj16/menu.gif";//$NON-NLS-1$
1659: URL url = BundleUtility.find(PlatformUI.PLUGIN_ID, iconPath);
1660: menuImageDescriptor = ImageDescriptor.createFromURL(url);
1661:
1662: iconPath = "$nl$/icons/full/obj16/submenu.gif";//$NON-NLS-1$
1663: url = BundleUtility.find(PlatformUI.PLUGIN_ID, iconPath);
1664: submenuImageDescriptor = ImageDescriptor.createFromURL(url);
1665:
1666: iconPath = "$nl$/icons/full/obj16/toolbar.gif";//$NON-NLS-1$
1667: url = BundleUtility.find(PlatformUI.PLUGIN_ID, iconPath);
1668: toolbarImageDescriptor = ImageDescriptor.createFromURL(url);
1669: }
1670:
1671: private void initializeShortCutMenu(ShortcutMenu menu,
1672: IWizardCategory element, List activeIds) {
1673: ShortcutMenu category = new ShortcutMenu(menu, element.getId(),
1674: element.getLabel());
1675: Object[] wizards = element.getWizards();
1676: for (int i = 0; i < wizards.length; i++) {
1677: WorkbenchWizardElement wizard = (WorkbenchWizardElement) wizards[i];
1678: category.addItem(wizard);
1679: if (activeIds.contains(wizard.getId())) {
1680: category.addCheckedItem(wizard);
1681: }
1682: }
1683: // @issue should not pass in null
1684: IWizardCategory[] children = element.getCategories();
1685: for (int i = 0; i < children.length; i++) {
1686: initializeShortCutMenu(category, children[i], activeIds);
1687: }
1688: }
1689:
1690: private void initializeShortcutMenuInput() {
1691: rootMenu = new ShortcutMenu(null, "Root", ""); //$NON-NLS-1$ //$NON-NLS-2$
1692: List activeIds;
1693:
1694: if (window.containsSubmenu(WorkbenchWindow.NEW_WIZARD_SUBMENU)) {
1695: ShortcutMenu wizardMenu = new ShortcutMenu(
1696: rootMenu,
1697: ShortcutMenu.ID_WIZARD,
1698: WorkbenchMessages.ActionSetDialogInput_wizardCategory);
1699:
1700: IWizardCategory wizardCollection = WorkbenchPlugin
1701: .getDefault().getNewWizardRegistry()
1702: .getRootCategory();
1703:
1704: IWizardCategory[] wizardCategories = wizardCollection
1705: .getCategories();
1706: activeIds = Arrays.asList(perspective
1707: .getNewWizardShortcuts());
1708: for (int i = 0; i < wizardCategories.length; i++) {
1709: IWizardCategory element = wizardCategories[i];
1710: if (WorkbenchActivityHelper.filterItem(element)) {
1711: continue;
1712: }
1713: initializeShortCutMenu(wizardMenu, element, activeIds);
1714: }
1715: }
1716:
1717: if (window
1718: .containsSubmenu(WorkbenchWindow.OPEN_PERSPECTIVE_SUBMENU)) {
1719: ShortcutMenu perspMenu = new ShortcutMenu(
1720: rootMenu,
1721: ShortcutMenu.ID_PERSP,
1722: WorkbenchMessages.ActionSetDialogInput_perspectiveCategory);
1723: IPerspectiveRegistry perspReg = WorkbenchPlugin
1724: .getDefault().getPerspectiveRegistry();
1725: IPerspectiveDescriptor[] persps = perspReg
1726: .getPerspectives();
1727: for (int i = 0; i < persps.length; i++) {
1728: if (WorkbenchActivityHelper.filterItem(persps[i])) {
1729: continue;
1730: }
1731: perspMenu.addItem(persps[i]);
1732: }
1733: activeIds = Arrays.asList(perspective
1734: .getPerspectiveShortcuts());
1735: for (int i = 0; i < activeIds.size(); i++) {
1736: String id = (String) activeIds.get(i);
1737: Object item = perspMenu.getItem(id);
1738: if (item != null) {
1739: perspMenu.addCheckedItem(item);
1740: }
1741: }
1742: }
1743:
1744: if (window.containsSubmenu(WorkbenchWindow.SHOW_VIEW_SUBMENU)) {
1745: ShortcutMenu viewMenu = new ShortcutMenu(rootMenu,
1746: ShortcutMenu.ID_VIEW,
1747: WorkbenchMessages.ActionSetDialogInput_viewCategory);
1748: IViewRegistry viewReg = WorkbenchPlugin.getDefault()
1749: .getViewRegistry();
1750: IViewCategory[] categories = viewReg.getCategories();
1751: activeIds = Arrays.asList(perspective
1752: .getShowViewShortcuts());
1753: for (int i = 0; i < categories.length; i++) {
1754: IViewCategory category = categories[i];
1755: if (WorkbenchActivityHelper.filterItem(category)) {
1756: continue;
1757: }
1758: ShortcutMenu viewCategory = new ShortcutMenu(viewMenu,
1759: category.getId(), category.getLabel());
1760: IViewDescriptor[] views = category.getViews();
1761: if (views != null) {
1762: for (int j = 0; j < views.length; j++) {
1763: IViewDescriptor view = views[j];
1764: if (view.getId().equals(
1765: IIntroConstants.INTRO_VIEW_ID)) {
1766: continue;
1767: }
1768: if (WorkbenchActivityHelper.filterItem(view)) {
1769: continue;
1770: }
1771: viewCategory.addItem(view);
1772: if (activeIds.contains(view.getId())) {
1773: viewCategory.addCheckedItem(view);
1774: }
1775: }
1776: }
1777: }
1778: }
1779: }
1780:
1781: protected void okPressed() {
1782: if (showShortcutTab()) {
1783: ArrayList menus = rootMenu.children;
1784: for (int i = 0; i < menus.size(); i++) {
1785: ShortcutMenu menu = (ShortcutMenu) menus.get(i);
1786: if (ShortcutMenu.ID_VIEW.equals(menu.id)) {
1787: perspective.setShowViewActionIds(menu
1788: .getCheckedItemIds());
1789: } else if (ShortcutMenu.ID_PERSP.equals(menu.id)) {
1790: perspective.setPerspectiveActionIds(menu
1791: .getCheckedItemIds());
1792: } else if (ShortcutMenu.ID_WIZARD.equals(menu.id)) {
1793: perspective.setNewWizardActionIds(menu
1794: .getCheckedItemIds());
1795: }
1796: }
1797: }
1798:
1799: ArrayList toAdd = new ArrayList();
1800: ArrayList toRemove = new ArrayList();
1801: toRemove.addAll(initiallyActive);
1802:
1803: Object[] selected = actionSetsViewer.getCheckedElements();
1804: for (int i = 0; i < selected.length; i++) {
1805: Object obj = selected[i];
1806: toRemove.remove(obj);
1807: if (!initiallyActive.contains(toRemove)) {
1808: toAdd.add(obj);
1809: }
1810: }
1811:
1812: perspective.turnOnActionSets((IActionSetDescriptor[]) toAdd
1813: .toArray(new IActionSetDescriptor[toAdd.size()]));
1814: perspective.turnOffActionSets((IActionSetDescriptor[]) toRemove
1815: .toArray(new IActionSetDescriptor[toAdd.size()]));
1816:
1817: super .okPressed();
1818: }
1819:
1820: String removeShortcut(String label) {
1821: if (label == null) {
1822: return label;
1823: }
1824: int end = label.lastIndexOf('@');
1825: if (end >= 0) {
1826: label = label.substring(0, end);
1827: }
1828: return label;
1829: }
1830:
1831: private void setInitialSelections() {
1832: Object item = actionSetsViewer.getElementAt(0);
1833: if (lastSelectedActionSetId != null) {
1834: for (int i = 0; i < actionSets.size(); i++) {
1835: ActionSetDescriptor actionSet = (ActionSetDescriptor) actionSets
1836: .get(i);
1837: if (actionSet.getId().equals(lastSelectedActionSetId)) {
1838: item = actionSet;
1839: break;
1840: }
1841: }
1842: }
1843: if (item != null) {
1844: StructuredSelection sel = new StructuredSelection(item);
1845: actionSetsViewer.setSelection(sel, true);
1846: }
1847:
1848: if (showShortcutTab()) {
1849: menusCombo.select(lastSelectedMenuIndex);
1850: }
1851:
1852: if (lastSelectedTab != -1) {
1853: tabFolder.setSelection(lastSelectedTab);
1854: }
1855:
1856: if ((tabFolder.getSelectionIndex() == 0) && showShortcutTab()) {
1857: menusCombo.setFocus();
1858: } else {
1859: actionSetsViewer.getControl().setFocus();
1860: }
1861: }
1862:
1863: private void updateMenuCategoryCheckedState(ShortcutMenu menu) {
1864: if (menu == rootMenu) {
1865: return;
1866: }
1867: if (menu.isFullyChecked()) {
1868: menuCategoriesViewer.setParentsGrayed(menu, false);
1869: menuCategoriesViewer.setChecked(menu, true);
1870: } else if (menu.isFullyUnchecked()) {
1871: menuCategoriesViewer.setParentsGrayed(menu, false);
1872: menuCategoriesViewer.setChecked(menu, false);
1873: } else {
1874: menuCategoriesViewer.setParentsGrayed(menu, true);
1875: menuCategoriesViewer.setChecked(menu, true);
1876: }
1877: updateMenuCategoryCheckedState(menu.parent);
1878: }
1879:
1880: /* (non-Javadoc)
1881: * @see org.eclipse.jface.dialogs.Dialog#applyDialogFont()
1882: */
1883: protected boolean applyDialogFont() {
1884: return false;
1885: }
1886:
1887: /*
1888: * (non-Javadoc)
1889: * @see org.eclipse.jface.dialogs.Dialog#isResizable()
1890: */
1891: protected boolean isResizable() {
1892: return true;
1893: }
1894: }
|