Merge branch 'develop' into developtomchmmer
[jalview.git] / src / jalview / gui / Preferences.java
index 7c0ac95..a0a7511 100755 (executable)
@@ -22,14 +22,11 @@ package jalview.gui;
 
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.bin.Cache;
-import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenMarkovModel;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceI;
 import jalview.gui.Help.HelpId;
 import jalview.gui.StructureViewer.ViewerType;
-import jalview.hmmer.HMMBuildThread;
+import jalview.hmmer.HmmerCommand;
+import jalview.io.BackupFiles;
+import jalview.io.BackupFilesPresetEntry;
 import jalview.io.FileFormatI;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
@@ -42,6 +39,7 @@ import jalview.urls.UrlLinkTableModel;
 import jalview.urls.api.UrlProviderFactoryI;
 import jalview.urls.api.UrlProviderI;
 import jalview.urls.desktop.DesktopUrlProviderFactory;
+import jalview.util.FileUtils;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.util.UrlConstants;
@@ -54,17 +52,19 @@ import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
 import java.awt.event.MouseEvent;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Scanner;
 
 import javax.help.HelpSetException;
 import javax.swing.JColorChooser;
 import javax.swing.JFileChooser;
 import javax.swing.JInternalFrame;
 import javax.swing.JPanel;
+import javax.swing.JTextField;
 import javax.swing.ListSelectionModel;
 import javax.swing.RowFilter;
 import javax.swing.RowSorter;
