Merge branch 'feature/JAL-3169cancelOverwrite' into develop
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Feb 2019 15:51:18 +0000 (15:51 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Feb 2019 15:51:18 +0000 (15:51 +0000)
Conflicts:
src/jalview/io/JalviewFileChooser.java

1  2 
src/jalview/io/JalviewFileChooser.java

@@@ -30,8 -30,6 +30,8 @@@ import java.awt.Component
  import java.awt.Dimension;
  import java.awt.EventQueue;
  import java.awt.HeadlessException;
 +import java.awt.event.ActionEvent;
 +import java.awt.event.ActionListener;
  import java.awt.event.MouseAdapter;
  import java.awt.event.MouseEvent;
  import java.io.File;
@@@ -40,15 -38,14 +40,17 @@@ import java.util.List
  import java.util.StringTokenizer;
  import java.util.Vector;
  
 +import javax.swing.BoxLayout;
  import javax.swing.DefaultListCellRenderer;
 +import javax.swing.JCheckBox;
  import javax.swing.JFileChooser;
  import javax.swing.JList;
  import javax.swing.JPanel;
  import javax.swing.JScrollPane;
  import javax.swing.SpringLayout;
+ import javax.swing.SwingUtilities;
+ import javax.swing.border.TitledBorder;
 +import javax.swing.filechooser.FileFilter;
  import javax.swing.plaf.basic.BasicFileChooserUI;
  
  /**
  public class JalviewFileChooser extends JFileChooser
  {
    /**
 +   * backupfilesCheckBox = "Include backup files" checkbox includeBackupfiles =
 +   * flag set by checkbox
 +   */
 +  private JCheckBox backupfilesCheckBox = null;
 +
 +  protected boolean includeBackupFiles = false;
 +
 +  /**
     * Factory method to return a file chooser that offers readable alignment file
     * formats
     * 
    public static JalviewFileChooser forRead(String directory,
            String selected)
    {
 +    return JalviewFileChooser.forRead(directory, selected, false);
 +  }
 +
 +  public static JalviewFileChooser forRead(String directory,
 +          String selected, boolean allowBackupFiles)
 +  {
      List<String> extensions = new ArrayList<>();
      List<String> descs = new ArrayList<>();
      for (FileFormatI format : FileFormats.getInstance().getFormats())
          descs.add(format.getName());
        }
      }
 +
      return new JalviewFileChooser(directory,
              extensions.toArray(new String[extensions.size()]),
 -            descs.toArray(new String[descs.size()]), selected, true);
 +            descs.toArray(new String[descs.size()]), selected, true,
 +            allowBackupFiles);
    }
  
    /**
    JalviewFileChooser(String dir, String[] extensions, String[] descs,
            String selected, boolean allFiles)
    {
 +    this(dir, extensions, descs, selected, allFiles, false);
 +  }
 +
 +  public JalviewFileChooser(String dir, String[] extensions, String[] descs,
 +          String selected, boolean allFiles, boolean allowBackupFiles)
 +  {
      super(safePath(dir));
      if (extensions.length == descs.length)
      {
        {
          formats.add(new String[] { extensions[i], descs[i] });
        }
 -      init(formats, selected, allFiles);
 +      init(formats, selected, allFiles, allowBackupFiles);
      }
      else
      {
     */
    void init(List<String[]> formats, String selected, boolean allFiles)
    {
 +    init(formats, selected, allFiles, false);
 +  }
 +
 +  void init(List<String[]> formats, String selected, boolean allFiles,
 +          boolean allowBackupFiles)
 +  {
  
      JalviewFileFilter chosen = null;
  
      for (String[] format : formats)
      {
        JalviewFileFilter jvf = new JalviewFileFilter(format[0], format[1]);
 +      if (allowBackupFiles)
 +      {
 +        jvf.setParentJFC(this);
 +      }
        addChoosableFileFilter(jvf);
        if ((selected != null) && selected.equalsIgnoreCase(format[1]))
        {
        setFileFilter(chosen);
      }
  
 -    setAccessory(new RecentlyOpened());
 +    if (allowBackupFiles)
 +    {
 +      JPanel multi = new JPanel();
 +      multi.setLayout(new BoxLayout(multi, BoxLayout.PAGE_AXIS));
 +      if (backupfilesCheckBox == null)
 +      {
 +        try {
 +          includeBackupFiles = Boolean.parseBoolean(
 +                  Cache.getProperty(BackupFiles.NS + "_FC_INCLUDE"));
 +        } catch (Exception e)
 +        {
 +          includeBackupFiles = false;
 +        }
 +        backupfilesCheckBox = new JCheckBox(
 +                MessageManager.getString("label.include_backup_files"),
 +                includeBackupFiles);
 +        backupfilesCheckBox.setAlignmentX(Component.CENTER_ALIGNMENT);
 +        JalviewFileChooser jfc = this;
 +        backupfilesCheckBox.addActionListener(new ActionListener()
 +        {
 +          @Override
 +          public void actionPerformed(ActionEvent e)
 +          {
 +            includeBackupFiles = backupfilesCheckBox.isSelected();
 +            Cache.setProperty(BackupFiles.NS + "_FC_INCLUDE",
 +                    String.valueOf(includeBackupFiles));
 +
 +            FileFilter f = jfc.getFileFilter();
 +            // deselect the selected file if it's no longer choosable
 +            File selectedFile = jfc.getSelectedFile();
 +            if (selectedFile != null && !f.accept(selectedFile))
 +            {
 +              jfc.setSelectedFile(null);
 +            }
 +            // fake the OK button changing (to force it to upate)
 +            String s = jfc.getApproveButtonText();
 +            jfc.firePropertyChange(
 +                    APPROVE_BUTTON_TEXT_CHANGED_PROPERTY, null, s);
 +            // fake the file filter changing (its behaviour actually has)
 +            jfc.firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, null, f);
 +
 +            jfc.rescanCurrentDirectory();
 +            jfc.revalidate();
 +            jfc.repaint();
 +          }
 +        });
 +      }
 +      multi.add(new RecentlyOpened());
 +      multi.add(backupfilesCheckBox);
 +      setAccessory(multi);
 +    }
 +    else
 +    {
 +      // set includeBackupFiles=false to avoid other file choosers from picking
 +      // up backup files (Just In Case)
 +      includeBackupFiles = false;
 +      setAccessory(new RecentlyOpened());
 +    }
    }
  
    @Override
    public int showSaveDialog(Component parent) throws HeadlessException
    {
      this.setAccessory(null);
+     this.setSelectedFile(null);
+     return super.showSaveDialog(parent);
+   }
  
-     setDialogType(SAVE_DIALOG);
+   /**
+    * If doing a Save, and an existing file is chosen or entered, prompt for
+    * confirmation of overwrite. Proceed if Yes, else leave the file chooser
+    * open.
+    * 
+    * @see https://stackoverflow.com/questions/8581215/jfilechooser-and-checking-for-overwrite
+    */
+   @Override
+   public void approveSelection()
+   {
+     if (getDialogType() != SAVE_DIALOG)
+     {
+       super.approveSelection();
+       return;
+     }
  
-     this.setSelectedFile(null);
-     int ret = showDialog(parent, MessageManager.getString("action.save"));
      ourselectedFile = getSelectedFile();
  
-     if (getSelectedFile() == null)
+     if (ourselectedFile == null)
      {
        // Workaround for Java 9,10 on OSX - no selected file, but there is a
        // filename typed in
                  "Unexpected exception when trying to get filename.");
          x.printStackTrace();
        }
+       // TODO: ENSURE THAT FILES SAVED WITH A ':' IN THE NAME ARE REFUSED AND
+       // THE
+       // USER PROMPTED FOR A NEW FILENAME
      }
      if (ourselectedFile == null)
      {
-       return JalviewFileChooser.CANCEL_OPTION;
+       return;
      }
      if (getFileFilter() instanceof JalviewFileFilter)
      {
        JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();
        }
      }
  
