Merge branch 'feature/JAL-3169cancelOverwrite' into
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 10 Dec 2018 13:55:12 +0000 (13:55 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 10 Dec 2018 13:55:12 +0000 (13:55 +0000)
JAL-3048dialogRunner2

Conflicts:
src/jalview/io/JalviewFileChooser.java

1  2 
src/jalview/io/JalviewFileChooser.java

@@@ -61,87 -57,8 +63,89 @@@ import javax.swing.plaf.basic.BasicFile
   * @author AMW
   *
   */
 -public class JalviewFileChooser extends JFileChooser
 +public class JalviewFileChooser extends JFileChooser implements DialogRunnerI,
 +    PropertyChangeListener
  {
++  private static final long serialVersionUID = 1L;
++
 +  private DialogRunnerI runner = new DialogRunner();
 +  
 +  File selectedFile = null;
 +
 +  /**
 +   * On user selecting a file to save to, this response is run to check if the
 +   * file already exists, and if so show a dialog to prompt for confirmation of
 +   * overwrite.
 +   */
 +  RunResponse overwriteCheck = new RunResponse(JalviewFileChooser.APPROVE_OPTION)
 +  {
 +    @Override
 +    public void run()
 +      {
 +          selectedFile = getSelectedFile();
 +      
 +          if (selectedFile == null)
 +          {
 +            // Workaround for Java 9,10 on OSX - no selected file, but there is a
 +            // filename typed in
 +            // TODO is this needed in Java 8 or 11?
 +            try
 +            {
 +              String filename = ((BasicFileChooserUI) getUI()).getFileName();
 +              if (filename != null && filename.length() > 0)
 +              {
 +                selectedFile = new File(getCurrentDirectory(), filename);
 +              }
 +            } catch (Throwable x)
 +            {
 +              System.err.println(
 +                      "Unexpected exception when trying to get filename.");
 +              x.printStackTrace();
 +            }
 +          }
 +          if (selectedFile == null)
 +          {
 +            setReturnValue(JalviewFileChooser.CANCEL_OPTION);
 +            return;
 +          }
 +          // JBP Note - this code was executed regardless of 'SAVE' being pressed
 +          // need to see if there were side effects
 +          if (getFileFilter() instanceof JalviewFileFilter)
 +          {
 +            JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();
 +      
 +            if (!jvf.accept(getSelectedFile()))
 +            {
 +              String withExtension = getSelectedFile() + "."
 +                      + jvf.getAcceptableExtension();
 +              setSelectedFile(new File(withExtension));
 +            }
 +          }
 +          // All good, so we continue to save
 +          setReturnValue(JalviewFileChooser.APPROVE_OPTION);
 +      
 +          // TODO: ENSURE THAT FILES SAVED WITH A ':' IN THE NAME ARE REFUSED AND THE
 +          // USER PROMPTED FOR A NEW FILENAME
 +          if (!Jalview.isJS())
 +          {
 +            if (getSelectedFile().exists())
 +            {
 +              // JAL-3048 - may not need to raise this for browser saves
 +              // yes/no cancel
 +              int confirm = JvOptionPane.showConfirmDialog(JalviewFileChooser.this,
 +                      MessageManager.getString("label.overwrite_existing_file"),
 +                      MessageManager.getString("label.file_already_exists"),
 +                 JvOptionPane.YES_NO_OPTION);
 +      
 +             if (confirm != JvOptionPane.YES_OPTION)
 +             {
 +                 setReturnValue(JalviewFileChooser.CANCEL_OPTION);
 +               }
 +             }
 +           }
 +      };
 +  };
 +
    /**
     * Factory method to return a file chooser that offers readable alignment file
     * formats
    public int showSaveDialog(Component parent) throws HeadlessException
    {
      this.setAccessory(null);
+     this.setSelectedFile(null);
+     return super.showSaveDialog(parent);
+   }
  
-     /*
-      * Save dialog is opened until user picks a file format 
-      */
-     /*
-     if (!runner.isRegistered(overwriteCheck))
+   /**
+    * 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)
      {
-       // first call for this instance
-       runner.setFirstResponse(overwriteCheck);
+       super.approveSelection();
+       return;
      }
-     else
 -    ourselectedFile = getSelectedFile();
++    selectedFile = getSelectedFile();
 -    if (ourselectedFile == null)
++    if (selectedFile == null)
      {
-       // reset response flags
-       runner.resetResponses();
+       // Workaround for Java 9,10 on OSX - no selected file, but there is a
+       // filename typed in
+       try
+       {
+         String filename = ((BasicFileChooserUI) getUI()).getFileName();
+         if (filename != null && filename.length() > 0)
+         {
 -          ourselectedFile = new File(getCurrentDirectory(), filename);
++          selectedFile = new File(getCurrentDirectory(), filename);
+         }
+       } catch (Throwable x)
+       {
+         System.err.println(
+                 "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
      }
- */
-  //   runner.addResponse(overwriteCheck);
- //    setDialogType(SAVE_DIALOG);
-     
-     // Java 9,10,11 on OSX - clear selected file so name isn't auto populated
-     this.setSelectedFile(null);
-  
-     int value = super.showSaveDialog(parent);//, MessageManager.getString("action.save"));
-     if (!Jalview.isJS())
 -    if (ourselectedFile == null)
++
++    if (selectedFile == null)
      {
-       runner.handleResponse(value);
+       return;
      }
-     return value;
+     if (getFileFilter() instanceof JalviewFileFilter)
+     {
+       JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();
 -      if (!jvf.accept(ourselectedFile))
++      if (!jvf.accept(selectedFile))
+       {
+         String withExtension = getSelectedFile().getName() + "."
+                 + jvf.getAcceptableExtension();
 -        ourselectedFile = (new File(getCurrentDirectory(), withExtension));
 -        setSelectedFile(ourselectedFile);
++        selectedFile = (new File(getCurrentDirectory(), withExtension));
++        setSelectedFile(selectedFile);
+       }
+     }
 -    if (ourselectedFile.exists())
++    if (selectedFile.exists())
++    {
++      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)
+       {
 -        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;
 -        }
++        return;
+       }
++    }
+     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
    {
+     private static final long serialVersionUID = 1L;
 -    private JList<String> list;
 +    JList<String> list;
  
-     public RecentlyOpened()
+     RecentlyOpened()
      {
-       String historyItems = jalview.bin.Cache.getProperty("RECENT_FILE");
+       String historyItems = Cache.getProperty("RECENT_FILE");
        StringTokenizer st;
        Vector<String> recent = new Vector<>();
  
                    .setValue(scroller.getHorizontalScrollBar().getMaximum());
          }
        });
      }
    }
 +
 +  @Override
 +  public DialogRunnerI addResponse(RunResponse action)
 +  {
 +    return runner.addResponse(action);
 +  }
 +
 +  /**
 +   * JalviewJS signals file selection by a property change event
 +   * for property "SelectedFile".  This methods responds to that by
 +   * running the response action for 'OK' in the dialog.
 +   * 
 +   * @param evt
 +   */
 +  @Override
 +  public void propertyChange(PropertyChangeEvent evt)
 +  {
 +    // TODO other properties need runners...
 +    switch (evt.getPropertyName())
 +    {
 +    case "SelectedFile": 
 +      runner.handleResponse(APPROVE_OPTION);
 +      break;
 +    }
 +  }
-       @Override
-       public void approveSelection() 
-       {
-               if (getDialogType() == SAVE_DIALOG && !Jalview.isJS()) 
-               {
-                       File selectedFile = getSelectedFile();
-                       if ((selectedFile != null) && selectedFile.exists()) 
-                       {
-                               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;
-                               }
-                       }
-               }
-               super.approveSelection();
-       }
  }