@@ -88,6 +88,15 @@ import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
  */
 public class Preferences extends GPreferences
 {
+  // suggested list delimiter character
+  public static final String COMMA = ",";
+
+  public static final String HMMSEARCH_SEQCOUNT = "HMMSEARCH_SEQCOUNT";
+
+  public static final String HMMINFO_GLOBAL_BACKGROUND = "HMMINFO_GLOBAL_BACKGROUND";
+
+  public static final String HMMALIGN_TRIM_TERMINI = "HMMALIGN_TRIM_TERMINI";
+
   public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME";
 
   public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA";
@@ -112,7 +121,7 @@ public class Preferences extends GPreferences
   
   public static final String HMMER_PATH = "HMMER_PATH";
 
-  public static final String HMMSEARCH_DB_PATHS = "HMMSEARCH_DB_PATHS";
+  public static final String CYGWIN_PATH = "CYGWIN_PATH";
 
   public static final String HMMSEARCH_DBS = "HMMSEARCH_DBS";
 
@@ -122,6 +131,14 @@ public class Preferences extends GPreferences
 
   public static final String SHOW_OCCUPANCY = "SHOW_OCCUPANCY";
 
+  public static final String SHOW_OV_HIDDEN_AT_START = "SHOW_OV_HIDDEN_AT_START";
+
+  public static final String USE_LEGACY_GAP = "USE_LEGACY_GAP";
+
+  public static final String GAP_COLOUR = "GAP_COLOUR";
+
+  public static final String HIDDEN_COLOUR = "HIDDEN_COLOUR";
+
   private static final int MIN_FONT_SIZE = 1;
 
   private static final int MAX_FONT_SIZE = 30;
@@ -173,8 +190,6 @@ public class Preferences extends GPreferences
 
   JInternalFrame frame;
 
-  DasSourceBrowser dasSource;
-
   private WsPreferences wsPrefs;
 
   private OptionsParam promptEachTimeOpt = new OptionsParam(
@@ -195,8 +210,6 @@ public class Preferences extends GPreferences
     super();
     frame = new JInternalFrame();
     frame.setContentPane(this);
-    dasSource = new DasSourceBrowser();
-    dasTab.add(dasSource, BorderLayout.CENTER);
     wsPrefs = new WsPreferences();
     wsTab.add(wsPrefs, BorderLayout.CENTER);
     int width = 500, height = 450;
@@ -214,30 +227,59 @@ public class Preferences extends GPreferences
     /*
      * Set HMMER tab defaults
      */
-    trimTermini.setSelected(Cache.getDefault("TRIM_TERMINI", false));
-    isHMMERInstalled
-            .setSelected(Cache.getDefault("HMMER_INSTALLED", false));
-    if (Cache.getDefault("USE_UNIPROT", false))
+    hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
+    if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
     {
-      uniprot.setSelected(true);
+      hmmerBackgroundUniprot.setSelected(true);
     }
     else
     {
-      alignment.setSelected(true);
+      hmmerBackgroundAlignment.setSelected(true);
     }
-    numberOfSequencesToKeepField
-            .setText(Cache.getProperty("SEQUENCES_TO_KEEP"));
-    installationLocation.setEnabled(isHMMERInstalled.isSelected());
-    hmmerPath.setEnabled(isHMMERInstalled.isSelected());
+    hmmerSequenceCount
+            .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
     hmmerPath.setText(Cache.getProperty(HMMER_PATH));
     hmmerPath.addActionListener(new ActionListener()
     {
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        validateHMMERPath();
+        validateHmmerPath();
+      }
+    });
+    hmmerPath.addFocusListener(new FocusAdapter()
+    {
+      @Override
+      public void focusLost(FocusEvent e)
+      {
+        validateHmmerPath();
       }
     });
+    if (cygwinPath != null)
+    {
+      String path = Cache.getProperty(CYGWIN_PATH);
+      if (path == null)
+      {
+        path = FileUtils.getPathTo("bash");
+      }
+      cygwinPath.setText(path);
+      cygwinPath.addActionListener(new ActionListener()
+      {
+        @Override
+        public void actionPerformed(ActionEvent e)
+        {
+          validateCygwinPath();
+        }
+      });
+      cygwinPath.addFocusListener(new FocusAdapter()
+      {
+        @Override
+        public void focusLost(FocusEvent e)
+        {
+          validateCygwinPath();
+        }
+      });
+    }
 
     /*
      * Set Visual tab defaults
@@ -353,6 +395,21 @@ public class Preferences extends GPreferences
             Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
 
     /*
+     * Set overview panel defaults
+     */
+    gapColour.setBackground(
+            Cache.getDefaultColour(GAP_COLOUR,
+                    jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP));
+    hiddenColour.setBackground(
+            Cache.getDefaultColour(HIDDEN_COLOUR,
+                    jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN));
+    useLegacyGap.setSelected(Cache.getDefault(USE_LEGACY_GAP, false));
+    gapLabel.setEnabled(!useLegacyGap.isSelected());
+    gapColour.setEnabled(!useLegacyGap.isSelected());
+    showHiddenAtStart
+            .setSelected(Cache.getDefault(SHOW_OV_HIDDEN_AT_START, false));
+
+    /*
      * Set Structure tab defaults.
      */
     final boolean structSelected = Cache.getDefault(STRUCT_FROM_PDB, false);
@@ -546,8 +603,10 @@ public class Preferences extends GPreferences
     autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false));
     userIdWidth.setEnabled(!autoIdWidth.isSelected());
     userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
-    Integer wi = Cache.getIntegerProperty("FIGURE_USERIDWIDTH");
+    Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
     userIdWidth.setText(wi == null ? "" : wi.toString());
+    // TODO: refactor to use common enum via FormatAdapter and allow extension
+    // for new flat file formats
     blcjv.setSelected(Cache.getDefault("BLC_JVSUFFIX", true));
     clustaljv.setSelected(Cache.getDefault("CLUSTAL_JVSUFFIX", true));
     fastajv.setSelected(Cache.getDefault("FASTA_JVSUFFIX", true));
@@ -569,6 +628,12 @@ public class Preferences extends GPreferences
 
     annotations_actionPerformed(null); // update the display of the annotation
                                        // settings
+    
+    
+    /*
+     * Set Backups tab defaults
+     */
+    loadLastSavedBackupsOptions();
   }
 
   /**
@@ -681,42 +746,50 @@ public class Preferences extends GPreferences
     /*
      * Save HMMER settings
      */
