/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2015 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.treeviewer.view; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Insets; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTextField; import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.border.BevelBorder; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FilenameUtils; import org.jdesktop.swingx.JXBusyLabel; import org.openmicroscopy.shoola.agents.treeviewer.IconManager; import org.openmicroscopy.shoola.agents.treeviewer.TreeViewerAgent; import org.openmicroscopy.shoola.agents.treeviewer.actions.GroupSelectionAction; import org.openmicroscopy.shoola.agents.treeviewer.actions.RunScriptAction; import org.openmicroscopy.shoola.agents.treeviewer.actions.TreeViewerAction; import org.openmicroscopy.shoola.agents.treeviewer.browser.Browser; import org.openmicroscopy.shoola.agents.treeviewer.cmd.ExperimenterVisitor; import org.openmicroscopy.shoola.agents.treeviewer.util.GroupItem; import org.openmicroscopy.shoola.agents.treeviewer.util.DataMenuItem; import org.openmicroscopy.shoola.agents.util.ViewerSorter; import org.openmicroscopy.shoola.agents.util.browser.TreeImageDisplay; import org.openmicroscopy.shoola.agents.util.ui.ScriptMenuItem; import org.openmicroscopy.shoola.env.LookupNames; import org.openmicroscopy.shoola.env.data.model.ScriptObject; import org.openmicroscopy.shoola.env.ui.TaskBar; import org.openmicroscopy.shoola.util.ui.ScrollablePopupMenu; import org.openmicroscopy.shoola.util.ui.SelectableMenuItem; import org.openmicroscopy.shoola.util.ui.UIUtilities; import omero.gateway.model.ExperimenterData; import omero.gateway.model.GroupData; /** * The tool bar of {@link TreeViewer}. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * @since OME2.2 */ class ToolBar extends JPanel { /** The text indicating the number of successful import.*/ private static final String IMPORTED_TEXT = " Imported"; /** The text indicating the number of failed import.*/ private static final String FAILED_TEXT = " Failed"; /** The tool tip used to indicate on-going import.*/ private static final String IMPORT_TOOLTIP = "Indicates on-going imports"; /** Size of the horizontal box. */ private static final Dimension HBOX = new Dimension(100, 16); /** Text indicating to display the groups.*/ private static final String GROUP_DISPLAY_TEXT = "Display Groups"; /** The width of search field in characters */ private static final int SEARCHFIELD_WIDTH = 12; /** The default text shown in the empty search field */ private static final String SEARCHFIELD_TEXT = "Search ..."; /** Reference to the control. */ private TreeViewerControl controller; /** Reference to the model. */ private TreeViewerModel model; /** Reference to the view. */ private TreeViewerWin view; /** The menu displaying the groups the user is a member of. */ private JPopupMenu personalMenu; /** Button to open the full in a separate window. */ private JToggleButton fullScreen; /** The menu displaying the available scripts.*/ private JPopupMenu scriptsMenu; /** The button showing the available scripts.*/ private JButton scriptButton; /** Indicates the loading progress. */ private JXBusyLabel busyLabel; /** The index of the {@link #scriptButton}.*/ private int index; /** The management bar.*/ private JToolBar bar; /** The button to display the menu.*/ private JButton menuButton; /** Used to sort the list of users.*/ private ViewerSorter sorter; /** The menu displaying the users option.*/ private JPopupMenu popupMenu; /** Label indicating the number of successful import if any.*/ private JLabel importSuccessLabel; /** Label indicating the number of failed import if any.*/ private JLabel importFailureLabel; /** Label indicating the import status.*/ private JXBusyLabel importLabel; /** The terms to search for. */ private JTextField searchField; /** * Sets either the user display or group display. * * @param userDisplay Pass <code>true</code> for user display, * <code>false</code> for group display. */ private void handleSelectionDisplay(boolean userDisplay) { int n = popupMenu.getComponentCount(); GroupItem item; Component c; for (int i = 0; i < n; i++) { c = popupMenu.getComponent(i); if (c instanceof GroupItem) { item = (GroupItem) c; item.setDisplay(userDisplay); } } int mode = LookupNames.EXPERIMENTER_DISPLAY; if (!userDisplay) mode = LookupNames.GROUP_DISPLAY; controller.setDisplayMode(mode); } /** * Selects or de-selects all the groups. * * @param select Pass <code>true</code> to select all the groups, * <code>false</code> otherwise. */ private void handleAllGroupsSelection(boolean select) { int n = popupMenu.getComponentCount(); GroupItem item; Component c; for (int i = 0; i < n; i++) { c = popupMenu.getComponent(i); if (c instanceof GroupItem) { item = (GroupItem) c; if (item.getGroup() != null) { item.setMenuSelected(select, false); if (select) item.selectUsers(false, true); } } } handleSelection(); } /** * Selects or de-selects all the users. * * @param select Pass <code>true</code> to select all the groups, * <code>false</code> otherwise. */ private void handleAllUsersSelection(boolean select) { int n = popupMenu.getComponentCount(); GroupItem item; Component c; for (int i = 0; i < n; i++) { c = popupMenu.getComponent(i); if (c instanceof GroupItem) { item = (GroupItem) c; if (item.getGroup() != null) { item.setMenuSelected(true, false); item.selectUsers(true, select); } } } handleSelection(); } /** Handles the selection of users.*/ private void handleSelection() { int n = popupMenu.getComponentCount(); GroupItem item; Component c; boolean b; List<ExperimenterData> users; int count = 0; int total = 0; GroupItem allGroups = null; for (int i = 0; i < n; i++) { c = popupMenu.getComponent(i); if (c instanceof GroupItem) { item = (GroupItem) c; if (item.getGroup() != null) { total++; b = !item.isMenuSelected(); users = item.getSeletectedUsers(); if (n == 1) { if (b) { //group not selected users = new ArrayList<ExperimenterData>(); } b = false; } if (!b) count++; controller.setSelection(item.getGroup(), users, b); } else { if (GroupItem.ALL_GROUPS.equals(item.getText())) { allGroups = item; } } } } if (allGroups != null) { allGroups.setMenuSelected(total == count, false); } } /** * Fires a search event */ private void search() { TreeViewerAgent.getRegistry().getEventBus().post(new SearchEvent(searchField.getText())); } /** * Formats the header. * * @param text The text to display * @return See above. */ private JPanel formatHeader(String text) { JPanel title = new JPanel(); title.setLayout(new FlowLayout(FlowLayout.LEFT)); title.add(UIUtilities.setTextFont(text)); title.setBackground(UIUtilities.BACKGROUND_COLOUR_EVEN); return title; } /** * Creates the menu hosting the users belonging to the specified group. * Returns <code>true</code> if the group is selected, <code>false</code> * otherwise. * * @param groupItem The item hosting the group. * @param size The number of groups. * @return See above. */ private boolean createGroupMenu(GroupItem groupItem, int size) { long loggedUserID = model.getUserDetails().getId(); GroupData group = groupItem.getGroup(); //Determine the user already added to the display Browser browser = model.getBrowser(Browser.PROJECTS_EXPLORER); TreeImageDisplay refNode = null; List<TreeImageDisplay> nodes; ExperimenterVisitor visitor; List<Long> users = new ArrayList<Long>(); //Find the group already displayed if (group != null && size > 0) { visitor = new ExperimenterVisitor(browser, group.getId()); browser.accept(visitor); nodes = visitor.getNodes(); if (nodes.size() == 1) { refNode = nodes.get(0); } visitor = new ExperimenterVisitor(browser, -1, -1); if (refNode != null) refNode.accept(visitor); else if (size == 1) browser.accept(visitor); nodes = visitor.getNodes(); TreeImageDisplay n; if (CollectionUtils.isNotEmpty(nodes)) { Iterator<TreeImageDisplay> j = nodes.iterator(); while (j.hasNext()) { n = j.next(); if (n.getUserObject() instanceof ExperimenterData) { users.add(((ExperimenterData) n.getUserObject()).getId()); } } if (size == 1) { groupItem.setMenuSelected(true, false); } } } //now add the users List<DataMenuItem> items = new ArrayList<DataMenuItem>(); JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); List l = null; if (group != null) l = sorter.sort(group.getLeaders()); Iterator i; ExperimenterData exp; DataMenuItem item, allUser; boolean view = true; if (group != null) { int level = group.getPermissions().getPermissionsLevel(); if (level == GroupData.PERMISSIONS_PRIVATE) { view = model.isAdministrator() || model.isGroupOwner(group); } } List<DataMenuItem> list = new ArrayList<DataMenuItem>(); String v = (String) TreeViewerAgent.getRegistry().lookup( LookupNames.GROUP_ALL_MEMBERS_NAME); if (v == null || v.trim().length() == 0) { v = DataMenuItem.ALL_USERS_TEXT; } Boolean enabled = Boolean.parseBoolean((String) TreeViewerAgent.getRegistry().lookup( LookupNames.GROUP_ALL_MEMBERS_ENABLED)); boolean b = false; if (enabled != null) { b = enabled.booleanValue(); } allUser = new DataMenuItem(v, b); allUser.setRefString(DataMenuItem.ALL_USERS_TEXT); allUser.addPropertyChangeListener(groupItem); items.add(allUser); if (view) p.add(allUser); int count = 0; int total = 0; enabled = Boolean.parseBoolean((String) TreeViewerAgent.getRegistry().lookup( LookupNames.GROUP_LEADERS_ENABLED)); b = false; if (enabled != null) { b = enabled.booleanValue(); } if (CollectionUtils.isNotEmpty(l) && b) { total += l.size(); i = l.iterator(); while (i.hasNext()) { exp = (ExperimenterData) i.next(); if (view || exp.getId() == loggedUserID) { if (exp.getId() == loggedUserID) b = true; item = new DataMenuItem(exp, b); item.setChecked(users.contains(exp.getId())); if (item.isChecked()) count++; item.addPropertyChangeListener(groupItem); items.add(item); list.add(item); } } if (list.size() > 0) { v = (String) TreeViewerAgent.getRegistry().lookup( LookupNames.GROUP_LEADERS_NAME); if (v == null || v.trim().length() == 0) { v = "Group owners"; } p.add(formatHeader(v)); for(DataMenuItem dmi : list) p.add(dmi); list.clear(); } } if (group != null) l = sorter.sort(group.getMembersOnly()); enabled = Boolean.parseBoolean((String) TreeViewerAgent.getRegistry().lookup( LookupNames.GROUP_MEMBERS_ENABLED)); b = false; if (enabled != null) { b = enabled.booleanValue(); } if (CollectionUtils.isNotEmpty(l) && b) { total += l.size(); i = l.iterator(); while (i.hasNext()) { exp = (ExperimenterData) i.next(); if (view || exp.getId() == loggedUserID) { if (exp.getId() == loggedUserID) b = true; item = new DataMenuItem(exp, b); item.setChecked(users.contains(exp.getId())); if (item.isChecked()) count++; item.addPropertyChangeListener(groupItem); items.add(item); list.add(item); } } if (list.size() > 0) { v = (String) TreeViewerAgent.getRegistry().lookup( LookupNames.GROUP_MEMBERS_NAME); if (v == null || v.trim().length() == 0) { v = "Members"; } p.add(formatHeader(v)); for(DataMenuItem dmi : list) p.add(dmi); } } allUser.setChecked(total != 0 && total == count); allUser.addPropertyChangeListener(groupItem); JScrollPane pane = new JScrollPane(p); Dimension d = p.getPreferredSize(); int max = 500; if (d.height > max) { Insets insets = pane.getInsets(); pane.setPreferredSize( new Dimension(d.width+insets.left+insets.right+20, max)); } groupItem.add(pane); groupItem.setUsersItem(items); groupItem.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String name = evt.getPropertyName(); if (GroupItem.USER_SELECTION_PROPERTY.equals(name)) handleSelection(); else if (GroupItem.ALL_GROUPS_SELECTION_PROPERTY.equals(name)) handleAllGroupsSelection(true); else if (GroupItem.ALL_GROUPS_DESELECTION_PROPERTY.equals(name)) handleAllGroupsSelection(false); else if (GroupItem.ALL_USERS_SELECTION_PROPERTY.equals(name)) handleAllUsersSelection((Boolean) evt.getNewValue()); } }); return groupItem.isMenuSelected(); } /** * Creates the menu displaying the groups and users. * * @param source The invoker. * @param p The location of the mouse clicked. */ private void createGroupsAndUsersMenu(Component source, Point p) { if (!source.isEnabled()) return; Collection groups = model.getGroups(); if (CollectionUtils.isEmpty(groups)) return; popupMenu.removeAll(); GroupData group; List sortedGroups = sorter.sort(groups); //Determine the group already displayed. Browser browser = model.getBrowser(Browser.PROJECTS_EXPLORER); List<TreeImageDisplay> nodes; ExperimenterVisitor visitor; //Find the user already added to the selected group. visitor = new ExperimenterVisitor(browser, -1); browser.accept(visitor); nodes = visitor.getNodes(); Iterator<TreeImageDisplay> k = nodes.iterator(); List<Long> groupIds = new ArrayList<Long>(); long id; while (k.hasNext()) { id = k.next().getUserObjectId(); if (id >= 0) groupIds.add(id); } //Create the group menu. Iterator i = sortedGroups.iterator(); int size = sortedGroups.size(); long userID = model.getExperimenter().getId(); //First add item to toggle between users and group display final SelectableMenuItem data = new SelectableMenuItem( model.getDisplayMode() == LookupNames.EXPERIMENTER_DISPLAY, DataMenuItem.USERS_TEXT, true); data.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String name = evt.getPropertyName(); if (SelectableMenuItem.SELECTION_PROPERTY.equals(name)) { handleSelectionDisplay(data.isChecked()); } } }); popupMenu.add(data); popupMenu.add(new JSeparator()); GroupItem item; GroupItem allGroup = null; //First add option to add all the groups. if (size > 1) { item = new GroupItem(false); item.setUserID(userID); createGroupMenu(item, 0); popupMenu.add(item); popupMenu.add(new JSeparator()); allGroup = item; } boolean selected; int count = 0; while (i.hasNext()) { group = (GroupData) i.next(); boolean b = groupIds.contains(group.getId()); item = new GroupItem(group, b, size > 1); item.setUserID(userID); selected = createGroupMenu(item, size); popupMenu.add(item); if (selected) count++; } if (allGroup != null) { allGroup.setMenuSelected(count == sortedGroups.size(), false); } popupMenu.show(source, p.x, p.y); } /** * Sets the defaults of the specified menu item. * * @param item The menu item. */ private void initMenuItem(JMenuItem item) { item.setBorder(null); item.setFont((Font) TreeViewerAgent.getRegistry().lookup( "/resources/fonts/Labels")); } /** * Helper method to create the tool bar hosting the management items. * * @return See above. */ private JComponent createManagementBar() { bar = new JToolBar(); bar.setFloatable(false); bar.setRollover(true); bar.setBorder(null); JToggleButton button = new JToggleButton( controller.getAction(TreeViewerControl.INSPECTOR)); button.setSelected(true); bar.add(button); button = new JToggleButton( controller.getAction(TreeViewerControl.METADATA)); button.setSelected(true); bar.add(button); JButton b = new JButton(controller.getAction(TreeViewerControl.BROWSE)); UIUtilities.unifiedButtonLookAndFeel(b); bar.add(b); boolean ij = false; switch (TreeViewerAgent.runAsPlugin()) { case LookupNames.IMAGE_J: case LookupNames.IMAGE_J_IMPORT: ij = true; b = UIUtilities.formatButtonFromAction( controller.getAction(TreeViewerControl.VIEW)); UIUtilities.unifiedButtonLookAndFeel(b); b.addMouseListener(new MouseAdapter() { /** * Displays the menu when the user releases the mouse. * @see MouseListener#mouseReleased(MouseEvent) */ public void mouseReleased(MouseEvent e) { controller.showMenu(TreeViewer.VIEW_MENU, (JComponent) e.getSource(), e.getPoint()); } }); bar.add(b); break; default: b = new JButton(controller.getAction(TreeViewerControl.VIEW)); UIUtilities.unifiedButtonLookAndFeel(b); bar.add(b); } bar.add(b); bar.add(new JSeparator(JSeparator.VERTICAL)); //Now register the agent if any TaskBar tb = TreeViewerAgent.getRegistry().getTaskBar(); List<JComponent> l = tb.getToolBarEntries(TaskBar.AGENTS); if (l != null) { Iterator<JComponent> i = l.iterator(); JComponent comp; while (i.hasNext()) { comp = i.next(); UIUtilities.unifiedButtonLookAndFeel(comp); bar.add(comp); } bar.add(new JSeparator(JSeparator.VERTICAL)); } fullScreen = new JToggleButton( controller.getAction(TreeViewerControl.FULLSCREEN)); fullScreen.setSelected(model.isFullScreen()); //bar.add(fullScreen); if (TreeViewerAgent.isAdministrator()) { b = new JButton(controller.getAction( TreeViewerControl.UPLOAD_SCRIPT)); UIUtilities.unifiedButtonLookAndFeel(b); bar.add(b); } TreeViewerAction a = controller.getAction( TreeViewerControl.AVAILABLE_SCRIPTS); b = new JButton(a); Icon icon = b.getIcon(); Dimension d = new Dimension(UIUtilities.DEFAULT_ICON_WIDTH, UIUtilities.DEFAULT_ICON_HEIGHT); if (icon != null) d = new Dimension(icon.getIconWidth(), icon.getIconHeight()); busyLabel = new JXBusyLabel(d); busyLabel.setVisible(true); b.addMouseListener((RunScriptAction) a); UIUtilities.unifiedButtonLookAndFeel(b); scriptButton = b; bar.add(b); index = bar.getComponentCount()-1; bar.add(new JSeparator(JSeparator.VERTICAL)); MouseAdapter adapter = new MouseAdapter() { /** * Shows the menu corresponding to the display mode. */ public void mousePressed(MouseEvent me) { createGroupsAndUsersMenu((Component) me.getSource(), me.getPoint()); } }; a = controller.getAction(TreeViewerControl.SWITCH_USER); IconManager icons = IconManager.getInstance(); menuButton = new JButton(icons.getIcon(IconManager.FILTER_MENU)); menuButton.setVisible(true); menuButton.setText(GROUP_DISPLAY_TEXT); menuButton.setHorizontalTextPosition(SwingConstants.LEFT); menuButton.addMouseListener(adapter); bar.add(menuButton); setPermissions(); if (ij) { b = new JButton(a = controller.getAction( TreeViewerControl.SAVE_TO_OMERO)); bar.add(Box.createHorizontalStrut(5)); bar.add(b); } return bar; } /** * Helper method to create the tool bar hosting the edit items. * * @return See above. */ private JToolBar createSearchBar() { JToolBar bar = new JToolBar(); bar.setFloatable(false); bar.setRollover(true); bar.setBorder(null); bar.add(new JSeparator(JSeparator.VERTICAL)); bar.add(new JToggleButton( controller.getAction(TreeViewerControl.SEARCH))); return bar; } /** Builds and lays out the UI. */ private void buildGUI() { JPanel bars = new JPanel(), outerPanel = new JPanel(); bars.setBorder(null); bars.setLayout(new BoxLayout(bars, BoxLayout.X_AXIS)); bars.add(createManagementBar()); if (!TreeViewerWin.JXTASKPANE_TYPE.equals(view.getLayoutType())) { bars.add(createSearchBar()); } outerPanel.setBorder(null); outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.X_AXIS)); outerPanel.add(bars); outerPanel.add(Box.createRigidArea(HBOX)); outerPanel.add(Box.createHorizontalGlue()); setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); add(UIUtilities.buildComponentPanel(outerPanel)); add(UIUtilities.buildComponentPanelRight(buildRightPane())); } /** * Builds and lays out the component displayed on the right hand side of * the toolbar. * * @return See above. */ private JPanel buildRightPane() { JPanel p = new JPanel(); p.setBorder(null); p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); p.add(searchField); p.add(Box.createHorizontalStrut(50)); p.add(importFailureLabel); p.add(Box.createHorizontalStrut(5)); p.add(importSuccessLabel); p.add(Box.createHorizontalStrut(5)); p.add(importLabel); return p; } /** * Formats the specified label. * * @param label The label to format. */ private void formatLabel(JLabel label) { label.setHorizontalTextPosition(SwingConstants.LEADING); label.setAlignmentX(SwingConstants.RIGHT); label.setVisible(false); } /** Initializes the components.*/ private void initialize() { IconManager icons = IconManager.getInstance(); importFailureLabel = new JLabel(icons.getIcon(IconManager.DELETE)); formatLabel(importFailureLabel); importSuccessLabel = new JLabel(icons.getIcon(IconManager.APPLY)); formatLabel(importSuccessLabel); Dimension d = new Dimension(UIUtilities.DEFAULT_ICON_WIDTH, UIUtilities.DEFAULT_ICON_HEIGHT); importLabel = new JXBusyLabel(d); importLabel.setToolTipText(IMPORT_TOOLTIP); importLabel.setVisible(false); importLabel.setBusy(false); sorter = new ViewerSorter(); sorter.setCaseSensitive(true); popupMenu = new ScrollablePopupMenu(); searchField = initSearchField(); } /** * Initializes the search field */ private JTextField initSearchField() { final JTextField searchField = new JTextField(SEARCHFIELD_WIDTH); searchField.setText(SEARCHFIELD_TEXT); final Font defaultFont = searchField.getFont(); final Font italicFont = searchField.getFont().deriveFont(Font.ITALIC); searchField.setFont(italicFont); searchField.setForeground(UIUtilities.DEFAULT_FONT_COLOR); searchField.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_ENTER: search(); } } }); searchField.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { if (searchField.getText().trim().equals("")) { searchField.setText(SEARCHFIELD_TEXT); searchField.setFont(italicFont); searchField.setForeground(UIUtilities.DEFAULT_FONT_COLOR); } } @Override public void focusGained(FocusEvent e) { if (searchField.getText().equals(SEARCHFIELD_TEXT)) { searchField.setText(""); } else { searchField.selectAll(); } searchField.setFont(defaultFont); searchField.setForeground(Color.BLACK); } }); return searchField; } /** * Creates a new instance. * * @param controller Reference to the control. Mustn't be <code>null</code>. * @param model Reference to the model. Mustn't be <code>null</code>. * @param view Reference to the view. Mustn't be <code>null</code>. */ ToolBar(TreeViewerControl controller, TreeViewerModel model, TreeViewerWin view) { if (controller == null) throw new NullPointerException("No Controller."); if (model == null) throw new NullPointerException("No Model."); if (view == null) throw new NullPointerException("No View."); this.model = model; this.controller = controller; this.view = view; initialize(); buildGUI(); } /** * Brings up the <code>ManagePopupMenu</code>on top of the specified * component at the specified location. * * @param c The component that requested the pop-up menu. * @param p The point at which to display the menu, relative to the * <code>component</code>'s coordinates. */ void showManagementMenu(Component c, Point p) { if (p == null) return; if (c == null) throw new IllegalArgumentException("No component."); ManagePopupMenu managePopupMenu = new ManagePopupMenu(controller); managePopupMenu.show(c, p.x, p.y); } /** * Brings up the <code>Personal Menu</code> on top of the specified * component at the specified location. * * @param c The component that requested the pop-up menu. * @param p The point at which to display the menu, relative to the * <code>component</code>'s coordinates. */ void showPersonalMenu(Component c, Point p) { if (p == null) return; if (c == null) throw new IllegalArgumentException("No component."); personalMenu = new JPopupMenu(); personalMenu.setBorder( BorderFactory.createBevelBorder(BevelBorder.RAISED)); List<JMenuItem> l = createMenuItem(false); Iterator<JMenuItem> i = l.iterator(); while (i.hasNext()) { personalMenu.add(i.next()); } personalMenu.show(c, p.x, p.y); } /** * Creates the items for the menu. * * @param add Pass <code>true</code> to build items for the <code>Add</code> * menu, <code>false</code> otherwise. * @return See above */ private List<JMenuItem> createMenuItem(boolean add) { List<JMenuItem> items = new ArrayList<JMenuItem>(); List<GroupSelectionAction> l = controller.getUserGroupAction(add); Iterator<GroupSelectionAction> i = l.iterator(); GroupSelectionAction a; JMenuItem item; if (add) { //Check the groups that already in the view. Browser browser = model.getSelectedBrowser(); List<Long> ids = new ArrayList<Long>(); if (browser != null) { ExperimenterVisitor v = new ExperimenterVisitor(browser, -1); browser.accept(v, ExperimenterVisitor.TREEIMAGE_SET_ONLY); List<TreeImageDisplay> nodes = v.getNodes(); Iterator<TreeImageDisplay> j = nodes.iterator(); TreeImageDisplay node; while (j.hasNext()) { node = j.next(); ids.add(((GroupData) node.getUserObject()).getId()); } } while (i.hasNext()) { a = i.next(); item = new JMenuItem(a); if (ids.size() > 0) { item.setEnabled(!ids.contains(a.getGroupId())); } else item.setEnabled(true); initMenuItem(item); items.add(item); } } else { ButtonGroup buttonGroup = new ButtonGroup(); long id = model.getSelectedGroupId(); while (i.hasNext()) { a = i.next(); item = new JCheckBoxMenuItem(a); item.setEnabled(true); item.setSelected(a.isSameGroup(id)); initMenuItem(item); buttonGroup.add(item); items.add(item); } } return items; } /** * Brings up the <code>Available Scripts</code> on top of the specified * component at the specified location. * * @param c The component that requested the pop-pup menu. * @param p The point at which to display the menu, relative to the * <code>component</code>'s coordinates. */ void showAvailableScriptsMenu(Component c, Point p) { if (p == null) { p = new Point(0, 0); }; if (c == null) { c = scriptButton; repaint(); } IconManager icons = IconManager.getInstance(); Collection<ScriptObject> scripts = model.getAvailableScripts(); if (CollectionUtils.isEmpty(scripts)) return; if (scriptsMenu == null) { scriptsMenu = new JPopupMenu(); JMenuItem refresh = new JMenuItem(icons.getIcon( IconManager.REFRESH)); refresh.setText("Reload Scripts"); refresh.setToolTipText("Reloads the existing scripts."); refresh.addMouseListener(new MouseAdapter() { /** * Launches the dialog when the user releases the mouse. * MouseAdapter#mouseReleased(MouseEvent) */ public void mouseReleased(MouseEvent e) { model.setAvailableScripts(null); scriptsMenu = null; Point p = e.getPoint(); if (e.getSource() != scriptButton) { p = null; } controller.reloadAvailableScripts(p, (Component) e.getSource()); } }); scriptsMenu.add(refresh); scriptsMenu.add(new JSeparator()); ScriptObject so; Map<String, JMenu> menus = new HashMap<String, JMenu>(); String path; Icon icon = icons.getIcon(IconManager.ANALYSIS); Icon largeIcon = icons.getIcon(IconManager.ANALYSIS_48); ActionListener listener = new ActionListener() { /** * Listens to the selection of a script. * @see ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent e) { ScriptMenuItem item = (ScriptMenuItem) e.getSource(); controller.handleScriptSelection(item.getScript()); } }; String name =""; //loop twice to check if we need to add the first element String refString = null; int count = 0; Iterator<ScriptObject> i = scripts.iterator(); String sep; String[] values; String value; while (i.hasNext()) { so = i.next(); value = ""; path = so.getPath(); if (path != null) { sep = FilenameUtils.getPrefix(path); if (path.startsWith(sep)) path = path.substring(1, path.length()); values = UIUtilities.splitString(path); if (values != null && values.length > 0) value = values[0]; } if (refString == null) { refString = value; count++; } else if (refString.equals(value)) count++; } int index = 0; if (scripts.size() == count) index++; i = scripts.iterator(); List<JMenuItem> topMenus = new ArrayList<JMenuItem>(); JMenu ref = null; while (i.hasNext()) { so = i.next(); path = so.getPath(); if (path != null) { sep = FilenameUtils.getPrefix(path); if (path.startsWith(sep)) path = path.substring(1, path.length()); values = UIUtilities.splitString(path); if (values != null) { for (int j = index; j < values.length; j++) { value = values[j]; JMenu v; String text = name+value; if (menus.containsKey(text)) { v = menus.get(text); } else { value = value.replace( ScriptObject.PARAMETER_SEPARATOR, ScriptObject.PARAMETER_UI_SEPARATOR); v = new JMenu(value); } if (ref == null) topMenus.add(v); else ref.add(v); ref = v; name+=values[j]; menus.put(name, v); } } } ScriptMenuItem item = new ScriptMenuItem(so); item.addActionListener(listener); if (ref != null) ref.add(item); else topMenus.add(item); name = ""; ref = null; if (so.getIcon() == null) { so.setIcon(icon); so.setIconLarge(largeIcon); } } Iterator<JMenuItem> j = topMenus.iterator(); while (j.hasNext()) { scriptsMenu.add(j.next()); } } scriptsMenu.show(c, p.x, p.y); } /** * Brings up the <code>ManagePopupMenu</code>on top of the specified * component at the specified location. * * @param c The component that requested the pop-up menu. * @param p The point at which to display the menu, relative to the * <code>component</code>'s coordinates. * @param index The index of the menu. */ void showCreateMenu(Component c, Point p, int index) { if (c == null) return; if (p == null) return; PopupMenu menu = new PopupMenu(controller, model, index); menu.show(c, p.x, p.y); } /** * Sets the selected flag of the {@link #fullScreen} component. * * @param selected The value to set. */ void setFullScreenSelected(boolean selected) { fullScreen.setSelected(selected); } /** * Invokes when loadings scripts. * * @param loading Passes <code>true</code> if there is an on-going loading. * <code>false</code> otherwise. */ void setScriptsLoadingStatus(boolean loading) { bar.remove(index); busyLabel.setBusy(loading); if (loading) bar.add(busyLabel, index); else bar.add(scriptButton, index); validate(); repaint(); } /** Sets the permissions level.*/ void setPermissions() { Browser browser = model.getSelectedBrowser(); if (browser != null && browser.getBrowserType() == Browser.ADMIN_EXPLORER) { menuButton.setEnabled(false); return; } menuButton.setEnabled(true); } /** Invokes when import is going on or finished.*/ void onImport() { //Clear first importFailureLabel.setText(""); importFailureLabel.setVisible(false); importSuccessLabel.setText(""); importSuccessLabel.setVisible(false); importLabel.setBusy(model.isImporting()); importLabel.setVisible(model.isImporting()); int n = model.getImportFailureCount(); StringBuffer buffer; if (n > 0) { buffer = new StringBuffer(); buffer.append(n); buffer.append(FAILED_TEXT); importFailureLabel.setText(buffer.toString()); importFailureLabel.setVisible(true); } n = model.getImportSuccessCount(); if (n > 0) { buffer = new StringBuffer(); buffer.append(n); buffer.append(IMPORTED_TEXT); importSuccessLabel.setText(buffer.toString()); importSuccessLabel.setVisible(true); } repaint(); } /** Clears the menus. */ void clearMenus() { scriptsMenu = null; //reset the menu. } }