/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.ui.toolbar;
import org.eclipse.che.ide.api.action.Action;
import org.eclipse.che.ide.api.action.ActionEvent;
import org.eclipse.che.ide.api.action.ActionGroup;
import org.eclipse.che.ide.api.action.ActionManager;
import org.eclipse.che.ide.api.action.Presentation;
import org.eclipse.che.ide.api.action.Separator;
import org.eclipse.che.ide.api.parts.PerspectiveManager;
import org.eclipse.che.ide.util.loging.Log;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author Evgen Vidolob
* @author Dmitry Shnurenko
* @author Oleksii Orel
*/
public class Utils {
/**
* Returns the list of visible action group.
*
* @param group
* action group
* @param presentationFactory
* presentation factory
* @param actionManager
* action manager
* @param perspectiveManager
* perspective manager
* @return list of visible action group
*/
public static List<VisibleActionGroup> renderActionGroup(@NotNull ActionGroup group,
PresentationFactory presentationFactory,
ActionManager actionManager,
PerspectiveManager perspectiveManager) {
Presentation presentation = presentationFactory.getPresentation(group);
ActionEvent event = new ActionEvent(presentation, actionManager, perspectiveManager);
if (!presentation.isVisible()) { // don't process invisible groups
return null;
}
Action[] children = group.getChildren(event);
List<VisibleActionGroup> currentVisibleActionGroupList = new ArrayList<>();
List<Action> currentActionList = new ArrayList<>();
String currentGroupId = actionManager.getId(group);
for (Action child : children) {
if (child == null) {
Log.error(Utils.class, "action is null: group=" + group + " group id=" + currentGroupId);
continue;
}
presentation = presentationFactory.getPresentation(child);
child.update(new ActionEvent(presentation, actionManager, perspectiveManager));
if (!presentation.isVisible()) { // don't create invisible items in the menu
continue;
}
if (child instanceof ActionGroup) {
ActionGroup actionGroup = (ActionGroup)child;
if (actionGroup.isPopup()) { // popup menu has its own presentation
if (actionGroup.disableIfNoVisibleChildren()) {
final boolean visibleChildren = hasVisibleChildren(actionGroup,
presentationFactory,
actionManager,
perspectiveManager);
if (actionGroup.hideIfNoVisibleChildren() && !visibleChildren) {
continue;
}
presentation.setEnabled(actionGroup.canBePerformed() || visibleChildren);
}
currentActionList.add(child);
} else {
List<VisibleActionGroup> newVisibleActionGroupList = renderActionGroup((ActionGroup)child,
presentationFactory,
actionManager,
perspectiveManager);
currentVisibleActionGroupList.addAll(newVisibleActionGroupList);
}
} else if (child instanceof Separator) {
if ((((Separator)child).getText() != null) ||
(!currentActionList.isEmpty() && !(currentActionList.get(currentActionList.size() - 1) instanceof Separator))) {
currentActionList.add(child);
}
} else {
currentActionList.add(child);
}
}
currentVisibleActionGroupList.add(0, new VisibleActionGroup(currentGroupId, currentActionList));
return currentVisibleActionGroupList;
}
/**
* Returns true if action group has visible children.
*
* @param group
* action group
* @param factory
* presentation factory
* @param actionManager
* action manager
* @param perspectiveManager
* perspective manager
* @return boolean
*/
public static boolean hasVisibleChildren(ActionGroup group,
PresentationFactory factory,
ActionManager actionManager,
PerspectiveManager perspectiveManager) {
ActionEvent event = new ActionEvent(factory.getPresentation(group), actionManager, perspectiveManager);
for (Action anAction : group.getChildren(event)) {
if (anAction == null) {
Log.error(Utils.class, "Null action found in group " + group + ", " + factory.getPresentation(group));
continue;
}
if (anAction instanceof Separator) {
continue;
}
final Presentation presentation = factory.getPresentation(anAction);
anAction.update(new ActionEvent(presentation, actionManager, perspectiveManager));
if (anAction instanceof ActionGroup) {
ActionGroup childGroup = (ActionGroup)anAction;
// popup menu must be visible itself
if (childGroup.isPopup()) {
if (!presentation.isVisible()) {
continue;
}
}
if (hasVisibleChildren(childGroup, factory, actionManager, perspectiveManager)) {
return true;
}
} else if (presentation.isVisible()) {
return true;
}
}
return false;
}
public static class VisibleActionGroup {
private String groupId;
private List<Action> actionList;
/**
* Creates a new <code>VisibleActionGroup</code> with the specified groupId
* and actionList.
*
* @param groupId
* Action group ID
* @param actionList
* List of actions
*/
public VisibleActionGroup(String groupId, List<Action> actionList) {
this.groupId = groupId;
this.actionList = actionList;
}
public String getGroupId() {
return groupId;
}
public List<Action> getActionList() {
return actionList;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof VisibleActionGroup)) {
return false;
}
VisibleActionGroup other = (VisibleActionGroup)o;
return Objects.equals(groupId, other.groupId)
&& Objects.equals(actionList, other.actionList);
}
@Override
public int hashCode() {
return Objects.hash(groupId, actionList);
}
}
}