blob: 5c8f055244c95eccc8fc77dead896e4e700f4c6b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.SubActionBars;
import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2;
import org.eclipse.ui.internal.registry.IActionSet;
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
/**
* Manage the configurable actions for one window.
*/
public class ActionPresentation {
private WorkbenchWindow window;
private Map<IActionSetDescriptor, SetRec> mapDescToRec = new HashMap<>(3);
private Map<IActionSetDescriptor, SetRec> invisibleBars = new HashMap<>(3);
private static class SetRec {
public SetRec(IActionSet set, SubActionBars bars) {
this.set = set;
this.bars = bars;
}
public IActionSet set;
public SubActionBars bars;
}
/**
* ActionPresentation constructor comment.
*
* @param window the workbench window to manage actions for
*/
public ActionPresentation(WorkbenchWindow window) {
super();
this.window = window;
}
/**
* Remove all action sets.
*/
public void clearActionSets() {
// Get all of the action sets -- both visible and invisible.
final List<IActionSetDescriptor> oldList = new ArrayList<>();
oldList.addAll(mapDescToRec.keySet());
oldList.addAll(invisibleBars.keySet());
Iterator<IActionSetDescriptor> iter = oldList.iterator();
while (iter.hasNext()) {
IActionSetDescriptor desc = iter.next();
removeActionSet(desc);
}
}
/**
* Destroy an action set.
*
* @param desc an actions set to destroy
*/
public void removeActionSet(IActionSetDescriptor desc) {
SetRec rec = mapDescToRec.remove(desc);
if (rec == null) {
rec = invisibleBars.remove(desc);
}
if (rec != null) {
IActionSet set = rec.set;
SubActionBars bars = rec.bars;
if (bars != null) {
bars.dispose();
}
if (set != null) {
set.dispose();
}
}
}
/**
* Sets the list of visible action set.
*
* @param newArray the list of visible action set
*/
public void setActionSets(IActionSetDescriptor[] newArray) {
// Convert array to list.
Set<IActionSetDescriptor> newList = new HashSet<>();
newList.addAll(Arrays.asList(newArray));
List<IActionSetDescriptor> oldList = new ArrayList<>(mapDescToRec.keySet());
// Remove obsolete actions.
Iterator<IActionSetDescriptor> iter = oldList.iterator();
while (iter.hasNext()) {
IActionSetDescriptor desc = iter.next();
if (!newList.contains(desc)) {
SetRec rec = mapDescToRec.get(desc);
if (rec != null) {
mapDescToRec.remove(desc);
IActionSet set = rec.set;
SubActionBars bars = rec.bars;
if (bars != null) {
SetRec invisibleRec = new SetRec(set, bars);
invisibleBars.put(desc, invisibleRec);
bars.deactivate();
}
}
}
}
// Add new actions.
List<PluginActionSet> sets = new ArrayList<>();
for (IActionSetDescriptor desc : newArray) {
if (!mapDescToRec.containsKey(desc)) {
try {
SetRec rec;
// If the action bars and sets have already been created
// then
// reuse those action sets
if (invisibleBars.containsKey(desc)) {
rec = invisibleBars.get(desc);
if (rec.bars != null) {
rec.bars.activate();
}
invisibleBars.remove(desc);
} else {
IActionSet set = desc.createActionSet();
SubActionBars bars = new ActionSetActionBars(window.getActionBars(), window,
(IActionBarConfigurer2) window.getWindowConfigurer().getActionBarConfigurer(),
desc.getId());
rec = new SetRec(set, bars);
set.init(window, bars);
if (set instanceof PluginActionSet) {
PluginActionSet pluginActionSet = (PluginActionSet) set;
sets.add(pluginActionSet);
} else {
String pattern = "Ignored unexpected IActionSet implementation for descriptor {0}: {1}"; //$NON-NLS-1$
WorkbenchPlugin.log(NLS.bind(pattern, desc.getId(), set));
}
// only register against the tracker once - check for
// other registrations against the provided extension
Object[] existingRegistrations = window.getExtensionTracker()
.getObjects(desc.getConfigurationElement().getDeclaringExtension());
if (existingRegistrations.length == 0 || !containsRegistration(existingRegistrations, desc)) {
// register the set with the page tracker
// this will be cleaned up by WorkbenchWindow listener
window.getExtensionTracker().registerObject(
desc.getConfigurationElement().getDeclaringExtension(), desc,
IExtensionTracker.REF_WEAK);
}
}
mapDescToRec.put(desc, rec);
} catch (CoreException e) {
WorkbenchPlugin.log("Unable to create ActionSet: " + desc.getId(), e);//$NON-NLS-1$
}
}
}
// We process action sets in two passes for coolbar purposes. First we
// process base contributions
// (i.e., actions that the action set contributes to its toolbar), then
// we process adjunct contributions
// (i.e., actions that the action set contributes to other toolbars).
// This type of processing is
// necessary in order to maintain group order within a coolitem.
PluginActionSetBuilder.processActionSets(sets, window);
Iterator<PluginActionSet> setIterator = sets.iterator();
while (setIterator.hasNext()) {
PluginActionSet set = setIterator.next();
set.getBars().activate();
}
}
/**
* Return whether the array contains the given action set.
*
* @param existingRegistrations the array to check
* @param set the set to look for
* @return whether the set is in the array
* @since 3.1
*/
private boolean containsRegistration(Object[] existingRegistrations, IActionSetDescriptor set) {
for (Object existingRegistration : existingRegistrations) {
if (existingRegistration == set) {
return true;
}
}
return false;
}
/**
* @return the list of visible action set
*/
public IActionSet[] getActionSets() {
Collection<SetRec> setRecCollection = mapDescToRec.values();
IActionSet result[] = new IActionSet[setRecCollection.size()];
int i = 0;
for (Iterator<SetRec> iterator = setRecCollection.iterator(); iterator.hasNext(); i++) {
result[i] = (iterator.next()).set;
}
return result;
}
}