http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java b/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java new file mode 100644 index 0000000..9f6ac8c --- /dev/null +++ b/taverna-workbench-httpproxy-config/src/main/java/net/sf/taverna/t2/workbench/httpproxy/config/HttpProxyConfigurationUIFactory.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.httpproxy.config; + +import javax.swing.JPanel; + +import uk.org.taverna.configuration.Configurable; +import uk.org.taverna.configuration.ConfigurationUIFactory; +import uk.org.taverna.configuration.proxy.HttpProxyConfiguration; + +/** + * A Factory to create a HttpProxyConfiguration + * + * @author alanrw + * @author David Withers + */ +public class HttpProxyConfigurationUIFactory implements ConfigurationUIFactory { + private HttpProxyConfiguration httpProxyConfiguration; + + @Override + public boolean canHandle(String uuid) { + return uuid.equals(getConfigurable().getUUID()); + } + + @Override + public JPanel getConfigurationPanel() { + return new HttpProxyConfigurationPanel(httpProxyConfiguration); + } + + @Override + public Configurable getConfigurable() { + return httpProxyConfiguration; + } + + public void setHttpProxyConfiguration(HttpProxyConfiguration httpProxyConfiguration) { + this.httpProxyConfiguration = httpProxyConfiguration; + } +}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory ---------------------------------------------------------------------- diff --git a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory new file mode 100644 index 0000000..d87772b --- /dev/null +++ b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/services/net.sf.taverna.t2.workbench.configuration.ConfigurationUIFactory @@ -0,0 +1 @@ +net.sf.taverna.t2.workbench.httpproxy.config.HttpProxyConfigurationUIFactory \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml ---------------------------------------------------------------------- diff --git a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml new file mode 100644 index 0000000..631bdb4 --- /dev/null +++ b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context-osgi.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:beans="http://www.springframework.org/schema/beans" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/osgi + http://www.springframework.org/schema/osgi/spring-osgi.xsd"> + + <service ref="HttpProxyConfigurationUIFactory" interface="uk.org.taverna.configuration.ConfigurationUIFactory" /> + + <reference id="httpProxyConfiguration" interface="uk.org.taverna.configuration.proxy.HttpProxyConfiguration" /> + +</beans:beans> http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml ---------------------------------------------------------------------- diff --git a/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml new file mode 100644 index 0000000..6d6060f --- /dev/null +++ b/taverna-workbench-httpproxy-config/src/main/resources/META-INF/spring/httpproxy-config-context.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <bean id="HttpProxyConfigurationUIFactory" class="net.sf.taverna.t2.workbench.httpproxy.config.HttpProxyConfigurationUIFactory"> + <property name="httpProxyConfiguration" ref="httpProxyConfiguration" /> + </bean> + +</beans> http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-menu-impl/pom.xml ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/pom.xml b/taverna-workbench-menu-impl/pom.xml new file mode 100644 index 0000000..d95bf49 --- /dev/null +++ b/taverna-workbench-menu-impl/pom.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>net.sf.taverna.t2</groupId> + <artifactId>ui-impl</artifactId> + <version>2.0-SNAPSHOT</version> + </parent> + <groupId>net.sf.taverna.t2.ui-impl</groupId> + <artifactId>menu-impl</artifactId> + <packaging>bundle</packaging> + <name>Menu generation implementation</name> + <description>The main workbench ui</description> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Embed-Dependency>javahelp</Embed-Dependency> + <Import-Package>org.jdesktop.jdic.browser;resolution:=optional,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>net.sf.taverna.t2.ui-api</groupId> + <artifactId>workbench-api</artifactId> + <version>${t2.ui.api.version}</version> + </dependency> + <dependency> + <groupId>net.sf.taverna.t2.ui-api</groupId> + <artifactId>menu-api</artifactId> + <version>${t2.ui.api.version}</version> + </dependency> + <dependency> + <groupId>net.sf.taverna.t2.ui-api</groupId> + <artifactId>helper-api</artifactId> + <version>${t2.ui.api.version}</version> + </dependency> + <dependency> + <groupId>net.sf.taverna.t2.lang</groupId> + <artifactId>ui</artifactId> + <version>${t2.lang.version}</version> + </dependency> + <dependency> + <groupId>uk.org.taverna.configuration</groupId> + <artifactId>taverna-app-configuration-api</artifactId> + <version>${taverna.configuration.version}</version> + </dependency> + + <dependency> + <groupId>javax.help</groupId> + <artifactId>javahelp</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java new file mode 100644 index 0000000..ee1fd3d --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/ui/menu/impl/MenuManagerImpl.java @@ -0,0 +1,880 @@ +/******************************************************************************* + * 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 net.sf.taverna.t2.lang.observer.MultiCaster; +import net.sf.taverna.t2.lang.observer.Observable; +import net.sf.taverna.t2.lang.observer.Observer; +import net.sf.taverna.t2.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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java new file mode 100644 index 0000000..9a2f37b --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/AdvancedMenu.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java new file mode 100644 index 0000000..a15237c --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/EditMenu.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * 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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java new file mode 100644 index 0000000..6b6eb7c --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FeedbackMenuAction.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java new file mode 100644 index 0000000..61f963b --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/FileMenu.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java new file mode 100644 index 0000000..c4169cc --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/HelpMenu.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java new file mode 100644 index 0000000..d091c8e --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/OnlineHelpMenuAction.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java new file mode 100644 index 0000000..308d51d --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ShowLogsAndDataMenuAction.java @@ -0,0 +1,89 @@ +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/72850d5a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java new file mode 100644 index 0000000..2df05e5 --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/java/net/sf/taverna/t2/workbench/ui/impl/menu/ViewShowMenuSection.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * 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/72850d5a/taverna-workbench-menu-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuManager ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuManager b/taverna-workbench-menu-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuManager new file mode 100644 index 0000000..3b06fd9 --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/resources/META-INF/services/net.sf.taverna.t2.ui.menu.MenuManager @@ -0,0 +1 @@ +net.sf.taverna.t2.ui.menu.impl.MenuManagerImpl \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context-osgi.xml ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context-osgi.xml b/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context-osgi.xml new file mode 100644 index 0000000..3a1eadf --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context-osgi.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:beans="http://www.springframework.org/schema/beans" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/osgi + http://www.springframework.org/schema/osgi/spring-osgi.xsd"> + + <service ref="MenuManagerImpl" interface="net.sf.taverna.t2.ui.menu.MenuManager" /> + + <service ref="FileMenu" auto-export="interfaces" /> + <service ref="EditMenu" auto-export="interfaces" /> + <service ref="AdvancedMenu" auto-export="interfaces" /> + <service ref="HelpMenu" auto-export="interfaces" /> + <service ref="OnlineHelpMenuAction" auto-export="interfaces" /> + <service ref="FeedbackMenuAction" auto-export="interfaces" /> + <service ref="ShowLogsAndDataMenuAction" auto-export="interfaces" /> + + <reference id="applicationConfiguration" interface="uk.org.taverna.configuration.app.ApplicationConfiguration" /> + <reference id="selectionManager" interface="net.sf.taverna.t2.workbench.selection.SelectionManager" /> + + <list id="menuComponents" interface="net.sf.taverna.t2.ui.menu.MenuComponent" cardinality="0..N" greedy-proxying="true"> + <listener ref="MenuManagerImpl" bind-method="update" unbind-method="update" /> + </list> + +</beans:beans> http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context.xml ---------------------------------------------------------------------- diff --git a/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context.xml b/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context.xml new file mode 100644 index 0000000..62fd24e --- /dev/null +++ b/taverna-workbench-menu-impl/src/main/resources/META-INF/spring/menu-impl-context.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd"> + + <bean id="MenuManagerImpl" class="net.sf.taverna.t2.ui.menu.impl.MenuManagerImpl"> + <property name="menuComponents" ref="menuComponents" /> + <property name="selectionManager" ref="selectionManager" /> + </bean> + + <bean id="FileMenu" class="net.sf.taverna.t2.workbench.ui.impl.menu.FileMenu" /> + <bean id="EditMenu" class="net.sf.taverna.t2.workbench.ui.impl.menu.EditMenu" /> + <bean id="AdvancedMenu" class="net.sf.taverna.t2.workbench.ui.impl.menu.AdvancedMenu" /> + <bean id="HelpMenu" class="net.sf.taverna.t2.workbench.ui.impl.menu.HelpMenu" /> + <bean id="OnlineHelpMenuAction" + class="net.sf.taverna.t2.workbench.ui.impl.menu.OnlineHelpMenuAction" /> + <bean id="FeedbackMenuAction" + class="net.sf.taverna.t2.workbench.ui.impl.menu.FeedbackMenuAction" /> + <bean id="ShowLogsAndDataMenuAction" + class="net.sf.taverna.t2.workbench.ui.impl.menu.ShowLogsAndDataMenuAction"> + <property name="applicationConfiguration" ref="applicationConfiguration" /> + </bean> + +</beans> http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugin-manager/pom.xml ---------------------------------------------------------------------- diff --git a/taverna-workbench-plugin-manager/pom.xml b/taverna-workbench-plugin-manager/pom.xml new file mode 100644 index 0000000..4e9f0c1 --- /dev/null +++ b/taverna-workbench-plugin-manager/pom.xml @@ -0,0 +1,49 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>net.sf.taverna.t2</groupId> + <artifactId>ui-impl</artifactId> + <version>2.0-SNAPSHOT</version> + </parent> + <groupId>net.sf.taverna.t2.ui-impl</groupId> + <artifactId>plugin-manager</artifactId> + <packaging>bundle</packaging> + <name>Taverna Workbench Plugin Manager</name> + <dependencies> + <dependency> + <groupId>net.sf.taverna.t2.ui-api</groupId> + <artifactId>menu-api</artifactId> + <version>${t2.ui.api.version}</version> + </dependency> + <dependency> + <groupId>net.sf.taverna.t2.ui-api</groupId> + <artifactId>workbench-api</artifactId> + <version>${t2.ui.api.version}</version> + </dependency> + <dependency> + <groupId>uk.org.taverna.commons</groupId> + <artifactId>taverna-plugin-api</artifactId> + <version> ${taverna.commons.version}</version> + </dependency> + + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <version>${osgi.core.version}</version> + </dependency> + + <!-- <dependency> + <groupId>uk.org.taverna.commons</groupId> + <artifactId>taverna-download-impl</artifactId> + <version>0.1.0-SNAPSHOT</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>uk.org.taverna.commons</groupId> + <artifactId>taverna-plugin-impl</artifactId> + <version>0.1.0-SNAPSHOT</version> + <scope>test</scope> + </dependency> --> + </dependencies> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/AvailablePluginPanel.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/AvailablePluginPanel.java b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/AvailablePluginPanel.java new file mode 100644 index 0000000..f189f91 --- /dev/null +++ b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/AvailablePluginPanel.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (C) 2013 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.plugin.impl; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Action; + +import uk.org.taverna.commons.plugin.PluginException; +import uk.org.taverna.commons.plugin.PluginManager; +import uk.org.taverna.commons.plugin.xml.jaxb.PluginVersions; + +/** + * @author David Withers + */ +@SuppressWarnings("serial") +public class AvailablePluginPanel extends PluginPanel { + private final PluginManager pluginManager; + private final PluginVersions pluginVersions; + + public AvailablePluginPanel(PluginVersions pluginVersions, + PluginManager pluginManager) { + super(pluginVersions.getName(), pluginVersions.getOrganization(), + pluginVersions.getLatestVersion().getVersion(), pluginVersions + .getDescription()); + this.pluginVersions = pluginVersions; + this.pluginManager = pluginManager; + } + + @Override + public Action getPluginAction() { + return new PluginAction(); + } + + class PluginAction extends AbstractAction { + public PluginAction() { + putValue(NAME, "Install"); + } + + @Override + public void actionPerformed(ActionEvent e) { + setEnabled(false); + putValue(NAME, "Installing"); + try { + pluginManager.installPlugin(pluginVersions.getPluginSiteUrl(), + pluginVersions.getLatestVersion().getFile()).start(); + } catch (PluginException ex) { + ex.printStackTrace(); + } + putValue(NAME, "Installed"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/InstalledPluginPanel.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/InstalledPluginPanel.java b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/InstalledPluginPanel.java new file mode 100644 index 0000000..a08cf14 --- /dev/null +++ b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/InstalledPluginPanel.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (C) 2013 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.plugin.impl; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Action; + +import uk.org.taverna.commons.plugin.Plugin; +import uk.org.taverna.commons.plugin.PluginException; + +/** + * @author David Withers + */ +@SuppressWarnings("serial") +public class InstalledPluginPanel extends PluginPanel { + private final Plugin plugin; + + public InstalledPluginPanel(Plugin plugin) { + super(plugin.getName(), plugin.getOrganization(), plugin.getVersion() + .toString(), plugin.getDescription()); + this.plugin = plugin; + } + + @Override + public Action getPluginAction() { + return new PluginAction(); + } + + class PluginAction extends AbstractAction { + public PluginAction() { + putValue(NAME, "Uninstall"); + } + + @Override + public void actionPerformed(ActionEvent e) { + setEnabled(false); + putValue(NAME, "Uninstalling"); + try { + plugin.uninstall(); + } catch (PluginException ex) { + ex.printStackTrace(); + } + putValue(NAME, "Uninstalled"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerPanel.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerPanel.java b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerPanel.java new file mode 100644 index 0000000..dfef2fe --- /dev/null +++ b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerPanel.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (C) 2013 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.plugin.impl; + +import static java.awt.GridBagConstraints.BOTH; +import static java.awt.GridBagConstraints.EAST; +import static java.awt.GridBagConstraints.NONE; +import static java.awt.GridBagConstraints.WEST; +import static java.lang.Math.max; +import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER; +import static javax.swing.SwingConstants.CENTER; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.LayoutManager; +import java.util.List; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; + +import org.apache.log4j.Logger; + +import uk.org.taverna.commons.plugin.Plugin; +import uk.org.taverna.commons.plugin.PluginException; +import uk.org.taverna.commons.plugin.PluginManager; +import uk.org.taverna.commons.plugin.xml.jaxb.PluginVersions; + +/** + * @author David Withers + */ +@SuppressWarnings("serial") +public class PluginManagerPanel extends JPanel { + private static final Logger logger = Logger + .getLogger(PluginManagerPanel.class); + + private PluginManager pluginManager; + private JLabel message = new JLabel(""); + + public PluginManagerPanel(PluginManager pluginManager) { + this.pluginManager = pluginManager; + initialize(); + } + + public void initialize() { + removeAll(); + setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.anchor = WEST; + gbc.gridy = 0; + gbc.insets.left = 5; + gbc.insets.right = 5; + gbc.insets.top = 5; + + JTabbedPane tabbedPane = new JTabbedPane(); + tabbedPane.addTab("Available", createAvailablePluginsPanel()); + tabbedPane.addTab("Installed", createInstalledPluginsPanel()); + tabbedPane.addTab("Updates", createUpdatePluginsPanel()); + + gbc.weightx = 1; + gbc.weighty = 1; + gbc.gridy = 1; + gbc.fill = BOTH; + add(tabbedPane, gbc); + + gbc.anchor = EAST; + gbc.fill = NONE; + gbc.weightx = 0; + gbc.weighty = 0; + gbc.gridy = 2; + gbc.insets.bottom = 5; + add(message, gbc); + } + + public void checkForUpdates() { + message.setText("Checking for updates"); + try { + pluginManager.checkForUpdates(); + } catch (PluginException e) { + logger.info("Error checking for plugin updates", e); + } finally { + message.setText(""); + } + } + + private static Component scrolled(Component view) { + JScrollPane scrollPane = new JScrollPane(view); + scrollPane.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(null); + return scrollPane; + } + + private Component createAvailablePluginsPanel() { + try { + List<PluginVersions> availablePlugins = pluginManager + .getAvailablePlugins(); + if (availablePlugins.size() == 0) + return new JLabel("No new plugins available", CENTER); + + JPanel panel = new JPanel(new ListLayout()); + for (PluginVersions plugin : availablePlugins) + panel.add(new AvailablePluginPanel(plugin, pluginManager)); + return scrolled(panel); + } catch (PluginException e) { + logger.info("Error looking for new plugins", e); + return new JLabel("No new plugins available", CENTER); + } + } + + private Component createInstalledPluginsPanel() { + try { + List<Plugin> installedPlugins = pluginManager.getInstalledPlugins(); + if (installedPlugins.size() == 0) + return new JLabel("No installed plugins", CENTER); + + JPanel panel = new JPanel(new ListLayout()); + for (Plugin plugin : installedPlugins) + panel.add(new InstalledPluginPanel(plugin)); + return scrolled(panel); + } catch (PluginException e) { + return new JLabel("No installed plugins", CENTER); + } + } + + private Component createUpdatePluginsPanel() { + try { + List<PluginVersions> pluginUpdates = pluginManager + .getPluginUpdates(); + if (pluginUpdates.size() == 0) + return new JLabel("All plugins are up to date", CENTER); + + JPanel panel = new JPanel(new ListLayout()); + for (PluginVersions plugin : pluginUpdates) + panel.add(new UpdatePluginPanel(plugin, pluginManager)); + return scrolled(panel); + } catch (PluginException e) { + return new JLabel("All plugins are up to date", CENTER); + } + } + + private final class ListLayout implements LayoutManager { + @Override + public void addLayoutComponent(String name, Component comp) { + } + + @Override + public void removeLayoutComponent(Component comp) { + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + Dimension preferredLayoutSize = new Dimension(0, 1); + for (Component component : parent.getComponents()) { + Dimension preferredSize = component.getPreferredSize(); + preferredLayoutSize.width = max(preferredSize.width, + preferredLayoutSize.width); + preferredLayoutSize.height = preferredSize.height + + preferredLayoutSize.height - 1; + } + return preferredLayoutSize; + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + Dimension minimumLayoutSize = new Dimension(0, 1); + for (Component component : parent.getComponents()) { + Dimension minimumSize = component.getMinimumSize(); + minimumLayoutSize.width = max(minimumSize.width, + minimumLayoutSize.width); + minimumLayoutSize.height = minimumSize.height + + minimumLayoutSize.height - 1; + } + return minimumLayoutSize; + } + + @Override + public void layoutContainer(Container parent) { + int y = 0; + for (Component component : parent.getComponents()) { + component.setLocation(0, y); + component.setSize(parent.getSize().width, + component.getPreferredSize().height); + y += component.getHeight() - 1; + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/72850d5a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerView.java ---------------------------------------------------------------------- diff --git a/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerView.java b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerView.java new file mode 100644 index 0000000..27822a6 --- /dev/null +++ b/taverna-workbench-plugin-manager/src/main/java/net/sf/taverna/t2/workbench/plugin/impl/PluginManagerView.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (C) 2013 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.plugin.impl; + +import static net.sf.taverna.t2.workbench.MainWindow.getMainWindow; + +import javax.swing.JDialog; + +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; + +import uk.org.taverna.commons.plugin.PluginManager; + +/** + * @author David Withers + */ +public class PluginManagerView implements EventHandler { + private JDialog dialog; + private PluginManagerPanel pluginManagerPanel; + private PluginManager pluginManager; + + public void showDialog() { + getDialog().setVisible(true); + getPluginManagerPanel().checkForUpdates(); + } + + private JDialog getDialog() { + if (dialog == null) { + dialog = new JDialog(getMainWindow(), "Plugin Manager"); + dialog.add(getPluginManagerPanel()); + dialog.setSize(700, 500); + dialog.setLocationRelativeTo(dialog.getOwner()); + dialog.setVisible(true); + } + return dialog; + } + + private PluginManagerPanel getPluginManagerPanel() { + if (pluginManagerPanel == null) + pluginManagerPanel = new PluginManagerPanel(pluginManager); + return pluginManagerPanel; + } + + @Override + public void handleEvent(Event event) { + pluginManagerPanel.initialize(); + pluginManagerPanel.revalidate(); + } + + public void setPluginManager(PluginManager pluginManager) { + this.pluginManager = pluginManager; + } +}