blob: 4afa7a882831793994b05c76775aefbd48cc4b0f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 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
* Benjamin Muskalla - Bug 169023 [WorkingSets] "Add to working set"
* drop down should include a "new working set" option
*******************************************************************************/
package org.eclipse.ui.internal.actions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
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.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionDelegate2;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.QuickMenuCreator;
import org.eclipse.ui.dialogs.IWorkingSetNewWizard;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
/**
* @since 3.3
*
*/
public class ModifyWorkingSetDelegate extends
AbstractWorkingSetPulldownDelegate implements IExecutableExtension, IActionDelegate2 {
public class NewWorkingSetAction extends Action {
/**
* Create a new instance of this action.
*/
public NewWorkingSetAction() {
super(WorkbenchMessages.NewWorkingSet);
}
public void run() {
IWorkingSetManager manager = WorkbenchPlugin.getDefault()
.getWorkingSetManager();
IWorkingSetNewWizard wizard = manager.createWorkingSetNewWizard(null);
// the wizard can never be null since we have at least a resource
// working set
// creation page
WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench()
.getDisplay().getActiveShell(), wizard);
dialog.create();
PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(),
IWorkbenchHelpContextIds.WORKING_SET_NEW_WIZARD);
if (dialog.open() == Window.OK) {
IWorkingSet workingSet = wizard.getSelection();
if(workingSet != null) {
manager.addWorkingSet(workingSet);
}
}
}
}
private class ModifyAction extends Action {
private IWorkingSet set;
private IAdaptable [] selectedElements;
/**
* @param set
* @param selectedElements
* @param add
*/
private ModifyAction(IWorkingSet set, IAdaptable [] selectedElements) {
super(set.getLabel(), IAction.AS_CHECK_BOX);
this.set = set;
this.selectedElements = selectedElements;
setImageDescriptor(set.getImageDescriptor());
}
public void run() {
Collection oldElements = Arrays.asList(set.getElements());
Set newElements = new HashSet(oldElements.size()
+ selectedElements.length);
newElements.addAll(oldElements);
List selectedAsList = Arrays.asList(selectedElements);
if (add) {
newElements.addAll(selectedAsList);
} else {
newElements.removeAll(selectedAsList);
}
set.setElements((IAdaptable[]) newElements
.toArray(new IAdaptable[newElements.size()]));
}
}
private QuickMenuCreator contextMenuCreator = new QuickMenuCreator() {
protected void fillMenu(IMenuManager menu) {
ModifyWorkingSetDelegate.this.fillMenu(menu);
}
};
private boolean add = true;
private IPropertyChangeListener listener = new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
refreshEnablement();
}
/**
*
*/
private void refreshEnablement() {
selectionChanged(actionProxy, getSelection());
}
};
private IAction actionProxy;
/**
*
*/
public ModifyWorkingSetDelegate() {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
public void run(IAction action) {
contextMenuCreator.createMenu();
}
/* (non-Javadoc)
* @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event)
*/
public void runWithEvent(IAction action, Event event) {
if (event.type == SWT.KeyDown || event.type == SWT.KeyUp)
run(action);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.actions.AbstractWorkingSetPulldownDelegate#init(org.eclipse.ui.IWorkbenchWindow)
*/
public void init(IWorkbenchWindow window) {
super.init(window);
getWindow().getWorkbench().getWorkingSetManager()
.addPropertyChangeListener(listener);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.actions.AbstractWorkingSetPulldownDelegate#dispose()
*/
public void dispose() {
getWindow().getWorkbench().getWorkingSetManager()
.removePropertyChangeListener(listener);
super.dispose();
contextMenuCreator.dispose();
}
public void fillMenu(Menu menu) {
List menuItems = getItems();
for (int i = 0; i < menuItems.size(); i++) {
Object object = menuItems.get(i);
if (object instanceof IAction) {
ActionContributionItem item = new ActionContributionItem((IAction) object);
item.fill(menu, -1);
} else {
IContributionItem item = (IContributionItem) object;
item.fill(menu, -1);
}
}
// create working set action only for add menu
if(add) {
IContributionItem item = null;
if (menu.getItemCount() > 0) {
item = new Separator();
item.fill(menu, -1);
}
item = new ActionContributionItem(new NewWorkingSetAction());
item.fill(menu, -1);
}
}
/**
* Return the list of items to show in the submenu.
*
* @return the items to show in the submenu
*/
private List getItems() {
List menuItems = new ArrayList();
ISelection selection = getSelection();
if (!(selection instanceof IStructuredSelection)) {
if(!add) {
IAction emptyAction = new Action(WorkbenchMessages.NoApplicableWorkingSets) {};
emptyAction.setEnabled(false);
menuItems.add(emptyAction);
}
return menuItems;
}
IWorkingSet[][] typedSets = splitSets();
Object [] selectedElements = ((IStructuredSelection)selection).toArray();
// keep a tab of whether or not we need a separator. If a given type
// of working set has contributed some items then this will be true
// after the processing of the working set type. The next type will
// then consult this field and add a separator before adding any
// items of its own. In this way the list will never end with a
// separator.
boolean needsSeparator = false;
for (int i = 0; i < typedSets.length; i++) {
int oldCount = menuItems.size();
IWorkingSet[] sets = typedSets[i];
for (int j = 0; j < sets.length; j++) {
IWorkingSet set = sets[j];
Set existingElements = new HashSet();
existingElements.addAll(Arrays
.asList(set.getElements()));
boolean visible = false;
IAdaptable [] adaptables = new IAdaptable[selectedElements.length];
System.arraycopy(selectedElements, 0, adaptables, 0, selectedElements.length);
adaptables = set.adaptElements(adaptables);
if (adaptables.length > 0 && add) {
for (int k = 0; k < adaptables.length; k++) {
if (!existingElements.contains(adaptables[k])) {
// show if any element is not present in
// addition
visible = true;
break;
}
}
}
else if (adaptables.length > 0) {
for (int k = 0; k < adaptables.length; k++) {
if (existingElements.contains(adaptables[k]))
visible = true; // show if any element
// is present in removal
break;
}
}
if (visible) {
if (needsSeparator) {
menuItems.add(new Separator());
needsSeparator = false;
}
ModifyAction action = new ModifyAction(set,
adaptables);
menuItems.add(action);
}
}
// we need a separator if we needed one before but never added it or
// we've added new items to the list.
needsSeparator |= menuItems.size() > oldCount;
}
if (menuItems.isEmpty() && !add) {
IAction emptyAction = new Action(
WorkbenchMessages.NoApplicableWorkingSets) {
};
emptyAction.setEnabled(false);
menuItems.add(emptyAction);
}
return menuItems;
}
private void fillMenu(IMenuManager menu) {
List menuItems = getItems();
for (int i = 0; i < menuItems.size(); i++) {
Object object = menuItems.get(i);
if (object instanceof IAction) {
menu.add((IAction) object);
} else {
IContributionItem item = (IContributionItem) object;
menu.add(item);
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.internal.actions.AbstractWorkingSetPulldownDelegate#selectionChanged(org.eclipse.jface.action.IAction,
* org.eclipse.jface.viewers.ISelection)
*/
public void selectionChanged(IAction actionProxy, ISelection selection) {
super.selectionChanged(actionProxy, selection);
if (selection instanceof IStructuredSelection) {
Object[] selectedElements = ((IStructuredSelection) getSelection())
.toArray();
// ensure every item is of type IAdaptable and is NOT an IWorkingSet (minimal fix for 157799)
boolean minimallyOkay = true;
for (int i = 0; i < selectedElements.length; i++) {
Object object = selectedElements[i];
if (!(object instanceof IAdaptable) || object instanceof IWorkingSet) {
minimallyOkay = false;
break;
}
}
actionProxy.setEnabled(minimallyOkay);
}
else
actionProxy.setEnabled(false);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
* java.lang.String, java.lang.Object)
*/
public void setInitializationData(IConfigurationElement config,
String propertyName, Object data) {
if (data instanceof String) {
add = Boolean.valueOf((String) data).booleanValue();
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction)
*/
public void init(IAction action) {
this.actionProxy = action;
}
}