-    Cache.applicationProperties.setProperty("TRIM_TERMINI",
-            Boolean.toString(trimTermini.isSelected()));
-    Cache.applicationProperties.setProperty("USE_UNIPROT",
-            Boolean.toString(uniprot.isSelected()));
-    Cache.applicationProperties.setProperty("SEQUENCES_TO_KEEP",
-            numberOfSequencesToKeepField.getText());
-    Cache.applicationProperties.setProperty(HMMER_PATH,
-            hmmerPath.getText());
-    boolean hmmerInstalled = isHMMERInstalled.isSelected();
-    Cache.applicationProperties.setProperty("HMMER_INSTALLED",
-            Boolean.toString(hmmerInstalled));
-    boolean hmmerFunctioning = validateHMMERPath(false);
-    Cache.applicationProperties.setProperty("HMMER_FUNCTIONING",
-            Boolean.toString(hmmerFunctioning));
+    Cache.applicationProperties.setProperty(HMMALIGN_TRIM_TERMINI,
+            Boolean.toString(hmmrTrimTermini.isSelected()));
+    Cache.applicationProperties.setProperty(HMMINFO_GLOBAL_BACKGROUND,
+            Boolean.toString(hmmerBackgroundUniprot.isSelected()));
+    Cache.applicationProperties.setProperty(HMMSEARCH_SEQCOUNT,
+            hmmerSequenceCount.getText());
+    Cache.setOrRemove(HMMER_PATH, hmmerPath.getText());
+    if (cygwinPath != null)
+    {
+      Cache.setOrRemove(CYGWIN_PATH, cygwinPath.getText());
+    }
     AlignFrame[] frames = Desktop.getAlignFrames();
-    boolean hmmerStatus = hmmerFunctioning && hmmerInstalled ? true : false;
-    for (AlignFrame frame : frames)
+    if (frames != null && frames.length > 0)
     {
-      frame.updateHMMERStatus(hmmerStatus);
+      for (AlignFrame f : frames)
+      {
+        f.updateHMMERStatus();
+      }
     }
     
-    
-    trimTermini.setSelected(Cache.getDefault("TRIM_TERMINI", false));
-    if (Cache.getDefault("USE_UNIPROT", false))
+    hmmrTrimTermini.setSelected(Cache.getDefault(HMMALIGN_TRIM_TERMINI, false));
+    if (Cache.getDefault(HMMINFO_GLOBAL_BACKGROUND, false))
     {
-      uniprot.setSelected(true);
+      hmmerBackgroundUniprot.setSelected(true);
     }
     else
     {
-      alignment.setSelected(true);
+      hmmerBackgroundAlignment.setSelected(true);
     }
-    numberOfSequencesToKeepField
-            .setText(Cache.getProperty("SEQUENCES_TO_KEEP"));
+    hmmerSequenceCount
+            .setText(Cache.getProperty(HMMSEARCH_SEQCOUNT));
     hmmerPath.setText(Cache.getProperty(HMMER_PATH));
 
     /*
+     * Save Overview settings
+     */
+    Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
+    Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
+    Cache.applicationProperties.setProperty(USE_LEGACY_GAP,
+            Boolean.toString(useLegacyGap.isSelected()));
+    Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START,
+            Boolean.toString(showHiddenAtStart.isSelected()));
+
+    /*
      * Save Structure settings
      */
     Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN,
@@ -835,7 +908,7 @@ public class Preferences extends GPreferences
     Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH",
             Boolean.toString(autoIdWidth.isSelected()));
     userIdWidth_actionPerformed();
