blob: 87584a0075241e0d65da64d499a2587898fecabb [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.actions;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.PresentationFactory;
import com.intellij.openapi.actionSystem.impl.Utils;
import com.intellij.openapi.diagnostic.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
/**
* @author peter
*/
public abstract class WeighingActionGroup extends ActionGroup {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.WeighingActionGroup");
private final PresentationFactory myPresentationFactory = new PresentationFactory();
@Override
public void update(AnActionEvent e) {
getDelegate().update(e);
}
protected abstract ActionGroup getDelegate();
private static void getAllChildren(@Nullable AnActionEvent e, ActionGroup group, List<AnAction> result) {
for (final AnAction action : group.getChildren(e)) {
if (action == null) {
LOG.error("Null child for " + group + " of class " + group.getClass());
continue;
}
if (action instanceof ActionGroup && !((ActionGroup)action).isPopup()) {
getAllChildren(e, (ActionGroup)action, result);
}
else {
result.add(action);
}
}
}
@Override
@NotNull
public AnAction[] getChildren(@Nullable AnActionEvent e) {
final AnAction[] children = getDelegate().getChildren(e);
if (e == null) {
return children;
}
final ArrayList<AnAction> all = new ArrayList<AnAction>();
getAllChildren(e, getDelegate(), all);
LinkedHashSet<AnAction> heaviest = null;
double maxWeight = Presentation.DEFAULT_WEIGHT;
for (final AnAction action : all) {
final Presentation presentation = myPresentationFactory.getPresentation(action);
presentation.setWeight(Presentation.DEFAULT_WEIGHT);
Utils.updateGroupChild(e.getDataContext(), e.getPlace(), action, presentation);
if (presentation.isEnabled() && presentation.isVisible()) {
if (presentation.getWeight() > maxWeight) {
maxWeight = presentation.getWeight();
heaviest = new LinkedHashSet<AnAction>();
}
if (presentation.getWeight() == maxWeight && heaviest != null) {
heaviest.add(action);
}
}
}
if (heaviest == null) {
return children;
}
final DefaultActionGroup chosen = new DefaultActionGroup();
boolean prevSeparator = true;
for (final AnAction action : all) {
final boolean separator = action instanceof Separator;
if (separator && !prevSeparator) {
chosen.add(action);
}
prevSeparator = separator;
if (shouldBeChosenAnyway(action)) {
heaviest.add(action);
}
if (heaviest.contains(action)) {
chosen.add(action);
}
}
final ActionGroup other = new ExcludingActionGroup(getDelegate(), heaviest);
other.setPopup(true);
other.getTemplatePresentation().setText("Other...");
return new AnAction[]{chosen, new Separator(), other};
}
protected boolean shouldBeChosenAnyway(AnAction action) {
return false;
}
}