-     // TODO: ENSURE THAT FILES SAVED WITH A ':' IN THE NAME ARE REFUSED AND THE
-     // USER PROMPTED FOR A NEW FILENAME.
-     // DO NOT need to confirm file overwrite if using backup files (the files
-     // aren't being overwritten!)
-     if ((ret == JalviewFileChooser.APPROVE_OPTION)
-             && ourselectedFile.exists() && (!BackupFiles.getEnabled()))
+     if (ourselectedFile.exists())
 -      {
 -        int confirm = JvOptionPane.showConfirmDialog(this,
 -                MessageManager.getString("label.overwrite_existing_file"),
 -                MessageManager.getString("label.file_already_exists"),
 -                JvOptionPane.YES_NO_OPTION);
 +    {
-       int confirm = JvOptionPane.showConfirmDialog(parent,
++      int confirm = JvOptionPane.showConfirmDialog(this,
 +              MessageManager.getString("label.overwrite_existing_file"),
 +              MessageManager.getString("label.file_already_exists"),
 +              JvOptionPane.YES_NO_OPTION);
  
 -        if (confirm != JvOptionPane.YES_OPTION)
 -        {
 -          return;
 -        }
 +      if (confirm != JvOptionPane.YES_OPTION)
 +      {
-         ret = JalviewFileChooser.CANCEL_OPTION;
++        return;
        }
 +    }
  
-     return ret;
+     super.approveSelection();
    }
  
    void recentListSelectionChanged(Object selection)
      }
    }
  
