/* *------------------------------------------------------------------------------ * 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.util.ui; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JRootPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import omero.gateway.SecurityContext; import omero.log.LogMessage; import org.openmicroscopy.shoola.env.config.Registry; import org.openmicroscopy.shoola.env.data.OmeroImageService; import org.openmicroscopy.shoola.env.data.model.ScriptObject; import org.openmicroscopy.shoola.env.ui.UserNotifier; import org.openmicroscopy.shoola.util.CommonsLangUtils; import org.openmicroscopy.shoola.util.filter.file.CppFilter; import org.openmicroscopy.shoola.util.filter.file.CustomizedFileFilter; import org.openmicroscopy.shoola.util.filter.file.JavaFilter; import org.openmicroscopy.shoola.util.filter.file.MatlabFilter; import org.openmicroscopy.shoola.util.filter.file.PythonFilter; import org.openmicroscopy.shoola.util.ui.IconManager; import org.openmicroscopy.shoola.util.ui.MessageBox; import org.openmicroscopy.shoola.util.ui.TitlePanel; import org.openmicroscopy.shoola.util.ui.UIUtilities; import org.openmicroscopy.shoola.util.ui.filechooser.GenericFileChooser; /** * Dialog used to select the scripts to upload to the server. * * @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 3.0-Beta4 */ public class ScriptUploaderDialog extends JDialog implements ActionListener { /** Bound property indicating to upload the script. */ public static final String UPLOAD_SCRIPT_PROPERTY = "uploadScript"; /** Property name for file selection change */ public static final String FILESELECTION_PROPERTY = "SelectedFileChangedProperty"; /** * The size of the invisible components used to separate buttons * horizontally. */ private static final Dimension H_SPACER_SIZE = new Dimension(3, 10); /** The title of the dialog. */ private static final String TITLE = "Upload Script"; /** The text of the dialog. */ private static final String TEXT = "Select the script to upload"; /** Action ID indicating to upload the script to the server. */ private static final int SAVE = 0; /** Action ID indicating to close and disposes of the dialog. */ private static final int CANCEL = 1; /** Collection of supported filters. */ private static final List<CustomizedFileFilter> FILTERS; static { FILTERS = new ArrayList<CustomizedFileFilter>(); FILTERS.add(new CppFilter()); FILTERS.add(new JavaFilter()); FILTERS.add(new MatlabFilter()); FILTERS.add(new PythonFilter()); } /** Chooser used to select the file. */ private GenericFileChooser chooser; /** * Replaces the <code>ApproveButton</code> provided by the * {@link JFileChooser} class. */ private JButton saveButton; /** * Replaces the <code>CancelButton</code> provided by the * {@link JFileChooser} class. */ private JButton cancelButton; /** The location of the script. */ private JTextField location; /** Display the available location. */ private JButton locationFinder; /** Existing scripts */ private List<ScriptObject> scripts; /** The available folders. */ private List<String> folders; /** The menu displaying the list of available folders. */ private JPopupMenu menu; /** Helper reference.*/ private Registry context; /** Initializes the components. */ private void initComponents() { folders = new ArrayList<String>(); chooser = new GenericFileChooser(); chooser.setAcceptAllFileFilterUsed(true); Iterator<CustomizedFileFilter> i = FILTERS.iterator(); while (i.hasNext()) { chooser.addChoosableFileFilter(i.next()); } chooser.setControlButtonsAreShown(false); chooser.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (FILESELECTION_PROPERTY.equals(evt.getPropertyName())) { File f = chooser.getSelectedFile(); saveButton.setEnabled(f != null && f.isFile()); } } }); saveButton = new JButton("Upload"); saveButton.setToolTipText( UIUtilities.formatToolTipText("Upload the selected script " + "to the server.")); saveButton.addActionListener(this); saveButton.setActionCommand(""+SAVE); cancelButton = new JButton("Cancel"); cancelButton.setToolTipText( UIUtilities.formatToolTipText("Closes the dialog.")); cancelButton.addActionListener(this); cancelButton.setActionCommand(""+CANCEL); location = new JTextField(); locationFinder = new JButton("Find Folder"); locationFinder.setToolTipText("List the existing folders."); locationFinder.setEnabled(folders.size() > 0); locationFinder.addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { showFolderList(e.getPoint()); } }); saveButton.setEnabled(false); } /** * Builds and lays out the controls. * * @return See above. */ private JPanel buildControls() { JPanel controls = new JPanel(); controls.setLayout(new BorderLayout()); controls.add(buildToolbar(), BorderLayout.CENTER); JPanel folder = new JPanel(); folder.setLayout(new BorderLayout()); JLabel l = new JLabel("Upload into Folder:"); folder.add(l, BorderLayout.WEST); folder.add(location, BorderLayout.CENTER); folder.add(locationFinder, BorderLayout.EAST); JPanel p = new JPanel(); p.setLayout(new GridBagLayout()); p.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.weightx = 1; c.weighty = 1; c.fill = GridBagConstraints.BOTH; p.add(chooser, c); c.gridy++; c.weighty = 0; c.fill = GridBagConstraints.HORIZONTAL; p.add(folder, c); c.gridy++; p.add(controls, c); return p; } /** Builds and lays out the UI. */ private void buildGUI() { IconManager icons = IconManager.getInstance(); TitlePanel tp = new TitlePanel(TITLE, TEXT, icons.getIcon(IconManager.UPLOAD_SCRIPT_48)); Container c = getContentPane(); c.setLayout(new BorderLayout(0, 0)); c.add(tp, BorderLayout.NORTH); c.add(buildControls(), BorderLayout.CENTER); if (JDialog.isDefaultLookAndFeelDecorated()) { boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations(); if (supportsWindowDecorations) getRootPane().setWindowDecorationStyle( JRootPane.FILE_CHOOSER_DIALOG); } } /** * Builds the tool bar. * * @return See above */ private JPanel buildToolbar() { JPanel bar = new JPanel(); bar.setBorder(null); bar.add(cancelButton); bar.add(Box.createRigidArea(H_SPACER_SIZE)); bar.add(saveButton); JPanel p = UIUtilities.buildComponentPanelRight(bar); p.setOpaque(true); return p; } /** Closes and disposes. */ private void close() { setVisible(false); dispose(); } /** Uploads the script to the server. */ private void upload() { File f = chooser.getSelectedFile(); Iterator<CustomizedFileFilter> i = FILTERS.iterator(); boolean supported = false; CustomizedFileFilter filter; String mimeType = null; while (i.hasNext()) { filter = i.next(); if (filter.accept(f)) { supported = true; mimeType = filter.getMIMEType(); break; } } if (!supported) { UserNotifier un = context.getUserNotifier(); un.notifyInfo(TITLE, "The selected script does not seem to " + "be supported."); return; } if (scripts != null) { boolean exists = false; ScriptObject tmp = new ScriptObject(-1, "", f.getName()); String name = tmp.getDisplayedName(); for(ScriptObject s : scripts) { String value = s.getDisplayedName(); if (value.equals(name)) { exists = true; break; } } if (exists) { MessageBox box = new MessageBox((JFrame) getOwner(), TITLE, "A script with the same name already exists in " + "the system.\n" + "Do you still want to upload the script?"); if (box.centerMsgBox() == MessageBox.NO_OPTION) return; } } ScriptObject script = new ScriptObject(-1, f.getAbsolutePath(), f.getName()); script.setMIMEType(mimeType); String value = location.getText(); if (CommonsLangUtils.isNotEmpty(value)) script.setFolder(value.trim()); else script.setFolder(f.getParentFile().getName()); IconManager icons = IconManager.getInstance(); script.setIcon(icons.getIcon(IconManager.UPLOAD_SCRIPT)); firePropertyChange(UPLOAD_SCRIPT_PROPERTY, null, script); close(); } /** Sets the properties of the dialog. */ private void setProperties() { setTitle(TITLE); setModal(true); } /** * Displays the existing folders. * * @param p The location of the mouse click. */ private void showFolderList(Point p) { if (menu == null) { menu = new JPopupMenu(); int index = CANCEL+1; Iterator<String> i = folders.iterator(); JMenuItem item; while (i.hasNext()) { item = new JMenuItem(i.next()); item.setActionCommand(""+index); item.addActionListener(this); index++; menu.add(item); } } menu.show(locationFinder, p.x, p.y); } /** * Creates a new instance. * * @param owner The owner of the dialog. * @param context Reference to the context. * @param ctx The {@link SecurityContext} */ public ScriptUploaderDialog(JFrame owner, Registry context, SecurityContext ctx) { super(owner); this.context = context; setProperties(); initComponents(); buildGUI(); loadScripts(ctx); pack(); } /** * Set the scripts which already exist on the server * @param scripts The List of {@link ScriptObject}s */ void setScripts(List<ScriptObject> scripts) { this.scripts = scripts; for (ScriptObject s : scripts) { String folder = s.getFolder(); if(folder.startsWith("/")) folder = folder.replaceFirst("/", ""); if(folder.endsWith("/")) folder = folder.substring(0, folder.length()-1); if (!folders.contains(folder)) folders.add(folder); } locationFinder.setEnabled(!folders.isEmpty()); } /** * Starts an async call to load the existing scripts * from the server * @param The {@link SecurityContext} */ private void loadScripts(final SecurityContext ctx) { Runnable r = new Runnable() { @Override public void run() { try { OmeroImageService svc = context.getImageService(); final List<ScriptObject> scripts = svc .loadAvailableScripts(ctx, -1); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { ScriptUploaderDialog.this.setScripts(scripts); } }); } catch (Exception e) { LogMessage m = new LogMessage("Couldn't load scripts", e); context.getLogger().error(ScriptUploaderDialog.this, m); } } }; new Thread(r).start(); } /** * Uploads the script or closes the dialog. * @see ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent e) { int index = Integer.parseInt(e.getActionCommand()); switch (index) { case CANCEL: close(); break; case SAVE: upload(); break; default: if (e.getSource() instanceof JMenuItem) { JMenuItem item = (JMenuItem) e.getSource(); location.setText(item.getText()); } } } }