-    Cache.applicationProperties.setProperty("FIGURE_USERIDWIDTH",
+    Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH",
             userIdWidth.getText());
 
     /*
@@ -848,8 +921,31 @@ public class Preferences extends GPreferences
     Cache.applicationProperties.setProperty("PAD_GAPS",
             Boolean.toString(padGaps.isSelected()));
 
-    dasSource.saveProperties(Cache.applicationProperties);
     wsPrefs.updateAndRefreshWsMenuConfig(false);
+
+    /*
+     * Save Backups settings
+     */
+    Cache.applicationProperties.setProperty(BackupFiles.ENABLED,
+            Boolean.toString(enableBackupFiles.isSelected()));
+    int preset = getComboIntStringKey(backupfilesPresetsCombo);
+    Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset));
+
+    if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM)
+    {
+      BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry();
+      BackupFilesPresetEntry.backupfilesPresetEntriesValues.put(
+              BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE);
+      Cache.applicationProperties
+              .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG,
+                      customBFPE.toString());
+    }
+
+    BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues
+            .get(preset);
+    Cache.applicationProperties.setProperty(
+            BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
+
     Cache.saveProperties();
     Desktop.instance.doConfigureStructurePrefs();
     try
@@ -873,14 +969,6 @@ public class Preferences extends GPreferences
       structureTab.requestFocusInWindow();
       return false;
     }
-    if (isHMMERInstalled.isSelected())
-    {
-      if (!validateHMMER())
-      {
-        hmmerTab.requestFocusInWindow();
-        return false;
-      }
-    }
     return true;
   }
 
@@ -891,13 +979,6 @@ public class Preferences extends GPreferences
 
   }
 
-  @Override
-  protected boolean validateHMMER()
-  {
-    return validateHMMERPath();
-
-  }
-
   /**
    * DOCUMENT ME!
    */
@@ -1138,6 +1219,63 @@ public class Preferences extends GPreferences
   }
 
   @Override
+  public void gapColour_actionPerformed(JPanel gap)
+  {
+    if (!useLegacyGap.isSelected())
+    {
+      Color col = JColorChooser.showDialog(this,
+              MessageManager.getString("label.select_gap_colour"),
+              gapColour.getBackground());
+      if (col != null)
+      {
+        gap.setBackground(col);
+      }
+      gap.repaint();
+    }
+  }
+
+  @Override
+  public void hiddenColour_actionPerformed(JPanel hidden)
+  {
+    Color col = JColorChooser.showDialog(this,
+            MessageManager.getString("label.select_hidden_colour"),
+            hiddenColour.getBackground());
+    if (col != null)
+    {
+      hidden.setBackground(col);
+    }
+    hidden.repaint();
+  }
+
+  @Override
+  protected void useLegacyGaps_actionPerformed(ActionEvent e)
+  {
+    boolean enabled = useLegacyGap.isSelected();
+    if (enabled)
+    {
+      gapColour.setBackground(
+              jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_LEGACY_GAP);
+    }
+    else
+    {
+      gapColour.setBackground(
+              jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_GAP);
+    }
+    gapColour.setEnabled(!enabled);
+    gapLabel.setEnabled(!enabled);
+  }
+
+  @Override
+  protected void resetOvDefaults_actionPerformed(ActionEvent e)
+  {
+    useLegacyGap.setSelected(false);
+    useLegacyGaps_actionPerformed(null);
+    showHiddenAtStart.setSelected(false);
+    hiddenColour.setBackground(
+            jalview.renderer.OverviewResColourFinder.OVERVIEW_DEFAULT_HIDDEN);
+  }
+
+  @Override
   protected void userIdWidth_actionPerformed()
   {
     try
@@ -1192,94 +1330,31 @@ public class Preferences extends GPreferences
   }
   
   /**
-   * Returns true if hmmer path contains the necessary valid executables, else
-   * show an error dialog (if showing dialog).
+   * Returns true if the given text field contains a path to a folder that
+   * contains an executable with the given name, else false (after showing a
+   * warning dialog). The executable name will be tried with .exe appended if not
+   * found.
+   * 
+   * @param textField
+   * @param executable
    */
