001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Benjamin Muskalla - Bug 169023 [WorkingSets] "Add to working set"
011: * drop down should include a "new working set" option
012: *******************************************************************************/package org.eclipse.ui.internal.actions;
013:
014: import java.util.ArrayList;
015: import java.util.Arrays;
016: import java.util.Collection;
017: import java.util.HashSet;
018: import java.util.List;
019: import java.util.Set;
020:
021: import org.eclipse.core.runtime.IAdaptable;
022: import org.eclipse.core.runtime.IConfigurationElement;
023: import org.eclipse.core.runtime.IExecutableExtension;
024: import org.eclipse.jface.action.Action;
025: import org.eclipse.jface.action.ActionContributionItem;
026: import org.eclipse.jface.action.IAction;
027: import org.eclipse.jface.action.IContributionItem;
028: import org.eclipse.jface.action.IMenuManager;
029: import org.eclipse.jface.action.Separator;
030: import org.eclipse.jface.util.IPropertyChangeListener;
031: import org.eclipse.jface.util.PropertyChangeEvent;
032: import org.eclipse.jface.viewers.ISelection;
033: import org.eclipse.jface.viewers.IStructuredSelection;
034: import org.eclipse.jface.window.Window;
035: import org.eclipse.jface.wizard.WizardDialog;
036: import org.eclipse.swt.SWT;
037: import org.eclipse.swt.widgets.Event;
038: import org.eclipse.swt.widgets.Menu;
039: import org.eclipse.ui.IActionDelegate2;
040: import org.eclipse.ui.IWorkbenchWindow;
041: import org.eclipse.ui.IWorkingSet;
042: import org.eclipse.ui.IWorkingSetManager;
043: import org.eclipse.ui.PlatformUI;
044: import org.eclipse.ui.actions.QuickMenuCreator;
045: import org.eclipse.ui.dialogs.IWorkingSetNewWizard;
046: import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
047: import org.eclipse.ui.internal.WorkbenchMessages;
048: import org.eclipse.ui.internal.WorkbenchPlugin;
049:
050: /**
051: * @since 3.3
052: *
053: */
054: public class ModifyWorkingSetDelegate extends
055: AbstractWorkingSetPulldownDelegate implements
056: IExecutableExtension, IActionDelegate2 {
057:
058: public class NewWorkingSetAction extends Action {
059:
060: /**
061: * Create a new instance of this action.
062: */
063: public NewWorkingSetAction() {
064: super (WorkbenchMessages.NewWorkingSet);
065: }
066:
067: public void run() {
068: IWorkingSetManager manager = WorkbenchPlugin.getDefault()
069: .getWorkingSetManager();
070: IWorkingSetNewWizard wizard = manager
071: .createWorkingSetNewWizard(null);
072: // the wizard can never be null since we have at least a resource
073: // working set
074: // creation page
075: WizardDialog dialog = new WizardDialog(PlatformUI
076: .getWorkbench().getDisplay().getActiveShell(),
077: wizard);
078:
079: dialog.create();
080: PlatformUI.getWorkbench().getHelpSystem().setHelp(
081: dialog.getShell(),
082: IWorkbenchHelpContextIds.WORKING_SET_NEW_WIZARD);
083: if (dialog.open() == Window.OK) {
084: IWorkingSet workingSet = wizard.getSelection();
085: if (workingSet != null) {
086: manager.addWorkingSet(workingSet);
087: }
088: }
089: }
090:
091: }
092:
093: private class ModifyAction extends Action {
094:
095: private IWorkingSet set;
096:
097: private IAdaptable[] selectedElements;
098:
099: /**
100: * @param set
101: * @param selectedElements
102: * @param add
103: */
104: private ModifyAction(IWorkingSet set,
105: IAdaptable[] selectedElements) {
106: super (set.getLabel(), IAction.AS_CHECK_BOX);
107: this .set = set;
108: this .selectedElements = selectedElements;
109: setImageDescriptor(set.getImageDescriptor());
110: }
111:
112: public void run() {
113:
114: Collection oldElements = Arrays.asList(set.getElements());
115: Set newElements = new HashSet(oldElements.size()
116: + selectedElements.length);
117: newElements.addAll(oldElements);
118: List selectedAsList = Arrays.asList(selectedElements);
119: if (add) {
120: newElements.addAll(selectedAsList);
121: } else {
122: newElements.removeAll(selectedAsList);
123: }
124: set.setElements((IAdaptable[]) newElements
125: .toArray(new IAdaptable[newElements.size()]));
126: }
127: }
128:
129: private QuickMenuCreator contextMenuCreator = new QuickMenuCreator() {
130: protected void fillMenu(IMenuManager menu) {
131: ModifyWorkingSetDelegate.this .fillMenu(menu);
132: }
133: };
134:
135: private boolean add = true;
136:
137: private IPropertyChangeListener listener = new IPropertyChangeListener() {
138:
139: public void propertyChange(PropertyChangeEvent event) {
140: refreshEnablement();
141: }
142:
143: /**
144: *
145: */
146: private void refreshEnablement() {
147: selectionChanged(actionProxy, getSelection());
148: }
149: };
150:
151: private IAction actionProxy;
152:
153: /**
154: *
155: */
156: public ModifyWorkingSetDelegate() {
157: }
158:
159: /*
160: * (non-Javadoc)
161: *
162: * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
163: */
164: public void run(IAction action) {
165: contextMenuCreator.createMenu();
166: }
167:
168: /* (non-Javadoc)
169: * @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event)
170: */
171: public void runWithEvent(IAction action, Event event) {
172: if (event.type == SWT.KeyDown || event.type == SWT.KeyUp)
173: run(action);
174: }
175:
176: /*
177: * (non-Javadoc)
178: *
179: * @see org.eclipse.ui.internal.actions.AbstractWorkingSetPulldownDelegate#init(org.eclipse.ui.IWorkbenchWindow)
180: */
181: public void init(IWorkbenchWindow window) {
182: super .init(window);
183: getWindow().getWorkbench().getWorkingSetManager()
184: .addPropertyChangeListener(listener);
185: }
186:
187: /*
188: * (non-Javadoc)
189: *
190: * @see org.eclipse.ui.internal.actions.AbstractWorkingSetPulldownDelegate#dispose()
191: */
192: public void dispose() {
193: getWindow().getWorkbench().getWorkingSetManager()
194: .removePropertyChangeListener(listener);
195: super .dispose();
196: contextMenuCreator.dispose();
197: }
198:
199: public void fillMenu(Menu menu) {
200: List menuItems = getItems();
201: for (int i = 0; i < menuItems.size(); i++) {
202: Object object = menuItems.get(i);
203: if (object instanceof IAction) {
204: ActionContributionItem item = new ActionContributionItem(
205: (IAction) object);
206: item.fill(menu, -1);
207: } else {
208: IContributionItem item = (IContributionItem) object;
209: item.fill(menu, -1);
210: }
211: }
212: // create working set action only for add menu
213: if (add) {
214: IContributionItem item = null;
215: if (menu.getItemCount() > 0) {
216: item = new Separator();
217: item.fill(menu, -1);
218: }
219:
220: item = new ActionContributionItem(new NewWorkingSetAction());
221: item.fill(menu, -1);
222: }
223: }
224:
225: /**
226: * Return the list of items to show in the submenu.
227: *
228: * @return the items to show in the submenu
229: */
230: private List getItems() {
231: List menuItems = new ArrayList();
232: ISelection selection = getSelection();
233: if (!(selection instanceof IStructuredSelection)) {
234: if (!add) {
235: IAction emptyAction = new Action(
236: WorkbenchMessages.NoApplicableWorkingSets) {
237: };
238: emptyAction.setEnabled(false);
239: menuItems.add(emptyAction);
240: }
241: return menuItems;
242: }
243:
244: IWorkingSet[][] typedSets = splitSets();
245: Object[] selectedElements = ((IStructuredSelection) selection)
246: .toArray();
247:
248: // keep a tab of whether or not we need a separator. If a given type
249: // of working set has contributed some items then this will be true
250: // after the processing of the working set type. The next type will
251: // then consult this field and add a separator before adding any
252: // items of its own. In this way the list will never end with a
253: // separator.
254: boolean needsSeparator = false;
255:
256: for (int i = 0; i < typedSets.length; i++) {
257: int oldCount = menuItems.size();
258:
259: IWorkingSet[] sets = typedSets[i];
260: for (int j = 0; j < sets.length; j++) {
261: IWorkingSet set = sets[j];
262:
263: Set existingElements = new HashSet();
264: existingElements.addAll(Arrays
265: .asList(set.getElements()));
266:
267: boolean visible = false;
268: IAdaptable[] adaptables = new IAdaptable[selectedElements.length];
269: System.arraycopy(selectedElements, 0, adaptables, 0,
270: selectedElements.length);
271: adaptables = set.adaptElements(adaptables);
272: if (adaptables.length > 0 && add) {
273: for (int k = 0; k < adaptables.length; k++) {
274: if (!existingElements.contains(adaptables[k])) {
275: // show if any element is not present in
276: // addition
277: visible = true;
278: break;
279: }
280: }
281: } else if (adaptables.length > 0) {
282: for (int k = 0; k < adaptables.length; k++) {
283: if (existingElements.contains(adaptables[k]))
284: visible = true; // show if any element
285: // is present in removal
286: break;
287: }
288: }
289:
290: if (visible) {
291: if (needsSeparator) {
292: menuItems.add(new Separator());
293: needsSeparator = false;
294: }
295: ModifyAction action = new ModifyAction(set,
296: adaptables);
297: menuItems.add(action);
298: }
299: }
300: // we need a separator if we needed one before but never added it or
301: // we've added new items to the list.
302: needsSeparator |= menuItems.size() > oldCount;
303: }
304: if (menuItems.isEmpty() && !add) {
305: IAction emptyAction = new Action(
306: WorkbenchMessages.NoApplicableWorkingSets) {
307: };
308: emptyAction.setEnabled(false);
309: menuItems.add(emptyAction);
310: }
311: return menuItems;
312: }
313:
314: private void fillMenu(IMenuManager menu) {
315: List menuItems = getItems();
316: for (int i = 0; i < menuItems.size(); i++) {
317: Object object = menuItems.get(i);
318: if (object instanceof IAction) {
319: menu.add((IAction) object);
320: } else {
321: IContributionItem item = (IContributionItem) object;
322: menu.add(item);
323: }
324: }
325: }
326:
327: /*
328: * (non-Javadoc)
329: *
330: * @see org.eclipse.ui.internal.actions.AbstractWorkingSetPulldownDelegate#selectionChanged(org.eclipse.jface.action.IAction,
331: * org.eclipse.jface.viewers.ISelection)
332: */
333: public void selectionChanged(IAction actionProxy,
334: ISelection selection) {
335: super .selectionChanged(actionProxy, selection);
336: if (selection instanceof IStructuredSelection) {
337: Object[] selectedElements = ((IStructuredSelection) getSelection())
338: .toArray();
339: // ensure every item is of type IAdaptable and is NOT an IWorkingSet (minimal fix for 157799)
340: boolean minimallyOkay = true;
341: for (int i = 0; i < selectedElements.length; i++) {
342: Object object = selectedElements[i];
343: if (!(object instanceof IAdaptable)
344: || object instanceof IWorkingSet) {
345: minimallyOkay = false;
346: break;
347: }
348: }
349: actionProxy.setEnabled(minimallyOkay);
350:
351: } else
352: actionProxy.setEnabled(false);
353: }
354:
355: /*
356: * (non-Javadoc)
357: *
358: * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
359: * java.lang.String, java.lang.Object)
360: */
361: public void setInitializationData(IConfigurationElement config,
362: String propertyName, Object data) {
363: if (data instanceof String) {
364: add = Boolean.valueOf((String) data).booleanValue();
365: }
366: }
367:
368: /* (non-Javadoc)
369: * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction)
370: */
371: public void init(IAction action) {
372: this.actionProxy = action;
373: }
374: }
|