/* * Copyright (c) 2006, 2007 Borland Software 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: * Borland Software Corporation - initial API and implementation */ package org.eclipse.gmf.graphdef.editor.edit.parts; import java.text.Collator; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.gef.EditPart; import org.eclipse.gmf.gmfgraph.RealFigure; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuCreator; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.MenuListener; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart; // TODO: is it used? public class SelectStackedElementsAction extends Action implements IMenuCreator, MenuListener, IObjectActionDelegate { public static final String EMPTY_STRING = ""; //$NON-NLS-1$ /** * The menu created by this action */ private Menu myMenu; private AbstractFigureEditPart mySelectedElement; public void setActivePart(IAction action, IWorkbenchPart targetPart) { action.setMenuCreator(getMenuCreator()); } public IMenuCreator getMenuCreator() { return this; } public Menu getMenu(Control parent) { return createMenu(parent); } public Menu getMenu(Menu parent) { return createMenu(parent); } protected Menu createMenu(Widget parent) { if (parent == null) { return null; } if (myMenu != null) { myMenu.dispose(); } myMenu = createMenuFromMenuOrControlParent(parent); myMenu.addMenuListener(this); return myMenu; } public void menuShown(MenuEvent e) { clearMenu(myMenu); fillMenu(myMenu, mySelectedElement); } public void menuHidden(MenuEvent e) { } public void dispose() { if (myMenu != null) { myMenu.dispose(); } myMenu = null; } private void clearMenu(Menu menu) { MenuItem[] actions = menu.getItems(); for (int i=0; i<actions.length; i++) { actions[i].dispose(); } } private static Menu createMenuFromMenuOrControlParent(Widget parent) { Menu result = null; if (parent instanceof Menu) { result = new Menu((Menu)parent); } else if (parent instanceof Control) { result = new Menu((Control) parent); } return result; } private static void fillMenu(Menu menu, EditPart selectedElement) { if (selectedElement == null) { return; } int numChildren = selectedElement.getChildren().size(); IAction[] selectChildActions = new IAction[numChildren]; List expandChildrenActions = new ArrayList(numChildren); for (int i=0; i<numChildren; i++) { final EditPart next = (EditPart) selectedElement.getChildren().get(i); String className = next.getClass().getName(); String preciseName = String.valueOf(i); if (next instanceof AbstractFigureEditPart) { View model = (View) ((AbstractFigureEditPart) next).getModel(); RealFigure modelElement = (RealFigure) model.getElement(); className = modelElement.eClass().getName(); String elementName = modelElement.getName(); if (elementName != null && elementName.length() != 0) { preciseName = elementName; } } String selectChildCommandName = MessageFormat.format("{0}:{1}", new Object[] {className, preciseName}); selectChildActions[i] = new SelectChildAction(next, selectChildCommandName); if (next.getChildren().size() > 0) { String expandChildrenCommandName = numChildren > 1 ? MessageFormat.format("Select Children of {0}", new Object[] {selectChildCommandName}) : "Select Children"; expandChildrenActions.add(new ExpandChildrenAction(next, expandChildrenCommandName)); } } for (int i=0; i<selectChildActions.length; i++) { ActionContributionItem item = new ActionContributionItem(selectChildActions[i]); item.fill(menu, -1); } int numExpandableCommands = expandChildrenActions.size(); if (numExpandableCommands > 0) { new MenuItem(menu, SWT.SEPARATOR, selectChildActions.length); for (int i=0; i<numExpandableCommands; i++) { IAction next = (IAction) expandChildrenActions.get(i); ActionContributionItem item = new ActionContributionItem(next); item.fill(menu, selectChildActions.length + i + 1); } } } public void run(IAction action) { //do nothing, this action just creates a cascading menu. } public void selectionChanged(IAction action, ISelection selection) { mySelectedElement = null; if (selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection) selection; if (structuredSelection.size() == 1 && structuredSelection.getFirstElement() instanceof AbstractFigureEditPart) { mySelectedElement = (AbstractFigureEditPart) structuredSelection.getFirstElement(); } } action.setEnabled(isEnabled()); } public boolean isEnabled() { return mySelectedElement != null && mySelectedElement.getChildren().size() > 0; } private static class SelectChildAction extends Action implements Comparable { private final EditPart myTarget; private final String myName; public SelectChildAction(EditPart target, String name) { super(name, IAction.AS_PUSH_BUTTON); myName = name; myTarget = target; } public EditPart getTargetPart() { return myTarget; } public String getName() { return myName; } public void run() { myTarget.getViewer().select(myTarget); } public int compareTo(Object o) { if (!(o instanceof SelectChildAction)) { return -1; } String otherName = ((SelectChildAction)o).getName(); return Collator.getInstance().compare(getName(), otherName); } } private static class ExpandChildrenAction extends Action implements IMenuCreator, Comparable { private final EditPart myTarget; private final String myName; private Menu myMenu; public ExpandChildrenAction(EditPart target, String name) { super(name, IAction.AS_DROP_DOWN_MENU); myName = name; myTarget = target; } public IMenuCreator getMenuCreator() { return this; } public EditPart getTargetPart() { return myTarget; } public String getName() { return myName; } public void run() { //do nothing, this action just creates a cascading menu. } public int compareTo(Object o) { if (!(o instanceof SelectChildAction)) { return -1; } String otherName = ((SelectChildAction)o).getName(); return Collator.getInstance().compare(getName(), otherName); } public void dispose() { if (myMenu != null) { myMenu.dispose(); } myMenu = null; } public Menu getMenu(Control parent) { return createMenu(parent); } public Menu getMenu(Menu parent) { return createMenu(parent); } private Menu createMenu(Widget parent) { if (myMenu == null) { if (parent == null) { return null; } myMenu = SelectStackedElementsAction.createMenuFromMenuOrControlParent(parent); SelectStackedElementsAction.fillMenu(myMenu, myTarget); } return myMenu; } } }