You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by re...@apache.org on 2015/03/26 19:51:52 UTC
[03/51] [partial] incubator-taverna-workbench git commit: all
packages are moved to org.apache.taverna.*
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java
deleted file mode 100644
index 29b8057..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java
+++ /dev/null
@@ -1,880 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.ui.menu.impl;
-
-import static java.lang.Math.min;
-import static javax.help.CSH.setHelpIDString;
-import static javax.swing.Action.NAME;
-import static javax.swing.Action.SHORT_DESCRIPTION;
-import static net.sf.taverna.t2.lang.ui.ShadedLabel.GREEN;
-import static net.sf.taverna.t2.ui.menu.AbstractMenuSection.SECTION_COLOR;
-import static net.sf.taverna.t2.ui.menu.DefaultContextualMenu.DEFAULT_CONTEXT_MENU;
-import static net.sf.taverna.t2.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
-import static net.sf.taverna.t2.ui.menu.DefaultToolBar.DEFAULT_TOOL_BAR;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.lang.ref.WeakReference;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.WeakHashMap;
-
-import javax.swing.AbstractButton;
-import javax.swing.Action;
-import javax.swing.ButtonGroup;
-import javax.swing.JButton;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-import javax.swing.JRadioButtonMenuItem;
-import javax.swing.JToggleButton;
-import javax.swing.JToolBar;
-import javax.swing.border.EmptyBorder;
-
-import org.apache.taverna.lang.observer.MultiCaster;
-import org.apache.taverna.lang.observer.Observable;
-import org.apache.taverna.lang.observer.Observer;
-import org.apache.taverna.lang.observer.SwingAwareObserver;
-import net.sf.taverna.t2.lang.ui.ShadedLabel;
-import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
-import net.sf.taverna.t2.ui.menu.AbstractMenuOptionGroup;
-import net.sf.taverna.t2.ui.menu.ContextualMenuComponent;
-import net.sf.taverna.t2.ui.menu.ContextualSelection;
-import net.sf.taverna.t2.ui.menu.DesignOnlyAction;
-import net.sf.taverna.t2.ui.menu.DesignOrResultsAction;
-import net.sf.taverna.t2.ui.menu.MenuComponent;
-import net.sf.taverna.t2.ui.menu.MenuComponent.MenuType;
-import net.sf.taverna.t2.ui.menu.MenuManager;
-import net.sf.taverna.t2.workbench.selection.SelectionManager;
-import net.sf.taverna.t2.workbench.selection.events.PerspectiveSelectionEvent;
-import net.sf.taverna.t2.workbench.selection.events.SelectionManagerEvent;
-
-import org.apache.log4j.Logger;
-
-/**
- * Implementation of {@link MenuManager}.
- *
- * @author Stian Soiland-Reyes
- */
-public class MenuManagerImpl implements MenuManager {
- private static Logger logger = Logger.getLogger(MenuManagerImpl.class);
-
- private boolean needsUpdate;
- /**
- * Cache used by {@link #getURIByComponent(Component)}
- */
- private WeakHashMap<Component, URI> componentToUri;
- /**
- * {@link MenuElementComparator} used for sorting menu components from the
- * SPI registry.
- */
- private MenuElementComparator menuElementComparator = new MenuElementComparator();
- /**
- * Map of {@link URI} to it's discovered children. Populated by
- * {@link #findChildren()}.
- */
- private HashMap<URI, List<MenuComponent>> menuElementTree;
- /**
- * Multicaster to distribute messages to {@link Observer}s of this menu
- * manager.
- */
- private MultiCaster<MenuManagerEvent> multiCaster;
- /**
- * Lock for {@link #update()}
- */
- private final Object updateLock = new Object();
- /**
- * True if {@link #doUpdate()} is running, subsequents call to
- * {@link #update()} will return immediately.
- */
- private boolean updating;
- /**
- * Cache used by {@link #getComponentByURI(URI)}
- */
- private Map<URI, WeakReference<Component>> uriToComponent;
- /**
- * Map from {@link URI} to defining {@link MenuComponent}. Children are in
- * {@link #menuElementTree}.
- */
- private Map<URI, MenuComponent> uriToMenuElement;
- // Note: Not reset by #resetCollections()
- private Map<URI, List<WeakReference<Component>>> uriToPublishedComponents = new HashMap<>();
- private List<MenuComponent> menuComponents = new ArrayList<>();
-
- /**
- * Construct the MenuManagerImpl. Observes the SPI registry and does an
- * initial {@link #update()}.
- */
- public MenuManagerImpl() {
- multiCaster = new MultiCaster<>(this);
- needsUpdate = true;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addMenuItemsWithExpansion(List<JMenuItem> menuItems,
- JMenu parentMenu, int maxItemsInMenu,
- ComponentFactory headerItemFactory) {
- if (menuItems.size() <= maxItemsInMenu) {
- // Just add them directly
- for (JMenuItem menuItem : menuItems)
- parentMenu.add(menuItem);
- return;
- }
- int index = 0;
- while (index < menuItems.size()) {
- int toIndex = min(menuItems.size(), index + maxItemsInMenu);
- if (toIndex == menuItems.size() - 1)
- // Don't leave a single item left for the last subMenu
- toIndex--;
- List<JMenuItem> subList = menuItems.subList(index, toIndex);
- JMenuItem firstItem = subList.get(0);
- JMenuItem lastItem = subList.get(subList.size() - 1);
- JMenu subMenu = new JMenu(firstItem.getText() + " ... "
- + lastItem.getText());
- if (headerItemFactory != null)
- subMenu.add(headerItemFactory.makeComponent());
- for (JMenuItem menuItem : subList)
- subMenu.add(menuItem);
- parentMenu.add(subMenu);
- index = toIndex;
- }
- }
-
- @Override
- public void addObserver(Observer<MenuManagerEvent> observer) {
- multiCaster.addObserver(observer);
- }
-
- @Override
- public JPopupMenu createContextMenu(Object parent, Object selection,
- Component relativeToComponent) {
- ContextualSelection contextualSelection = new ContextualSelection(
- parent, selection, relativeToComponent);
- JPopupMenu popupMenu = new JPopupMenu();
- populateContextMenu(popupMenu, DEFAULT_CONTEXT_MENU,
- contextualSelection);
- registerComponent(DEFAULT_CONTEXT_MENU, popupMenu, true);
- return popupMenu;
- }
-
- @Override
- public JMenuBar createMenuBar() {
- return createMenuBar(DEFAULT_MENU_BAR);
- }
-
- @Override
- public JMenuBar createMenuBar(URI id) {
- JMenuBar menuBar = new JMenuBar();
- if (needsUpdate)
- update();
- populateMenuBar(menuBar, id);
- registerComponent(id, menuBar, true);
- return menuBar;
- }
-
- @Override
- public JToolBar createToolBar() {
- return createToolBar(DEFAULT_TOOL_BAR);
- }
-
- @Override
- public JToolBar createToolBar(URI id) {
- JToolBar toolbar = new JToolBar();
- if (needsUpdate)
- update();
- populateToolBar(toolbar, id);
- registerComponent(id, toolbar, true);
- return toolbar;
- }
-
- @Override
- public synchronized Component getComponentByURI(URI id) {
- WeakReference<Component> componentRef = uriToComponent.get(id);
- if (componentRef == null)
- return null;
- // Might also be null it reference has gone dead
- return componentRef.get();
- }
-
- @Override
- public List<Observer<MenuManagerEvent>> getObservers() {
- return multiCaster.getObservers();
- }
-
- @Override
- public synchronized URI getURIByComponent(Component component) {
- return componentToUri.get(component);
- }
-
- @Override
- public void removeObserver(Observer<MenuManagerEvent> observer) {
- multiCaster.removeObserver(observer);
- }
-
- @Override
- public void update() {
- synchronized (updateLock) {
- if (updating && !needsUpdate)
- return;
- updating = true;
- }
- try {
- doUpdate();
- } finally {
- synchronized (updateLock) {
- updating = false;
- needsUpdate = false;
- }
- }
- }
-
- public void update(Object service, Map<?, ?> properties) {
- needsUpdate = true;
- update();
- }
-
- /**
- * Add a {@link JMenu} to the list of components as described by the menu
- * component. If there are no children, the menu is not added.
- *
- * @param components
- * List of components where to add the created {@link JMenu}
- * @param menuComponent
- * The {@link MenuComponent} definition for this menu
- * @param isToolbar
- * True if the list of components is to be added to a toolbar
- */
- private void addMenu(List<Component> components,
- MenuComponent menuComponent, MenuOptions menuOptions) {
- URI menuId = menuComponent.getId();
- if (menuOptions.isToolbar()) {
- logger.warn("Can't have menu " + menuComponent
- + " within toolBar element");
- return;
- }
- MenuOptions childOptions = new MenuOptions(menuOptions);
- List<Component> subComponents = makeComponents(menuId, childOptions);
- if (subComponents.isEmpty()) {
- logger.warn("No sub components found for menu " + menuId);
- return;
- }
-
- JMenu menu = new JMenu(menuComponent.getAction());
- for (Component menuItem : subComponents)
- if (menuItem == null)
- menu.addSeparator();
- else
- menu.add(menuItem);
- registerComponent(menuId, menu);
- components.add(menu);
- }
-
- /**
- * Add <code>null</code> to the list of components, meaning that a separator
- * is to be created. Subsequent separators are ignored, and if there are no
- * components on the list already no separator will be added.
- *
- * @param components
- * List of components
- */
- private void addNullSeparator(List<Component> components) {
- if (components.isEmpty())
- // Don't start with a separator
- return;
- if (components.get(components.size() - 1) == null)
- // Already a separator in last position
- return;
- components.add(null);
- }
-
- /**
- * Add an {@link AbstractMenuOptionGroup option group} to the list of
- * components
- *
- * @param components
- * List of components where to add the created {@link JMenu}
- * @param optionGroupId
- * The {@link URI} identifying the option group
- * @param isToolbar
- * True if the option group is to be added to a toolbar
- */
- private void addOptionGroup(List<Component> components, URI optionGroupId,
- MenuOptions menuOptions) {
- MenuOptions childOptions = new MenuOptions(menuOptions);
- childOptions.setOptionGroup(true);
-
- List<Component> buttons = makeComponents(optionGroupId, childOptions);
- addNullSeparator(components);
- if (buttons.isEmpty()) {
- logger.warn("No sub components found for option group "
- + optionGroupId);
- return;
- }
- ButtonGroup buttonGroup = new ButtonGroup();
-
- for (Component button : buttons) {
- if (button instanceof AbstractButton)
- buttonGroup.add((AbstractButton) button);
- else
- logger.warn("Component of button group " + optionGroupId
- + " is not an AbstractButton: " + button);
- if (button == null) {
- logger.warn("Separator found within button group");
- addNullSeparator(components);
- } else
- components.add(button);
- }
- addNullSeparator(components);
- }
-
- /**
- * Add a section to a list of components.
- *
- * @param components
- * List of components
- * @param sectionId
- * The {@link URI} identifying the section
- * @param menuOptions
- * {@link MenuOptions options} for creating the menu
- */
- private void addSection(List<Component> components, URI sectionId,
- MenuOptions menuOptions) {
- List<Component> childComponents = makeComponents(sectionId, menuOptions);
-
- MenuComponent sectionDef = uriToMenuElement.get(sectionId);
- addNullSeparator(components);
- if (childComponents.isEmpty()) {
- logger.warn("No sub components found for section " + sectionId);
- return;
- }
- Action sectionAction = sectionDef.getAction();
- if (sectionAction != null) {
- String sectionLabel = (String) sectionAction.getValue(NAME);
- if (sectionLabel != null) {
- // No separators before the label
- stripTrailingNullSeparator(components);
- Color labelColor = (Color) sectionAction.getValue(SECTION_COLOR);
- if (labelColor == null)
- labelColor = GREEN;
- ShadedLabel label = new ShadedLabel(sectionLabel, labelColor);
- components.add(label);
- }
- }
- for (Component childComponent : childComponents)
- if (childComponent == null) {
- logger.warn("Separator found within section " + sectionId);
- addNullSeparator(components);
- } else
- components.add(childComponent);
- addNullSeparator(components);
- }
-
- /**
- * Remove the last <code>null</code> separator from the list of components
- * if it's present.
- *
- * @param components
- * List of components
- */
- private void stripTrailingNullSeparator(List<Component> components) {
- if (!components.isEmpty()) {
- int lastIndex = components.size() - 1;
- if (components.get(lastIndex) == null)
- components.remove(lastIndex);
- }
- }
-
- /**
- * Perform the actual update, called by {@link #update()}. Reset all the
- * collections, refresh from SPI, modify any previously published components
- * and notify any observers.
- */
- protected synchronized void doUpdate() {
- resetCollections();
- findChildren();
- updatePublishedComponents();
- multiCaster.notify(new UpdatedMenuManagerEvent());
- }
-
- /**
- * Find all children for all known menu components. Populates
- * {@link #uriToMenuElement}.
- *
- */
- protected void findChildren() {
- for (MenuComponent menuElement : menuComponents) {
- uriToMenuElement.put(menuElement.getId(), menuElement);
- logger.debug("Found menu element " + menuElement.getId() + " "
- + menuElement);
- if (menuElement.getParentId() == null)
- continue;
- List<MenuComponent> siblings = menuElementTree.get(menuElement
- .getParentId());
- if (siblings == null) {
- siblings = new ArrayList<>();
- synchronized (menuElementTree) {
- menuElementTree.put(menuElement.getParentId(), siblings);
- }
- }
- siblings.add(menuElement);
- }
-// if (uriToMenuElement.isEmpty()) {
-// logger.error("No menu elements found, check classpath/Raven/SPI");
-// }
- }
-
- /**
- * Get the children which have the given URI specified as their parent, or
- * an empty list if no children exist.
- *
- * @param id
- * The {@link URI} of the parent
- * @return The {@link List} of {@link MenuComponent} which have the given
- * parent
- */
- protected List<MenuComponent> getChildren(URI id) {
- List<MenuComponent> children = null;
- synchronized (menuElementTree) {
- children = menuElementTree.get(id);
- if (children != null)
- children = new ArrayList<>(children);
- }
- if (children == null)
- children = Collections.<MenuComponent> emptyList();
- else
- Collections.sort(children, menuElementComparator);
- return children;
- }
-
- /**
- * Make the list of Swing {@link Component}s that are the children of the
- * given {@link URI}.
- *
- * @param id
- * The {@link URI} of the parent which children are to be made
- * @param menuOptions
- * Options of the created menu, for instance
- * {@link MenuOptions#isToolbar()}.
- * @return A {@link List} of {@link Component}s that can be added to a
- * {@link JMenuBar}, {@link JMenu} or {@link JToolBar}.
- */
- protected List<Component> makeComponents(URI id, MenuOptions menuOptions) {
- List<Component> components = new ArrayList<>();
- for (MenuComponent childElement : getChildren(id)) {
- if (childElement instanceof ContextualMenuComponent)
- ((ContextualMenuComponent) childElement)
- .setContextualSelection(menuOptions
- .getContextualSelection());
- /*
- * Important - check this AFTER setContextualSelection so the item
- * can change it's enabled-state if needed.
- */
- if (!childElement.isEnabled())
- continue;
- MenuType type = childElement.getType();
- Action action = childElement.getAction();
- URI childId = childElement.getId();
- if (type.equals(MenuType.action)) {
- if (action == null) {
- logger.warn("Skipping invalid action " + childId + " for "
- + id);
- continue;
- }
-
- Component actionComponent;
- if (menuOptions.isOptionGroup()) {
- if (menuOptions.isToolbar()) {
- actionComponent = new JToggleButton(action);
- toolbarizeButton((AbstractButton) actionComponent);
- } else
- actionComponent = new JRadioButtonMenuItem(action);
- } else {
- if (menuOptions.isToolbar()) {
- actionComponent = new JButton(action);
- toolbarizeButton((AbstractButton) actionComponent);
- } else
- actionComponent = new JMenuItem(action);
- }
- registerComponent(childId, actionComponent);
- components.add(actionComponent);
- } else if (type.equals(MenuType.toggle)) {
- if (action == null) {
- logger.warn("Skipping invalid toggle " + childId + " for "
- + id);
- continue;
- }
- Component toggleComponent;
- if (menuOptions.isToolbar())
- toggleComponent = new JToggleButton(action);
- else
- toggleComponent = new JCheckBoxMenuItem(action);
- registerComponent(childId, toggleComponent);
- components.add(toggleComponent);
- } else if (type.equals(MenuType.custom)) {
- Component customComponent = childElement.getCustomComponent();
- if (customComponent == null) {
- logger.warn("Skipping null custom component " + childId
- + " for " + id);
- continue;
- }
- registerComponent(childId, customComponent);
- components.add(customComponent);
- } else if (type.equals(MenuType.optionGroup))
- addOptionGroup(components, childId, menuOptions);
- else if (type.equals(MenuType.section))
- addSection(components, childId, menuOptions);
- else if (type.equals(MenuType.menu))
- addMenu(components, childElement, menuOptions);
- else {
- logger.warn("Skipping invalid/unknown type " + type + " for "
- + id);
- continue;
- }
- }
- stripTrailingNullSeparator(components);
- return components;
- }
-
- /**
- * Fill the specified menu bar with the menu elements that have the given
- * URI as their parent.
- * <p>
- * Existing elements on the menu bar will be removed.
- *
- * @param menuBar
- * The {@link JMenuBar} to update
- * @param id
- * The {@link URI} of the menu bar
- */
- protected void populateMenuBar(JMenuBar menuBar, URI id) {
- menuBar.removeAll();
- MenuComponent menuDef = uriToMenuElement.get(id);
- if (menuDef == null)
- throw new IllegalArgumentException("Unknown menuBar " + id);
- if (!menuDef.getType().equals(MenuType.menu))
- throw new IllegalArgumentException("Element " + id
- + " is not a menu, but a " + menuDef.getType());
- MenuOptions menuOptions = new MenuOptions();
- for (Component component : makeComponents(id, menuOptions))
- if (component == null)
- logger.warn("Ignoring separator in menu bar " + id);
- else
- menuBar.add(component);
- }
-
- /**
- * Fill the specified menu bar with the menu elements that have the given
- * URI as their parent.
- * <p>
- * Existing elements on the menu bar will be removed.
- *
- * @param popupMenu
- * The {@link JPopupMenu} to update
- * @param id
- * The {@link URI} of the menu bar
- * @param contextualSelection
- * The current selection for the context menu
- */
- protected void populateContextMenu(JPopupMenu popupMenu, URI id,
- ContextualSelection contextualSelection) {
- popupMenu.removeAll();
- MenuComponent menuDef = uriToMenuElement.get(id);
- if (menuDef == null)
- throw new IllegalArgumentException("Unknown menuBar " + id);
- if (!menuDef.getType().equals(MenuType.menu))
- throw new IllegalArgumentException("Element " + id
- + " is not a menu, but a " + menuDef.getType());
- MenuOptions menuOptions = new MenuOptions();
- menuOptions.setContextualSelection(contextualSelection);
- for (Component component : makeComponents(id, menuOptions))
- if (component == null)
- popupMenu.addSeparator();
- else
- popupMenu.add(component);
- }
-
- /**
- * Fill the specified tool bar with the elements that have the given URI as
- * their parent.
- * <p>
- * Existing elements on the tool bar will be removed.
- *
- * @param toolbar
- * The {@link JToolBar} to update
- * @param id
- * The {@link URI} of the tool bar
- */
- protected void populateToolBar(JToolBar toolbar, URI id) {
- toolbar.removeAll();
- MenuComponent toolbarDef = uriToMenuElement.get(id);
- if (toolbarDef == null)
- throw new IllegalArgumentException("Unknown toolBar " + id);
- if (!toolbarDef.getType().equals(MenuType.toolBar))
- throw new IllegalArgumentException("Element " + id
- + " is not a toolBar, but a " + toolbarDef.getType());
- if (toolbarDef.getAction() != null) {
- String name = (String) toolbarDef.getAction().getValue(Action.NAME);
- toolbar.setName(name);
- } else
- toolbar.setName("");
- MenuOptions menuOptions = new MenuOptions();
- menuOptions.setToolbar(true);
- for (Component component : makeComponents(id, menuOptions)) {
- if (component == null) {
- toolbar.addSeparator();
- continue;
- }
- if (component instanceof JButton) {
- JButton toolbarButton = (JButton) component;
- toolbarButton.putClientProperty("hideActionText", true);
- }
- toolbar.add(component);
- }
- }
-
- /**
- * Register a component that has been created. Such a component can be
- * resolved through {@link #getComponentByURI(URI)}.
- *
- * @param id
- * The {@link URI} that defined the component
- * @param component
- * The {@link Component} that was created.
- */
- protected synchronized void registerComponent(URI id, Component component) {
- registerComponent(id, component, false);
- }
-
- /**
- * Register a component that has been created. Such a component can be
- * resolved through {@link #getComponentByURI(URI)}.
- *
- * @param id
- * The {@link URI} that defined the component
- * @param component
- * The {@link Component} that was created.
- * @param published
- * <code>true</code> if the component has been published through
- * {@link #createMenuBar()} or similar, and is to be
- * automatically updated by later calls to {@link #update()}.
- */
- protected synchronized void registerComponent(URI id, Component component,
- boolean published) {
- uriToComponent.put(id, new WeakReference<>(component));
- componentToUri.put(component, id);
- if (published) {
- List<WeakReference<Component>> publishedComponents = uriToPublishedComponents
- .get(id);
- if (publishedComponents == null) {
- publishedComponents = new ArrayList<>();
- uriToPublishedComponents.put(id, publishedComponents);
- }
- publishedComponents.add(new WeakReference<>(component));
- }
- setHelpStringForComponent(component, id);
- }
-
- /**
- * Reset all collections
- *
- */
- protected synchronized void resetCollections() {
- menuElementTree = new HashMap<>();
- componentToUri = new WeakHashMap<>();
- uriToMenuElement = new HashMap<>();
- uriToComponent = new HashMap<>();
- }
-
- /**
- * Set javax.help string to identify the component for later references to
- * the help document. Note that the component (ie. the
- * {@link AbstractMenuAction} must have an ID for an registration to take
- * place.
- *
- * @param component
- * The {@link Component} to set help string for
- * @param componentId
- * The {@link URI} to be used as identifier
- */
- protected void setHelpStringForComponent(Component component,
- URI componentId) {
- if (componentId != null) {
- String helpId = componentId.toASCIIString();
- setHelpIDString(component, helpId);
- }
- }
-
- /**
- * Make an {@link AbstractButton} be configured in a "toolbar-like" way, for
- * instance showing only the icon.
- *
- * @param actionButton
- * Button to toolbarise
- */
- protected void toolbarizeButton(AbstractButton actionButton) {
- Action action = actionButton.getAction();
- if (action.getValue(SHORT_DESCRIPTION) == null)
- action.putValue(SHORT_DESCRIPTION, action.getValue(NAME));
- actionButton.setBorder(new EmptyBorder(0, 2, 0, 2));
- // actionButton.setHorizontalTextPosition(JButton.CENTER);
- // actionButton.setVerticalTextPosition(JButton.BOTTOM);
- if (action.getValue(Action.SMALL_ICON) != null) {
- // Don't show the text
- actionButton.putClientProperty("hideActionText", true);
- // Since hideActionText seems to be broken in Java 5 and/or OS X
- actionButton.setText(null);
- }
- }
-
- /**
- * Update all components that have been published using
- * {@link #createMenuBar()} and similar. Content of such components will be
- * removed and replaced by fresh components.
- */
- protected void updatePublishedComponents() {
- for (Entry<URI, List<WeakReference<Component>>> entry : uriToPublishedComponents
- .entrySet())
- for (WeakReference<Component> reference : entry.getValue()) {
- URI id = entry.getKey();
- Component component = reference.get();
- if (component == null)
- continue;
- if (component instanceof JToolBar)
- populateToolBar((JToolBar) component, id);
- else if (component instanceof JMenuBar)
- populateMenuBar((JMenuBar) component, id);
- else
- logger.warn("Could not update published component " + id
- + ": " + component.getClass());
- }
- }
-
- public void setMenuComponents(List<MenuComponent> menuComponents) {
- this.menuComponents = menuComponents;
- }
-
- public void setSelectionManager(SelectionManager selectionManager) {
- selectionManager.addObserver(new SelectionManagerObserver());
- }
-
- /**
- * {@link Comparator} that can order {@link MenuComponent}s by their
- * {@link MenuComponent#getPositionHint()}.
- */
- protected static class MenuElementComparator implements
- Comparator<MenuComponent> {
- @Override
- public int compare(MenuComponent a, MenuComponent b) {
- return a.getPositionHint() - b.getPositionHint();
- }
- }
-
- /**
- * Various options for
- * {@link MenuManagerImpl#makeComponents(URI, MenuOptions)} and friends.
- *
- * @author Stian Soiland-Reyes
- */
- public static class MenuOptions {
- private boolean isToolbar = false;
- private boolean isOptionGroup = false;
- private ContextualSelection contextualSelection = null;
-
- public ContextualSelection getContextualSelection() {
- return contextualSelection;
- }
-
- public void setContextualSelection(
- ContextualSelection contextualSelection) {
- this.contextualSelection = contextualSelection;
- }
-
- public MenuOptions(MenuOptions original) {
- this.isOptionGroup = original.isOptionGroup();
- this.isToolbar = original.isToolbar();
- this.contextualSelection = original.getContextualSelection();
- }
-
- public MenuOptions() {
- }
-
- @Override
- protected MenuOptions clone() {
- return new MenuOptions(this);
- }
-
- public boolean isToolbar() {
- return isToolbar;
- }
-
- public void setToolbar(boolean isToolbar) {
- this.isToolbar = isToolbar;
- }
-
- public boolean isOptionGroup() {
- return isOptionGroup;
- }
-
- public void setOptionGroup(boolean isOptionGroup) {
- this.isOptionGroup = isOptionGroup;
- }
- }
-
- private final class SelectionManagerObserver extends
- SwingAwareObserver<SelectionManagerEvent> {
- private static final String DESIGN_PERSPECTIVE_ID = "net.sf.taverna.t2.ui.perspectives.design.DesignPerspective";
- private static final String RESULTS_PERSPECTIVE_ID = "net.sf.taverna.t2.ui.perspectives.results.ResultsPerspective";
-
- @Override
- public void notifySwing(Observable<SelectionManagerEvent> sender,
- SelectionManagerEvent message) {
- if (!(message instanceof PerspectiveSelectionEvent))
- return;
- handlePerspectiveSelect((PerspectiveSelectionEvent) message);
- }
-
- private void handlePerspectiveSelect(PerspectiveSelectionEvent event) {
- String perspectiveID = event.getSelectedPerspective().getID();
- boolean isDesign = DESIGN_PERSPECTIVE_ID.equals(perspectiveID);
- boolean isResults = RESULTS_PERSPECTIVE_ID.equals(perspectiveID);
-
- for (MenuComponent menuComponent : menuComponents)
- if (!(menuComponent instanceof ContextualMenuComponent)) {
- Action action = menuComponent.getAction();
- if (action instanceof DesignOnlyAction)
- action.setEnabled(isDesign);
- else if (action instanceof DesignOrResultsAction)
- action.setEnabled(isDesign || isResults);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java
deleted file mode 100644
index 9a2f37b..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import static java.awt.event.KeyEvent.VK_A;
-import static javax.swing.Action.MNEMONIC_KEY;
-import static net.sf.taverna.t2.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
-
-import java.net.URI;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenu;
-
-public class AdvancedMenu extends AbstractMenu {
- public static final URI ADVANCED_URI = URI
- .create("http://taverna.sf.net/2008/t2workbench/menu#advanced");
-
- public AdvancedMenu() {
- super(DEFAULT_MENU_BAR, 1000, ADVANCED_URI, makeAction());
- }
-
- public static DummyAction makeAction() {
- DummyAction action = new DummyAction("Advanced");
- action.putValue(MNEMONIC_KEY, Integer.valueOf(VK_A));
- return action;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java
deleted file mode 100644
index a15237c..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import static java.awt.event.KeyEvent.VK_E;
-import static javax.swing.Action.MNEMONIC_KEY;
-import static net.sf.taverna.t2.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
-
-import java.net.URI;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenu;
-
-public class EditMenu extends AbstractMenu {
- public EditMenu() {
- super(DEFAULT_MENU_BAR, 20, URI
- .create("http://taverna.sf.net/2008/t2workbench/menu#edit"),
- makeAction());
- }
-
- public static DummyAction makeAction() {
- DummyAction action = new DummyAction("Edit");
- action.putValue(MNEMONIC_KEY, Integer.valueOf(VK_E));
- return action;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java
deleted file mode 100644
index 6b6eb7c..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import static java.awt.Desktop.getDesktop;
-import static net.sf.taverna.t2.workbench.ui.impl.menu.HelpMenu.HELP_URI;
-
-import java.awt.event.ActionEvent;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
-
-import org.apache.log4j.Logger;
-
-/**
- * MenuItem for feedback
- *
- * @author alanrw
- */
-public class FeedbackMenuAction extends AbstractMenuAction {
- private static Logger logger = Logger.getLogger(FeedbackMenuAction.class);
-
- private static String FEEDBACK_URL = "http://www.taverna.org.uk/about/contact-us/feedback/";
-
- public FeedbackMenuAction() {
- super(HELP_URI, 20);
- }
-
- @Override
- protected Action createAction() {
- return new FeedbackAction();
- }
-
- @SuppressWarnings("serial")
- private final class FeedbackAction extends AbstractAction {
- private FeedbackAction() {
- super("Contact us");
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- try {
- getDesktop().browse(new URI(FEEDBACK_URL));
- } catch (IOException e1) {
- logger.error("Unable to open URL", e1);
- } catch (URISyntaxException e1) {
- logger.error("Invalid URL syntax", e1);
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java
deleted file mode 100644
index 61f963b..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import static java.awt.event.KeyEvent.VK_F;
-import static javax.swing.Action.MNEMONIC_KEY;
-import static net.sf.taverna.t2.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
-
-import java.net.URI;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenu;
-
-/**
- * File menu
- *
- * @author Stian Soiland-Reyes
- */
-public class FileMenu extends AbstractMenu {
- public FileMenu() {
- super(DEFAULT_MENU_BAR, 10, URI
- .create("http://taverna.sf.net/2008/t2workbench/menu#file"),
- makeAction());
- }
-
- public static DummyAction makeAction() {
- DummyAction action = new DummyAction("File");
- action.putValue(MNEMONIC_KEY, Integer.valueOf(VK_F));
- return action;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java
deleted file mode 100644
index c4169cc..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import static java.awt.event.KeyEvent.VK_H;
-import static javax.swing.Action.MNEMONIC_KEY;
-import static net.sf.taverna.t2.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
-
-import java.net.URI;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenu;
-
-public class HelpMenu extends AbstractMenu {
- public static final URI HELP_URI = URI
- .create("http://taverna.sf.net/2008/t2workbench/menu#help");
-
- public HelpMenu() {
- super(DEFAULT_MENU_BAR, 1024, HELP_URI, makeAction());
- }
-
- public static DummyAction makeAction() {
- DummyAction action = new DummyAction("Help");
- action.putValue(MNEMONIC_KEY, Integer.valueOf(VK_H));
- return action;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java
deleted file mode 100644
index d091c8e..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import static java.awt.event.KeyEvent.VK_F1;
-import static javax.swing.KeyStroke.getKeyStroke;
-import static net.sf.taverna.t2.workbench.helper.Helper.displayDefaultHelp;
-import static net.sf.taverna.t2.workbench.ui.impl.menu.HelpMenu.HELP_URI;
-
-import java.awt.AWTEvent;
-import java.awt.event.ActionEvent;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
-
-/**
- * MenuItem for help
- *
- * @author alanrw
- */
-public class OnlineHelpMenuAction extends AbstractMenuAction {
- public OnlineHelpMenuAction() {
- super(HELP_URI, 10);
- }
-
- @Override
- protected Action createAction() {
- return new OnlineHelpAction();
- }
-
- @SuppressWarnings("serial")
- private final class OnlineHelpAction extends AbstractAction {
- private OnlineHelpAction() {
- super("Online help");
- putValue(ACCELERATOR_KEY, getKeyStroke(VK_F1, 0));
-
- }
-
- /**
- * When selected, use the Helper to display the default help.
- */
- @Override
- public void actionPerformed(ActionEvent e) {
- displayDefaultHelp((AWTEvent) e);
- // TODO change helper to bean?
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java
deleted file mode 100644
index 308d51d..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import static java.lang.Runtime.getRuntime;
-import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
-import static javax.swing.JOptionPane.showInputDialog;
-import static net.sf.taverna.t2.workbench.MainWindow.getMainWindow;
-import static net.sf.taverna.t2.workbench.ui.impl.menu.AdvancedMenu.ADVANCED_URI;
-
-import java.awt.event.ActionEvent;
-import java.io.File;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenuAction;
-
-import org.apache.log4j.Logger;
-
-import uk.org.taverna.configuration.app.ApplicationConfiguration;
-
-public class ShowLogsAndDataMenuAction extends AbstractMenuAction {
- private static final String OPEN = "open";
- private static final String EXPLORER = "explorer";
- // TODO Consider using xdg-open instead of gnome-open
- private static final String GNOME_OPEN = "gnome-open";
- private static final String WINDOWS = "Windows";
- private static final String MAC_OS_X = "Mac OS X";
-
- private ApplicationConfiguration applicationConfiguration;
-
- public ShowLogsAndDataMenuAction() {
- super(ADVANCED_URI, 200);
- }
-
- private static Logger logger = Logger.getLogger(ShowLogsAndDataMenuAction.class);
-
- @Override
- protected Action createAction() {
- return new AbstractAction("Show logs and data folder") {
- private static final long serialVersionUID = 1L;
-
- @Override
- public void actionPerformed(ActionEvent e) {
- File logsAndDataDir = applicationConfiguration.getApplicationHomeDir();
- showDirectory(logsAndDataDir, "Taverna logs and data folder");
- }
- };
- }
-
- public static void showDirectory(File dir, String title) {
- String path = dir.getAbsolutePath();
- String os = System.getProperty("os.name");
- String cmd;
- boolean isWindows = false;
- if (os.equals(MAC_OS_X))
- cmd = OPEN;
- else if (os.startsWith(WINDOWS)) {
- cmd = EXPLORER;
- isWindows = true;
- } else
- // Assume Unix - best option is gnome-open
- cmd = GNOME_OPEN;
-
- String[] cmdArray = new String[2];
- cmdArray[0] = cmd;
- cmdArray[1] = path;
- try {
- Process exec = getRuntime().exec(cmdArray);
- Thread.sleep(300);
- exec.getErrorStream().close();
- exec.getInputStream().close();
- exec.getOutputStream().close();
- exec.waitFor();
- if (exec.exitValue() == 0 || isWindows && exec.exitValue() == 1)
- // explorer.exe thinks 1 means success
- return;
- logger.warn("Exit value from " + cmd + " " + path + ": " + exec.exitValue());
- } catch (Exception ex) {
- logger.warn("Could not call " + cmd + " " + path, ex);
- }
- // Fall-back - just show a dialogue with the path
- showInputDialog(getMainWindow(), "Copy path from below:", title,
- INFORMATION_MESSAGE, null, null, path);
- }
-
- public void setApplicationConfiguration(ApplicationConfiguration applicationConfiguration) {
- this.applicationConfiguration = applicationConfiguration;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java b/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java
deleted file mode 100644
index 2df05e5..0000000
--- a/taverna-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package net.sf.taverna.t2.workbench.ui.impl.menu;
-
-import java.net.URI;
-
-import net.sf.taverna.t2.ui.menu.AbstractMenuSection;
-
-/**
- * @author Alex Nenadic
- * @author Alan R Williams
- */
-public class ViewShowMenuSection extends AbstractMenuSection {
- public static final URI DIAGRAM_MENU = URI
- .create("http://taverna.sf.net/2008/t2workbench/menu#diagram");
- public static final URI VIEW_SHOW_MENU_SECTION = URI
- .create("http://taverna.sf.net/2008/t2workbench/menu#viewShowMenuSection");
-
- public ViewShowMenuSection() {
- super(DIAGRAM_MENU, 10, VIEW_SHOW_MENU_SECTION);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/org/apache/taverna/ui/menu/impl/MenuManagerImpl.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/org/apache/taverna/ui/menu/impl/MenuManagerImpl.java b/taverna-menu-impl/src/main/java/org/apache/taverna/ui/menu/impl/MenuManagerImpl.java
new file mode 100644
index 0000000..826114e
--- /dev/null
+++ b/taverna-menu-impl/src/main/java/org/apache/taverna/ui/menu/impl/MenuManagerImpl.java
@@ -0,0 +1,879 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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 org.apache.taverna.ui.menu.impl;
+
+import static java.lang.Math.min;
+import static javax.help.CSH.setHelpIDString;
+import static javax.swing.Action.NAME;
+import static javax.swing.Action.SHORT_DESCRIPTION;
+import static org.apache.taverna.lang.ui.ShadedLabel.GREEN;
+import static org.apache.taverna.ui.menu.AbstractMenuSection.SECTION_COLOR;
+import static org.apache.taverna.ui.menu.DefaultContextualMenu.DEFAULT_CONTEXT_MENU;
+import static org.apache.taverna.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
+import static org.apache.taverna.ui.menu.DefaultToolBar.DEFAULT_TOOL_BAR;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.lang.ref.WeakReference;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.WeakHashMap;
+
+import javax.swing.AbstractButton;
+import javax.swing.Action;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.taverna.lang.observer.MultiCaster;
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.lang.observer.SwingAwareObserver;
+import org.apache.taverna.lang.ui.ShadedLabel;
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.ui.menu.AbstractMenuOptionGroup;
+import org.apache.taverna.ui.menu.ContextualMenuComponent;
+import org.apache.taverna.ui.menu.ContextualSelection;
+import org.apache.taverna.ui.menu.DesignOnlyAction;
+import org.apache.taverna.ui.menu.DesignOrResultsAction;
+import org.apache.taverna.ui.menu.MenuComponent;
+import org.apache.taverna.ui.menu.MenuComponent.MenuType;
+import org.apache.taverna.ui.menu.MenuManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.selection.events.PerspectiveSelectionEvent;
+import org.apache.taverna.workbench.selection.events.SelectionManagerEvent;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Implementation of {@link MenuManager}.
+ *
+ * @author Stian Soiland-Reyes
+ */
+public class MenuManagerImpl implements MenuManager {
+ private static Logger logger = Logger.getLogger(MenuManagerImpl.class);
+
+ private boolean needsUpdate;
+ /**
+ * Cache used by {@link #getURIByComponent(Component)}
+ */
+ private WeakHashMap<Component, URI> componentToUri;
+ /**
+ * {@link MenuElementComparator} used for sorting menu components from the
+ * SPI registry.
+ */
+ private MenuElementComparator menuElementComparator = new MenuElementComparator();
+ /**
+ * Map of {@link URI} to it's discovered children. Populated by
+ * {@link #findChildren()}.
+ */
+ private HashMap<URI, List<MenuComponent>> menuElementTree;
+ /**
+ * Multicaster to distribute messages to {@link Observer}s of this menu
+ * manager.
+ */
+ private MultiCaster<MenuManagerEvent> multiCaster;
+ /**
+ * Lock for {@link #update()}
+ */
+ private final Object updateLock = new Object();
+ /**
+ * True if {@link #doUpdate()} is running, subsequents call to
+ * {@link #update()} will return immediately.
+ */
+ private boolean updating;
+ /**
+ * Cache used by {@link #getComponentByURI(URI)}
+ */
+ private Map<URI, WeakReference<Component>> uriToComponent;
+ /**
+ * Map from {@link URI} to defining {@link MenuComponent}. Children are in
+ * {@link #menuElementTree}.
+ */
+ private Map<URI, MenuComponent> uriToMenuElement;
+ // Note: Not reset by #resetCollections()
+ private Map<URI, List<WeakReference<Component>>> uriToPublishedComponents = new HashMap<>();
+ private List<MenuComponent> menuComponents = new ArrayList<>();
+
+ /**
+ * Construct the MenuManagerImpl. Observes the SPI registry and does an
+ * initial {@link #update()}.
+ */
+ public MenuManagerImpl() {
+ multiCaster = new MultiCaster<>(this);
+ needsUpdate = true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addMenuItemsWithExpansion(List<JMenuItem> menuItems,
+ JMenu parentMenu, int maxItemsInMenu,
+ ComponentFactory headerItemFactory) {
+ if (menuItems.size() <= maxItemsInMenu) {
+ // Just add them directly
+ for (JMenuItem menuItem : menuItems)
+ parentMenu.add(menuItem);
+ return;
+ }
+ int index = 0;
+ while (index < menuItems.size()) {
+ int toIndex = min(menuItems.size(), index + maxItemsInMenu);
+ if (toIndex == menuItems.size() - 1)
+ // Don't leave a single item left for the last subMenu
+ toIndex--;
+ List<JMenuItem> subList = menuItems.subList(index, toIndex);
+ JMenuItem firstItem = subList.get(0);
+ JMenuItem lastItem = subList.get(subList.size() - 1);
+ JMenu subMenu = new JMenu(firstItem.getText() + " ... "
+ + lastItem.getText());
+ if (headerItemFactory != null)
+ subMenu.add(headerItemFactory.makeComponent());
+ for (JMenuItem menuItem : subList)
+ subMenu.add(menuItem);
+ parentMenu.add(subMenu);
+ index = toIndex;
+ }
+ }
+
+ @Override
+ public void addObserver(Observer<MenuManagerEvent> observer) {
+ multiCaster.addObserver(observer);
+ }
+
+ @Override
+ public JPopupMenu createContextMenu(Object parent, Object selection,
+ Component relativeToComponent) {
+ ContextualSelection contextualSelection = new ContextualSelection(
+ parent, selection, relativeToComponent);
+ JPopupMenu popupMenu = new JPopupMenu();
+ populateContextMenu(popupMenu, DEFAULT_CONTEXT_MENU,
+ contextualSelection);
+ registerComponent(DEFAULT_CONTEXT_MENU, popupMenu, true);
+ return popupMenu;
+ }
+
+ @Override
+ public JMenuBar createMenuBar() {
+ return createMenuBar(DEFAULT_MENU_BAR);
+ }
+
+ @Override
+ public JMenuBar createMenuBar(URI id) {
+ JMenuBar menuBar = new JMenuBar();
+ if (needsUpdate)
+ update();
+ populateMenuBar(menuBar, id);
+ registerComponent(id, menuBar, true);
+ return menuBar;
+ }
+
+ @Override
+ public JToolBar createToolBar() {
+ return createToolBar(DEFAULT_TOOL_BAR);
+ }
+
+ @Override
+ public JToolBar createToolBar(URI id) {
+ JToolBar toolbar = new JToolBar();
+ if (needsUpdate)
+ update();
+ populateToolBar(toolbar, id);
+ registerComponent(id, toolbar, true);
+ return toolbar;
+ }
+
+ @Override
+ public synchronized Component getComponentByURI(URI id) {
+ WeakReference<Component> componentRef = uriToComponent.get(id);
+ if (componentRef == null)
+ return null;
+ // Might also be null it reference has gone dead
+ return componentRef.get();
+ }
+
+ @Override
+ public List<Observer<MenuManagerEvent>> getObservers() {
+ return multiCaster.getObservers();
+ }
+
+ @Override
+ public synchronized URI getURIByComponent(Component component) {
+ return componentToUri.get(component);
+ }
+
+ @Override
+ public void removeObserver(Observer<MenuManagerEvent> observer) {
+ multiCaster.removeObserver(observer);
+ }
+
+ @Override
+ public void update() {
+ synchronized (updateLock) {
+ if (updating && !needsUpdate)
+ return;
+ updating = true;
+ }
+ try {
+ doUpdate();
+ } finally {
+ synchronized (updateLock) {
+ updating = false;
+ needsUpdate = false;
+ }
+ }
+ }
+
+ public void update(Object service, Map<?, ?> properties) {
+ needsUpdate = true;
+ update();
+ }
+
+ /**
+ * Add a {@link JMenu} to the list of components as described by the menu
+ * component. If there are no children, the menu is not added.
+ *
+ * @param components
+ * List of components where to add the created {@link JMenu}
+ * @param menuComponent
+ * The {@link MenuComponent} definition for this menu
+ * @param isToolbar
+ * True if the list of components is to be added to a toolbar
+ */
+ private void addMenu(List<Component> components,
+ MenuComponent menuComponent, MenuOptions menuOptions) {
+ URI menuId = menuComponent.getId();
+ if (menuOptions.isToolbar()) {
+ logger.warn("Can't have menu " + menuComponent
+ + " within toolBar element");
+ return;
+ }
+ MenuOptions childOptions = new MenuOptions(menuOptions);
+ List<Component> subComponents = makeComponents(menuId, childOptions);
+ if (subComponents.isEmpty()) {
+ logger.warn("No sub components found for menu " + menuId);
+ return;
+ }
+
+ JMenu menu = new JMenu(menuComponent.getAction());
+ for (Component menuItem : subComponents)
+ if (menuItem == null)
+ menu.addSeparator();
+ else
+ menu.add(menuItem);
+ registerComponent(menuId, menu);
+ components.add(menu);
+ }
+
+ /**
+ * Add <code>null</code> to the list of components, meaning that a separator
+ * is to be created. Subsequent separators are ignored, and if there are no
+ * components on the list already no separator will be added.
+ *
+ * @param components
+ * List of components
+ */
+ private void addNullSeparator(List<Component> components) {
+ if (components.isEmpty())
+ // Don't start with a separator
+ return;
+ if (components.get(components.size() - 1) == null)
+ // Already a separator in last position
+ return;
+ components.add(null);
+ }
+
+ /**
+ * Add an {@link AbstractMenuOptionGroup option group} to the list of
+ * components
+ *
+ * @param components
+ * List of components where to add the created {@link JMenu}
+ * @param optionGroupId
+ * The {@link URI} identifying the option group
+ * @param isToolbar
+ * True if the option group is to be added to a toolbar
+ */
+ private void addOptionGroup(List<Component> components, URI optionGroupId,
+ MenuOptions menuOptions) {
+ MenuOptions childOptions = new MenuOptions(menuOptions);
+ childOptions.setOptionGroup(true);
+
+ List<Component> buttons = makeComponents(optionGroupId, childOptions);
+ addNullSeparator(components);
+ if (buttons.isEmpty()) {
+ logger.warn("No sub components found for option group "
+ + optionGroupId);
+ return;
+ }
+ ButtonGroup buttonGroup = new ButtonGroup();
+
+ for (Component button : buttons) {
+ if (button instanceof AbstractButton)
+ buttonGroup.add((AbstractButton) button);
+ else
+ logger.warn("Component of button group " + optionGroupId
+ + " is not an AbstractButton: " + button);
+ if (button == null) {
+ logger.warn("Separator found within button group");
+ addNullSeparator(components);
+ } else
+ components.add(button);
+ }
+ addNullSeparator(components);
+ }
+
+ /**
+ * Add a section to a list of components.
+ *
+ * @param components
+ * List of components
+ * @param sectionId
+ * The {@link URI} identifying the section
+ * @param menuOptions
+ * {@link MenuOptions options} for creating the menu
+ */
+ private void addSection(List<Component> components, URI sectionId,
+ MenuOptions menuOptions) {
+ List<Component> childComponents = makeComponents(sectionId, menuOptions);
+
+ MenuComponent sectionDef = uriToMenuElement.get(sectionId);
+ addNullSeparator(components);
+ if (childComponents.isEmpty()) {
+ logger.warn("No sub components found for section " + sectionId);
+ return;
+ }
+ Action sectionAction = sectionDef.getAction();
+ if (sectionAction != null) {
+ String sectionLabel = (String) sectionAction.getValue(NAME);
+ if (sectionLabel != null) {
+ // No separators before the label
+ stripTrailingNullSeparator(components);
+ Color labelColor = (Color) sectionAction.getValue(SECTION_COLOR);
+ if (labelColor == null)
+ labelColor = GREEN;
+ ShadedLabel label = new ShadedLabel(sectionLabel, labelColor);
+ components.add(label);
+ }
+ }
+ for (Component childComponent : childComponents)
+ if (childComponent == null) {
+ logger.warn("Separator found within section " + sectionId);
+ addNullSeparator(components);
+ } else
+ components.add(childComponent);
+ addNullSeparator(components);
+ }
+
+ /**
+ * Remove the last <code>null</code> separator from the list of components
+ * if it's present.
+ *
+ * @param components
+ * List of components
+ */
+ private void stripTrailingNullSeparator(List<Component> components) {
+ if (!components.isEmpty()) {
+ int lastIndex = components.size() - 1;
+ if (components.get(lastIndex) == null)
+ components.remove(lastIndex);
+ }
+ }
+
+ /**
+ * Perform the actual update, called by {@link #update()}. Reset all the
+ * collections, refresh from SPI, modify any previously published components
+ * and notify any observers.
+ */
+ protected synchronized void doUpdate() {
+ resetCollections();
+ findChildren();
+ updatePublishedComponents();
+ multiCaster.notify(new UpdatedMenuManagerEvent());
+ }
+
+ /**
+ * Find all children for all known menu components. Populates
+ * {@link #uriToMenuElement}.
+ *
+ */
+ protected void findChildren() {
+ for (MenuComponent menuElement : menuComponents) {
+ uriToMenuElement.put(menuElement.getId(), menuElement);
+ logger.debug("Found menu element " + menuElement.getId() + " "
+ + menuElement);
+ if (menuElement.getParentId() == null)
+ continue;
+ List<MenuComponent> siblings = menuElementTree.get(menuElement
+ .getParentId());
+ if (siblings == null) {
+ siblings = new ArrayList<>();
+ synchronized (menuElementTree) {
+ menuElementTree.put(menuElement.getParentId(), siblings);
+ }
+ }
+ siblings.add(menuElement);
+ }
+// if (uriToMenuElement.isEmpty()) {
+// logger.error("No menu elements found, check classpath/Raven/SPI");
+// }
+ }
+
+ /**
+ * Get the children which have the given URI specified as their parent, or
+ * an empty list if no children exist.
+ *
+ * @param id
+ * The {@link URI} of the parent
+ * @return The {@link List} of {@link MenuComponent} which have the given
+ * parent
+ */
+ protected List<MenuComponent> getChildren(URI id) {
+ List<MenuComponent> children = null;
+ synchronized (menuElementTree) {
+ children = menuElementTree.get(id);
+ if (children != null)
+ children = new ArrayList<>(children);
+ }
+ if (children == null)
+ children = Collections.<MenuComponent> emptyList();
+ else
+ Collections.sort(children, menuElementComparator);
+ return children;
+ }
+
+ /**
+ * Make the list of Swing {@link Component}s that are the children of the
+ * given {@link URI}.
+ *
+ * @param id
+ * The {@link URI} of the parent which children are to be made
+ * @param menuOptions
+ * Options of the created menu, for instance
+ * {@link MenuOptions#isToolbar()}.
+ * @return A {@link List} of {@link Component}s that can be added to a
+ * {@link JMenuBar}, {@link JMenu} or {@link JToolBar}.
+ */
+ protected List<Component> makeComponents(URI id, MenuOptions menuOptions) {
+ List<Component> components = new ArrayList<>();
+ for (MenuComponent childElement : getChildren(id)) {
+ if (childElement instanceof ContextualMenuComponent)
+ ((ContextualMenuComponent) childElement)
+ .setContextualSelection(menuOptions
+ .getContextualSelection());
+ /*
+ * Important - check this AFTER setContextualSelection so the item
+ * can change it's enabled-state if needed.
+ */
+ if (!childElement.isEnabled())
+ continue;
+ MenuType type = childElement.getType();
+ Action action = childElement.getAction();
+ URI childId = childElement.getId();
+ if (type.equals(MenuType.action)) {
+ if (action == null) {
+ logger.warn("Skipping invalid action " + childId + " for "
+ + id);
+ continue;
+ }
+
+ Component actionComponent;
+ if (menuOptions.isOptionGroup()) {
+ if (menuOptions.isToolbar()) {
+ actionComponent = new JToggleButton(action);
+ toolbarizeButton((AbstractButton) actionComponent);
+ } else
+ actionComponent = new JRadioButtonMenuItem(action);
+ } else {
+ if (menuOptions.isToolbar()) {
+ actionComponent = new JButton(action);
+ toolbarizeButton((AbstractButton) actionComponent);
+ } else
+ actionComponent = new JMenuItem(action);
+ }
+ registerComponent(childId, actionComponent);
+ components.add(actionComponent);
+ } else if (type.equals(MenuType.toggle)) {
+ if (action == null) {
+ logger.warn("Skipping invalid toggle " + childId + " for "
+ + id);
+ continue;
+ }
+ Component toggleComponent;
+ if (menuOptions.isToolbar())
+ toggleComponent = new JToggleButton(action);
+ else
+ toggleComponent = new JCheckBoxMenuItem(action);
+ registerComponent(childId, toggleComponent);
+ components.add(toggleComponent);
+ } else if (type.equals(MenuType.custom)) {
+ Component customComponent = childElement.getCustomComponent();
+ if (customComponent == null) {
+ logger.warn("Skipping null custom component " + childId
+ + " for " + id);
+ continue;
+ }
+ registerComponent(childId, customComponent);
+ components.add(customComponent);
+ } else if (type.equals(MenuType.optionGroup))
+ addOptionGroup(components, childId, menuOptions);
+ else if (type.equals(MenuType.section))
+ addSection(components, childId, menuOptions);
+ else if (type.equals(MenuType.menu))
+ addMenu(components, childElement, menuOptions);
+ else {
+ logger.warn("Skipping invalid/unknown type " + type + " for "
+ + id);
+ continue;
+ }
+ }
+ stripTrailingNullSeparator(components);
+ return components;
+ }
+
+ /**
+ * Fill the specified menu bar with the menu elements that have the given
+ * URI as their parent.
+ * <p>
+ * Existing elements on the menu bar will be removed.
+ *
+ * @param menuBar
+ * The {@link JMenuBar} to update
+ * @param id
+ * The {@link URI} of the menu bar
+ */
+ protected void populateMenuBar(JMenuBar menuBar, URI id) {
+ menuBar.removeAll();
+ MenuComponent menuDef = uriToMenuElement.get(id);
+ if (menuDef == null)
+ throw new IllegalArgumentException("Unknown menuBar " + id);
+ if (!menuDef.getType().equals(MenuType.menu))
+ throw new IllegalArgumentException("Element " + id
+ + " is not a menu, but a " + menuDef.getType());
+ MenuOptions menuOptions = new MenuOptions();
+ for (Component component : makeComponents(id, menuOptions))
+ if (component == null)
+ logger.warn("Ignoring separator in menu bar " + id);
+ else
+ menuBar.add(component);
+ }
+
+ /**
+ * Fill the specified menu bar with the menu elements that have the given
+ * URI as their parent.
+ * <p>
+ * Existing elements on the menu bar will be removed.
+ *
+ * @param popupMenu
+ * The {@link JPopupMenu} to update
+ * @param id
+ * The {@link URI} of the menu bar
+ * @param contextualSelection
+ * The current selection for the context menu
+ */
+ protected void populateContextMenu(JPopupMenu popupMenu, URI id,
+ ContextualSelection contextualSelection) {
+ popupMenu.removeAll();
+ MenuComponent menuDef = uriToMenuElement.get(id);
+ if (menuDef == null)
+ throw new IllegalArgumentException("Unknown menuBar " + id);
+ if (!menuDef.getType().equals(MenuType.menu))
+ throw new IllegalArgumentException("Element " + id
+ + " is not a menu, but a " + menuDef.getType());
+ MenuOptions menuOptions = new MenuOptions();
+ menuOptions.setContextualSelection(contextualSelection);
+ for (Component component : makeComponents(id, menuOptions))
+ if (component == null)
+ popupMenu.addSeparator();
+ else
+ popupMenu.add(component);
+ }
+
+ /**
+ * Fill the specified tool bar with the elements that have the given URI as
+ * their parent.
+ * <p>
+ * Existing elements on the tool bar will be removed.
+ *
+ * @param toolbar
+ * The {@link JToolBar} to update
+ * @param id
+ * The {@link URI} of the tool bar
+ */
+ protected void populateToolBar(JToolBar toolbar, URI id) {
+ toolbar.removeAll();
+ MenuComponent toolbarDef = uriToMenuElement.get(id);
+ if (toolbarDef == null)
+ throw new IllegalArgumentException("Unknown toolBar " + id);
+ if (!toolbarDef.getType().equals(MenuType.toolBar))
+ throw new IllegalArgumentException("Element " + id
+ + " is not a toolBar, but a " + toolbarDef.getType());
+ if (toolbarDef.getAction() != null) {
+ String name = (String) toolbarDef.getAction().getValue(Action.NAME);
+ toolbar.setName(name);
+ } else
+ toolbar.setName("");
+ MenuOptions menuOptions = new MenuOptions();
+ menuOptions.setToolbar(true);
+ for (Component component : makeComponents(id, menuOptions)) {
+ if (component == null) {
+ toolbar.addSeparator();
+ continue;
+ }
+ if (component instanceof JButton) {
+ JButton toolbarButton = (JButton) component;
+ toolbarButton.putClientProperty("hideActionText", true);
+ }
+ toolbar.add(component);
+ }
+ }
+
+ /**
+ * Register a component that has been created. Such a component can be
+ * resolved through {@link #getComponentByURI(URI)}.
+ *
+ * @param id
+ * The {@link URI} that defined the component
+ * @param component
+ * The {@link Component} that was created.
+ */
+ protected synchronized void registerComponent(URI id, Component component) {
+ registerComponent(id, component, false);
+ }
+
+ /**
+ * Register a component that has been created. Such a component can be
+ * resolved through {@link #getComponentByURI(URI)}.
+ *
+ * @param id
+ * The {@link URI} that defined the component
+ * @param component
+ * The {@link Component} that was created.
+ * @param published
+ * <code>true</code> if the component has been published through
+ * {@link #createMenuBar()} or similar, and is to be
+ * automatically updated by later calls to {@link #update()}.
+ */
+ protected synchronized void registerComponent(URI id, Component component,
+ boolean published) {
+ uriToComponent.put(id, new WeakReference<>(component));
+ componentToUri.put(component, id);
+ if (published) {
+ List<WeakReference<Component>> publishedComponents = uriToPublishedComponents
+ .get(id);
+ if (publishedComponents == null) {
+ publishedComponents = new ArrayList<>();
+ uriToPublishedComponents.put(id, publishedComponents);
+ }
+ publishedComponents.add(new WeakReference<>(component));
+ }
+ setHelpStringForComponent(component, id);
+ }
+
+ /**
+ * Reset all collections
+ *
+ */
+ protected synchronized void resetCollections() {
+ menuElementTree = new HashMap<>();
+ componentToUri = new WeakHashMap<>();
+ uriToMenuElement = new HashMap<>();
+ uriToComponent = new HashMap<>();
+ }
+
+ /**
+ * Set javax.help string to identify the component for later references to
+ * the help document. Note that the component (ie. the
+ * {@link AbstractMenuAction} must have an ID for an registration to take
+ * place.
+ *
+ * @param component
+ * The {@link Component} to set help string for
+ * @param componentId
+ * The {@link URI} to be used as identifier
+ */
+ protected void setHelpStringForComponent(Component component,
+ URI componentId) {
+ if (componentId != null) {
+ String helpId = componentId.toASCIIString();
+ setHelpIDString(component, helpId);
+ }
+ }
+
+ /**
+ * Make an {@link AbstractButton} be configured in a "toolbar-like" way, for
+ * instance showing only the icon.
+ *
+ * @param actionButton
+ * Button to toolbarise
+ */
+ protected void toolbarizeButton(AbstractButton actionButton) {
+ Action action = actionButton.getAction();
+ if (action.getValue(SHORT_DESCRIPTION) == null)
+ action.putValue(SHORT_DESCRIPTION, action.getValue(NAME));
+ actionButton.setBorder(new EmptyBorder(0, 2, 0, 2));
+ // actionButton.setHorizontalTextPosition(JButton.CENTER);
+ // actionButton.setVerticalTextPosition(JButton.BOTTOM);
+ if (action.getValue(Action.SMALL_ICON) != null) {
+ // Don't show the text
+ actionButton.putClientProperty("hideActionText", true);
+ // Since hideActionText seems to be broken in Java 5 and/or OS X
+ actionButton.setText(null);
+ }
+ }
+
+ /**
+ * Update all components that have been published using
+ * {@link #createMenuBar()} and similar. Content of such components will be
+ * removed and replaced by fresh components.
+ */
+ protected void updatePublishedComponents() {
+ for (Entry<URI, List<WeakReference<Component>>> entry : uriToPublishedComponents
+ .entrySet())
+ for (WeakReference<Component> reference : entry.getValue()) {
+ URI id = entry.getKey();
+ Component component = reference.get();
+ if (component == null)
+ continue;
+ if (component instanceof JToolBar)
+ populateToolBar((JToolBar) component, id);
+ else if (component instanceof JMenuBar)
+ populateMenuBar((JMenuBar) component, id);
+ else
+ logger.warn("Could not update published component " + id
+ + ": " + component.getClass());
+ }
+ }
+
+ public void setMenuComponents(List<MenuComponent> menuComponents) {
+ this.menuComponents = menuComponents;
+ }
+
+ public void setSelectionManager(SelectionManager selectionManager) {
+ selectionManager.addObserver(new SelectionManagerObserver());
+ }
+
+ /**
+ * {@link Comparator} that can order {@link MenuComponent}s by their
+ * {@link MenuComponent#getPositionHint()}.
+ */
+ protected static class MenuElementComparator implements
+ Comparator<MenuComponent> {
+ @Override
+ public int compare(MenuComponent a, MenuComponent b) {
+ return a.getPositionHint() - b.getPositionHint();
+ }
+ }
+
+ /**
+ * Various options for
+ * {@link MenuManagerImpl#makeComponents(URI, MenuOptions)} and friends.
+ *
+ * @author Stian Soiland-Reyes
+ */
+ public static class MenuOptions {
+ private boolean isToolbar = false;
+ private boolean isOptionGroup = false;
+ private ContextualSelection contextualSelection = null;
+
+ public ContextualSelection getContextualSelection() {
+ return contextualSelection;
+ }
+
+ public void setContextualSelection(
+ ContextualSelection contextualSelection) {
+ this.contextualSelection = contextualSelection;
+ }
+
+ public MenuOptions(MenuOptions original) {
+ this.isOptionGroup = original.isOptionGroup();
+ this.isToolbar = original.isToolbar();
+ this.contextualSelection = original.getContextualSelection();
+ }
+
+ public MenuOptions() {
+ }
+
+ @Override
+ protected MenuOptions clone() {
+ return new MenuOptions(this);
+ }
+
+ public boolean isToolbar() {
+ return isToolbar;
+ }
+
+ public void setToolbar(boolean isToolbar) {
+ this.isToolbar = isToolbar;
+ }
+
+ public boolean isOptionGroup() {
+ return isOptionGroup;
+ }
+
+ public void setOptionGroup(boolean isOptionGroup) {
+ this.isOptionGroup = isOptionGroup;
+ }
+ }
+
+ private final class SelectionManagerObserver extends
+ SwingAwareObserver<SelectionManagerEvent> {
+ private static final String DESIGN_PERSPECTIVE_ID = "net.sf.taverna.t2.ui.perspectives.design.DesignPerspective";
+ private static final String RESULTS_PERSPECTIVE_ID = "net.sf.taverna.t2.ui.perspectives.results.ResultsPerspective";
+
+ @Override
+ public void notifySwing(Observable<SelectionManagerEvent> sender,
+ SelectionManagerEvent message) {
+ if (!(message instanceof PerspectiveSelectionEvent))
+ return;
+ handlePerspectiveSelect((PerspectiveSelectionEvent) message);
+ }
+
+ private void handlePerspectiveSelect(PerspectiveSelectionEvent event) {
+ String perspectiveID = event.getSelectedPerspective().getID();
+ boolean isDesign = DESIGN_PERSPECTIVE_ID.equals(perspectiveID);
+ boolean isResults = RESULTS_PERSPECTIVE_ID.equals(perspectiveID);
+
+ for (MenuComponent menuComponent : menuComponents)
+ if (!(menuComponent instanceof ContextualMenuComponent)) {
+ Action action = menuComponent.getAction();
+ if (action instanceof DesignOnlyAction)
+ action.setEnabled(isDesign);
+ else if (action instanceof DesignOrResultsAction)
+ action.setEnabled(isDesign || isResults);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/AdvancedMenu.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/AdvancedMenu.java b/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/AdvancedMenu.java
new file mode 100644
index 0000000..50c57e0
--- /dev/null
+++ b/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/AdvancedMenu.java
@@ -0,0 +1,43 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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 org.apache.taverna.workbench.ui.impl.menu;
+
+import static java.awt.event.KeyEvent.VK_A;
+import static javax.swing.Action.MNEMONIC_KEY;
+import static org.apache.taverna.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
+
+import java.net.URI;
+
+import org.apache.taverna.ui.menu.AbstractMenu;
+
+public class AdvancedMenu extends AbstractMenu {
+ public static final URI ADVANCED_URI = URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#advanced");
+
+ public AdvancedMenu() {
+ super(DEFAULT_MENU_BAR, 1000, ADVANCED_URI, makeAction());
+ }
+
+ public static DummyAction makeAction() {
+ DummyAction action = new DummyAction("Advanced");
+ action.putValue(MNEMONIC_KEY, Integer.valueOf(VK_A));
+ return action;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/EditMenu.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/EditMenu.java b/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/EditMenu.java
new file mode 100644
index 0000000..4d63107
--- /dev/null
+++ b/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/EditMenu.java
@@ -0,0 +1,42 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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 org.apache.taverna.workbench.ui.impl.menu;
+
+import static java.awt.event.KeyEvent.VK_E;
+import static javax.swing.Action.MNEMONIC_KEY;
+import static org.apache.taverna.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
+
+import java.net.URI;
+
+import org.apache.taverna.ui.menu.AbstractMenu;
+
+public class EditMenu extends AbstractMenu {
+ public EditMenu() {
+ super(DEFAULT_MENU_BAR, 20, URI
+ .create("http://taverna.sf.net/2008/t2workbench/menu#edit"),
+ makeAction());
+ }
+
+ public static DummyAction makeAction() {
+ DummyAction action = new DummyAction("Edit");
+ action.putValue(MNEMONIC_KEY, Integer.valueOf(VK_E));
+ return action;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/a9a52bd5/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/FeedbackMenuAction.java
----------------------------------------------------------------------
diff --git a/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/FeedbackMenuAction.java b/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/FeedbackMenuAction.java
new file mode 100644
index 0000000..3cb6b7d
--- /dev/null
+++ b/taverna-menu-impl/src/main/java/org/apache/taverna/workbench/ui/impl/menu/FeedbackMenuAction.java
@@ -0,0 +1,74 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you 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 org.apache.taverna.workbench.ui.impl.menu;
+
+import static java.awt.Desktop.getDesktop;
+import static org.apache.taverna.workbench.ui.impl.menu.HelpMenu.HELP_URI;
+
+import java.awt.event.ActionEvent;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+
+import org.apache.log4j.Logger;
+
+/**
+ * MenuItem for feedback
+ *
+ * @author alanrw
+ */
+public class FeedbackMenuAction extends AbstractMenuAction {
+ private static Logger logger = Logger.getLogger(FeedbackMenuAction.class);
+
+ private static String FEEDBACK_URL = "http://www.taverna.org.uk/about/contact-us/feedback/";
+
+ public FeedbackMenuAction() {
+ super(HELP_URI, 20);
+ }
+
+ @Override
+ protected Action createAction() {
+ return new FeedbackAction();
+ }
+
+ @SuppressWarnings("serial")
+ private final class FeedbackAction extends AbstractAction {
+ private FeedbackAction() {
+ super("Contact us");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ getDesktop().browse(new URI(FEEDBACK_URL));
+ } catch (IOException e1) {
+ logger.error("Unable to open URL", e1);
+ } catch (URISyntaxException e1) {
+ logger.error("Invalid URL syntax", e1);
+ }
+ }
+ }
+
+}