+   /**
+    * A panel to set as the 'accessory' component to the file chooser dialog,
+    * holding a list of recently opened files (if any). These are held as a
+    * tab-separated list of file paths under key <code>RECENT_FILE</code> in
+    * <code>.jalview_properties</code>. A click in the list calls a method in
+    * JalviewFileChooser to set the chosen file as the selection.
+    */
    class RecentlyOpened extends JPanel
    {
-     JList list;
+     private static final long serialVersionUID = 1L;
  
-     public RecentlyOpened()
-     {
+     private JList<String> list;
  
-       String historyItems = jalview.bin.Cache.getProperty("RECENT_FILE");
+     RecentlyOpened()
+     {
+       String historyItems = Cache.getProperty("RECENT_FILE");
        StringTokenizer st;
-       Vector recent = new Vector();
+       Vector<String> recent = new Vector<>();
  
        if (historyItems != null)
        {
          st = new StringTokenizer(historyItems, "\t");
          while (st.hasMoreTokens())
          {
-           recent.addElement(st.nextElement());
+           recent.addElement(st.nextToken());
          }
        }
  
-       list = new JList(recent);
+       list = new JList<>(recent);
  
        DefaultListCellRenderer dlcr = new DefaultListCellRenderer();
        dlcr.setHorizontalAlignment(DefaultListCellRenderer.RIGHT);
          }
        });
  
-       this.setBorder(new javax.swing.border.TitledBorder(
+       this.setBorder(new TitledBorder(
                MessageManager.getString("label.recently_opened")));
  
        final JScrollPane scroller = new JScrollPane(list);
        layout.putConstraint(SpringLayout.NORTH, scroller, 5,
                SpringLayout.NORTH, this);
  
-       if (new Platform().isAMac())
+       if (Platform.isAMac())
        {
          scroller.setPreferredSize(new Dimension(500, 100));
        }
  
        this.add(scroller);
  
-       javax.swing.SwingUtilities.invokeLater(new Runnable()
+       SwingUtilities.invokeLater(new Runnable()
        {
          @Override
          public void run()
                    .setValue(scroller.getHorizontalScrollBar().getMaximum());
          }
        });
      }
    }
  }