/******************************************************************************* * Copyright (c) 2000, 2007 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.actions; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WorkingSetComparator; import org.eclipse.ui.internal.WorkingSetMenuContributionItem; import org.eclipse.ui.internal.actions.ClearWorkingSetAction; import org.eclipse.ui.internal.actions.EditWorkingSetAction; import org.eclipse.ui.internal.actions.SelectWorkingSetAction; import org.eclipse.ui.internal.util.Util; /** * Adds working set filter actions (set / clear / edit) * * @since 2.1 */ public class WorkingSetFilterActionGroup extends ActionGroup { private static final String TAG_WORKING_SET_NAME = "workingSetName"; //$NON-NLS-1$ private static final String TAG_IS_WINDOW_WORKING_SET = "isWindowWorkingSet"; //$NON-NLS-1$ /** * Indicates if working set was changed */ public static final String CHANGE_WORKING_SET = "changeWorkingSet"; //$NON-NLS-1$ private static final String START_SEPARATOR_ID = "workingSetGroupStartSeparator"; //$NON-NLS-1$ private static final String SEPARATOR_ID = "workingSetGroupSeparator"; //$NON-NLS-1$ private static final String WORKING_SET_ACTION_GROUP = "workingSetActionGroup"; //$NON-NLS-1$ private IWorkingSet workingSet = null; private ClearWorkingSetAction clearWorkingSetAction; private SelectWorkingSetAction selectWorkingSetAction; private EditWorkingSetAction editWorkingSetAction; private IPropertyChangeListener workingSetUpdater; private int mruMenuCount; private IMenuManager menuManager; private IMenuListener menuListener; private IWorkbenchWindow workbenchWindow; private IWorkbenchPage page; private boolean allowWindowWorkingSetByDefault; /** * Creates a new instance of the receiver. * * @param shell * shell to open dialogs and wizards on * @param workingSetUpdater * property change listener notified when a working set is set * @since 3.2 Please note that it is expected that clients treat any * selected working sets whose * {@link IWorkingSet#isAggregateWorkingSet()} method returns * <code>true</code> somewhat differently from traditional working * sets. Please see the documentation for * {@link IWorkbenchPage#getAggregateWorkingSet()} for details. */ public WorkingSetFilterActionGroup(Shell shell, IPropertyChangeListener workingSetUpdater) { Assert.isNotNull(shell); this.workingSetUpdater = workingSetUpdater; clearWorkingSetAction = new ClearWorkingSetAction(this); selectWorkingSetAction = new SelectWorkingSetAction(this, shell); editWorkingSetAction = new EditWorkingSetAction(this, shell); workbenchWindow = Util.getWorkbenchWindowForShell(shell); allowWindowWorkingSetByDefault = false; // set the default working set to be that of the window. page = workbenchWindow.getActivePage(); if (page == null) { IWorkbenchPage[] pages = workbenchWindow.getPages(); if (pages.length > 0) { page = pages[0]; } } } /** * Adds actions for the most recently used working sets to the specified * menu manager. * * @param menuManager * menu manager to add actions to */ private void addMruWorkingSetActions(IMenuManager menuManager) { IWorkingSet[] workingSets = PlatformUI.getWorkbench() .getWorkingSetManager().getRecentWorkingSets(); List sortedWorkingSets = Arrays.asList(workingSets); Collections.sort(sortedWorkingSets, new WorkingSetComparator()); Iterator iter = sortedWorkingSets.iterator(); mruMenuCount = 0; while (iter.hasNext()) { IWorkingSet workingSet = (IWorkingSet) iter.next(); if (workingSet != null) { IContributionItem item = new WorkingSetMenuContributionItem( ++mruMenuCount, this, workingSet); menuManager.insertBefore(SEPARATOR_ID, item); } } } /* (non-Javadoc) * @see org.eclipse.ui.actions.ActionGroup#dispose() */ public void dispose() { if (menuManager != null) { menuManager.removeMenuListener(menuListener); } super.dispose(); } /* (non-Javadoc) * @see org.eclipse.ui.actions.ActionGroup#fillActionBars(org.eclipse.ui.IActionBars) */ public void fillActionBars(IActionBars actionBars) { menuManager = actionBars.getMenuManager(); if(menuManager.find(IWorkbenchActionConstants.MB_ADDITIONS) != null) menuManager.insertAfter(IWorkbenchActionConstants.MB_ADDITIONS, new Separator(WORKING_SET_ACTION_GROUP)); else menuManager.add(new Separator(WORKING_SET_ACTION_GROUP)); menuManager.appendToGroup(WORKING_SET_ACTION_GROUP, selectWorkingSetAction); menuManager.appendToGroup(WORKING_SET_ACTION_GROUP, clearWorkingSetAction); menuManager.appendToGroup(WORKING_SET_ACTION_GROUP, editWorkingSetAction); menuManager.appendToGroup(WORKING_SET_ACTION_GROUP, new Separator(START_SEPARATOR_ID)); menuManager.appendToGroup(WORKING_SET_ACTION_GROUP, new Separator(SEPARATOR_ID)); menuListener = new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { removePreviousMruWorkingSetActions(manager); addMruWorkingSetActions(manager); } }; menuManager.addMenuListener(menuListener); } /* (non-Javadoc) * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager) */ public void fillContextMenu(IMenuManager menuManager) { menuManager.add(selectWorkingSetAction); menuManager.add(clearWorkingSetAction); menuManager.add(editWorkingSetAction); menuManager.add(new Separator()); menuManager.add(new Separator(SEPARATOR_ID)); menuListener = new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { removePreviousMruWorkingSetActions(manager); addMruWorkingSetActions(manager); } }; menuManager.addMenuListener(menuListener); } /** * Returns the working set which is currently selected. * * @return the working set which is currently selected. */ public IWorkingSet getWorkingSet() { return workingSet; } /** * Removes the most recently used working set actions that were * added to the specified menu. * * @param menuManager menu manager to remove actions from */ private void removePreviousMruWorkingSetActions(IMenuManager menuManager) { for (int i = 1; i <= mruMenuCount; i++) { menuManager.remove(WorkingSetMenuContributionItem.getId(i)); } } /** * Sets the current working set. * * @param newWorkingSet the new working set */ public void setWorkingSet(IWorkingSet newWorkingSet) { IWorkingSet oldWorkingSet = workingSet; workingSet = newWorkingSet; // Update action clearWorkingSetAction.setEnabled(newWorkingSet != null); editWorkingSetAction.setEnabled(newWorkingSet != null && newWorkingSet.isEditable()); firePropertyChange(newWorkingSet, oldWorkingSet); } /** * Fire the property change to the updater if there is one available. * * @param newWorkingSet the new working set * @param oldWorkingSet the previous working set * @since 3.2 */ private void firePropertyChange(IWorkingSet newWorkingSet, IWorkingSet oldWorkingSet) { // Update viewer if (workingSetUpdater != null) { workingSetUpdater.propertyChange(new PropertyChangeEvent(this, WorkingSetFilterActionGroup.CHANGE_WORKING_SET, oldWorkingSet, newWorkingSet)); } } /** * Saves the state of the filter actions in a memento. * * @param memento * the memento * @since 3.3 */ public void saveState(IMemento memento) { String workingSetName = ""; //$NON-NLS-1$ boolean isWindowWorkingSet = false; if (workingSet != null) { if (workingSet.isAggregateWorkingSet()) { isWindowWorkingSet = true; } else { workingSetName = workingSet.getName(); } } memento.putString(TAG_IS_WINDOW_WORKING_SET, isWindowWorkingSet ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ memento.putString(TAG_WORKING_SET_NAME, workingSetName); } /** * Restores the state of the filter actions from a memento. * <p> * Note: This method does not refresh the viewer. * </p> * * @param memento * @since 3.3 */ public void restoreState(IMemento memento) { boolean isWindowWorkingSet; if (memento.getString(TAG_IS_WINDOW_WORKING_SET) != null) { isWindowWorkingSet = Boolean.valueOf( memento.getString(TAG_IS_WINDOW_WORKING_SET)) .booleanValue(); } else { isWindowWorkingSet = useWindowWorkingSetByDefault(); } String workingSetName = memento.getString(TAG_WORKING_SET_NAME); boolean hasWorkingSetName = workingSetName != null && workingSetName.length() > 0; IWorkingSet ws = null; // First handle name if present. if (hasWorkingSetName) { ws = PlatformUI.getWorkbench().getWorkingSetManager() .getWorkingSet(workingSetName); } else if (isWindowWorkingSet && page != null) { ws = page.getAggregateWorkingSet(); } setWorkingSet(ws); } private boolean useWindowWorkingSetByDefault() { return allowWindowWorkingSetByDefault && PlatformUI .getPreferenceStore() .getBoolean( IWorkbenchPreferenceConstants.USE_WINDOW_WORKING_SET_BY_DEFAULT); } }