-  private boolean validateHMMERPath(boolean showDialog)
+  protected boolean validateExecutablePath(JTextField textField, String executable)
   {
-    int missing = 0;
-    String message = "";
-    String folder = hmmerPath.getText().trim();
+    String folder = textField.getText().trim();
+
+    if (FileUtils.getExecutable(executable, folder) != null)
+    {
+      return true;
+    }
     if (folder.length() > 0)
     {
-      File f = new File(folder);
-      if (!f.exists())
-      {
-        if (showDialog)
-        {
-          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
-                MessageManager.getString("label.folder_not_exists"),
-                MessageManager.getString("label.invalid_folder"),
-                JvOptionPane.ERROR_MESSAGE);
-        }
-        return false;
-      }
-      AlignmentI alignment = new Alignment(
-              new SequenceI[]
-      { new Sequence("test", "WLWL", 0, 3) });
-      if (canExecute(folder + "/hmmbuild"))
-        {
-        validateHMMBuild(alignment);
-        }
-      else
-      {
-        message += MessageManager.getString("label.hmmbuild_not_found")
-                + "\n";
-        missing++;
-      }
-
-
-      if (canExecute(folder + "/hmmalign"))
-        {
-
-        }
-      else
-      {
-        message += MessageManager.getString("label.hmmalign_not_found")
-                + "\n";
-        missing++;
-      }
-
-
-      if (canExecute(folder + "/hmmsearch"))
-        {
-
-        }
-      else
-      {
-        message += MessageManager.getString("label.hmmsearch_not_found")
-                + "\n";
-        missing++;
-      }
-      }
-
-      if (missing > 0)
-      {
-        if (missing < 3)
-        {
-          if (showDialog)
-          {
-            JvOptionPane.showInternalMessageDialog(Desktop.desktop, message,
-                  MessageManager.getString("label.invalid_folder"),
-                  JvOptionPane.ERROR_MESSAGE);
-          }
-          return false;
-        }
-        else
-        {
-          if (showDialog)
-          {
-            JvOptionPane.showInternalMessageDialog(Desktop.desktop,
-                  MessageManager.getString("label.no_binaries"),
-                  MessageManager.getString("label.invalid_folder"),
-                  JvOptionPane.ERROR_MESSAGE);
-          }
-
-          return false;
-        }
-      }
-
-    return true;
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+              MessageManager.formatMessage("label.executable_not_found",
+                      executable),
+              MessageManager.getString("label.invalid_folder"),
+              JvOptionPane.ERROR_MESSAGE);
+    }
+    return false;
   }
 
   /**
@@ -1306,57 +1381,6 @@ public class Preferences extends GPreferences
   }
 
   /**
-   * Runs hmmbuild to check if it is working. While doing this it parses the
-   * version of HMMER.
-   * 
-   * @param frame
-   * @return
-   */
-  public boolean validateHMMBuild(AlignmentI alignment)
-  {
-    HMMBuildThread hmmbuild = new HMMBuildThread(alignment);
-    hmmbuild.hmmbuildWaitTillComplete();
-    SequenceI hmmSeq = alignment.getSequenceAt(0);
-    HiddenMarkovModel hmm;
-    if (hmmSeq.isHMMConsensusSequence() && hmmSeq.getHMM() != null)
-    {
-      hmm = hmmSeq.getHMM();
-
-      if (hmm.getNumberOfSymbols() < 1)
-      {
-        return false;
-      }
-    }
-    else
-    {
-      return false;
-    }
-
-    String header = hmm.getFileHeader();
-    if (header == null)
-    {
-      return false;
-    }
-    else
-    {
-      Scanner scanner = new Scanner(header);
-      scanner.next();
-      String string = scanner.next();
-      String version = string.substring(1);
-      Cache.setProperty("HMMER_VERSION", version);
-      scanner.close();
-
-    }
-    return true;
-  }
-
-
-  private boolean validateHMMERPath()
-  {
-    return validateHMMERPath(true);
-  }
-
-  /**
    * If Chimera is selected, check it can be found on default or user-specified
    * path, if not show a warning/help dialog.
    */
@@ -1403,6 +1427,18 @@ public class Preferences extends GPreferences
     }
   }
 
+  @Override
+  protected void validateHmmerPath()
+  {
+    validateExecutablePath(hmmerPath, HmmerCommand.HMMBUILD);
+  }
+
+  @Override
+  protected void validateCygwinPath()
+  {
+    validateExecutablePath(cygwinPath, "run");
+  }
+
   public class OptionsParam
   {
     private String name;