JAL-1452 nucleotide/protein default colour; JAL-845 SplitFrame refactor
[jalview.git] / src / jalview / gui / AlignViewport.java
index a89174a..93d8c19 100644 (file)
@@ -46,6 +46,7 @@ import jalview.api.AlignViewportI;
 import jalview.api.ViewStyleI;
 import jalview.bin.Cache;
 import jalview.commands.CommandI;
+import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
@@ -67,10 +68,7 @@ import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.Rectangle;
-import java.io.File;
-import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Deque;
 import java.util.Hashtable;
 import java.util.Set;
 import java.util.Vector;
@@ -85,7 +83,7 @@ import javax.swing.JOptionPane;
  * @version $Revision: 1.141 $
  */
 public class AlignViewport extends AlignmentViewport implements
-        SelectionSource, VamsasSource, AlignViewportI, CommandListener
+        SelectionSource, AlignViewportI, CommandListener
 {
   int startRes;
 
@@ -106,15 +104,18 @@ public class AlignViewport extends AlignmentViewport implements
 
   boolean antiAlias = false;
 
-  Rectangle explodedPosition;
+  private Rectangle explodedGeometry;
 
   String viewName;
 
-  boolean gatherViewsHere = false;
-
-  private Deque<CommandI> historyList = new ArrayDeque<CommandI>();
-
-  private Deque<CommandI> redoList = new ArrayDeque<CommandI>();
+  /*
+   * Flag set true on the view that should 'gather' multiple views of the same
+   * sequence set id when a project is reloaded. Set false on all views when
+   * they are 'exploded' into separate windows. Set true on the current view
+   * when 'Gather' is performed, and also on the first tab when the first new
+   * view is created.
+   */
+  private boolean gatherViewsHere = false;
 
   private AnnotationColumnChooser annotationColumnSelectionState;
   /**
@@ -275,7 +276,7 @@ public class AlignViewport extends AlignmentViewport implements
       style = 2;
     }
 
-    setFont(new Font(fontName, style, Integer.parseInt(fontSize)));
+    setFont(new Font(fontName, style, Integer.parseInt(fontSize)), true);
 
     alignment
             .setGapCharacter(Cache.getDefault("GAP_SYMBOL", "-").charAt(0));
@@ -300,10 +301,18 @@ public class AlignViewport extends AlignmentViewport implements
       showConsensus = Cache.getDefault("SHOW_IDENTITY", true);
     }
     initAutoAnnotation();
-    if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
+    String colourProperty = alignment.isNucleotide() ? Preferences.DEFAULT_COLOUR_NUC
+            : Preferences.DEFAULT_COLOUR_PROT;
+    String propertyValue = Cache.getProperty(colourProperty);
+    if (propertyValue == null)
+    {
+      // fall back on this property for backwards compatibility
+      propertyValue = Cache.getProperty(Preferences.DEFAULT_COLOUR);
+    }
+    if (propertyValue != null)
     {
       globalColourScheme = ColourSchemeProperty.getColour(alignment,
-              jalview.bin.Cache.getProperty("DEFAULT_COLOUR"));
+              propertyValue);
 
       if (globalColourScheme instanceof UserColourScheme)
       {
@@ -466,12 +475,13 @@ public class AlignViewport extends AlignmentViewport implements
   boolean validCharWidth;
 
   /**
-   * DOCUMENT ME!
+   * update view settings with the given font. You may need to call
+   * alignPanel.fontChanged to update the layout geometry
    * 
-   * @param f
-   *          DOCUMENT ME!
+   * @param setGrid
+   *          when true, charWidth/height is set according to font mentrics
    */
-  public void setFont(Font f)
+  public void setFont(Font f, boolean setGrid)
   {
     font = f;
 
@@ -480,13 +490,9 @@ public class AlignViewport extends AlignmentViewport implements
     java.awt.FontMetrics fm = c.getFontMetrics(font);
     int w = viewStyle.getCharWidth(), ww = fm.charWidth('M'), h = viewStyle
             .getCharHeight();
-    // only update width/height if the new font won't fit
-    if (h < fm.getHeight())
+    if (setGrid)
     {
       setCharHeight(fm.getHeight());
-    }
-    if (w < ww)
-    {
       setCharWidth(ww);
     }
     viewStyle.setFontName(font.getName());
@@ -501,7 +507,7 @@ public class AlignViewport extends AlignmentViewport implements
   {
     super.setViewStyle(settingsForView);
     setFont(new Font(viewStyle.getFontName(), viewStyle.getFontStyle(),
-            viewStyle.getFontSize()));
+            viewStyle.getFontSize()), false);
 
   }
   /**
@@ -765,6 +771,10 @@ public class AlignViewport extends AlignmentViewport implements
     }
   }
 
+  /**
+   * Returns the (Desktop) instance of the StructureSelectionManager
+   */
+  @Override
   public StructureSelectionManager getStructureSelectionManager()
   {
     return StructureSelectionManager
@@ -894,8 +904,8 @@ public class AlignViewport extends AlignmentViewport implements
           StructureSelectionManager ssm, VamsasSource source)
   {
     /*
-     * ...work in progress... do nothing unless we are a 'complement' of the
-     * source May replace this with direct calls not via SSM.
+     * Do nothing unless we are a 'complement' of the source. May replace this
+     * with direct calls not via SSM.
      */
     if (source instanceof AlignViewportI
             && ((AlignViewportI) source).getCodingComplement() == this)
@@ -917,76 +927,6 @@ public class AlignViewport extends AlignmentViewport implements
     }
   }
 
-  @Override
-  public VamsasSource getVamsasSource()
-  {
-    return this;
-  }
-
-  /**
-   * Add one command to the command history list.
-   * 
-   * @param command
-   */
-  public void addToHistoryList(CommandI command)
-  {
-    if (this.historyList != null)
-    {
-      this.historyList.push(command);
-      broadcastCommand(command, false);
-    }
-  }
-
-  protected void broadcastCommand(CommandI command, boolean undo)
-  {
-    getStructureSelectionManager().commandPerformed(command, undo, getVamsasSource());
-  }
-
-  /**
-   * Add one command to the command redo list.
-   * 
-   * @param command
-   */
-  public void addToRedoList(CommandI command)
-  {
-    if (this.redoList != null)
-    {
-      this.redoList.push(command);
-    }
-    broadcastCommand(command, true);
-  }
-
-  /**
-   * Clear the command redo list.
-   */
-  public void clearRedoList()
-  {
-    if (this.redoList != null)
-    {
-      this.redoList.clear();
-    }
-  }
-
-  public void setHistoryList(Deque<CommandI> list)
-  {
-    this.historyList = list;
-  }
-
-  public Deque<CommandI> getHistoryList()
-  {
-    return this.historyList;
-  }
-
-  public void setRedoList(Deque<CommandI> list)
-  {
-    this.redoList = list;
-  }
-
-  public Deque<CommandI> getRedoList()
-  {
-    return this.redoList;
-  }
-
   /**
    * Add the sequences from the given alignment to this viewport. Optionally,
    * may give the user the option to open a new frame, or split panel, with cDNA
@@ -1053,9 +993,9 @@ public class AlignViewport extends AlignmentViewport implements
         MessageManager.getString("label.split_window"),
         MessageManager.getString("label.new_window"), };
     final String question = JvSwingUtils.wrapTooltip(true,
-            MessageManager.getString("label.open_linked_alignment?"));
+            MessageManager.getString("label.open_split_window?"));
     int response = JOptionPane.showOptionDialog(Desktop.desktop, question,
-            MessageManager.getString("label.open_linked_alignment"),
+            MessageManager.getString("label.open_split_window"),
             JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
             options, options[0]);
 
@@ -1106,8 +1046,6 @@ public class AlignViewport extends AlignmentViewport implements
      * added to the protein alignment.
      */
     MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna);
-    final StructureSelectionManager ssm = StructureSelectionManager
-            .getStructureSelectionManager(Desktop.instance);
     if (mapped != MappingResult.Mapped)
     {
       /*
@@ -1131,57 +1069,62 @@ public class AlignViewport extends AlignmentViewport implements
 
     if (openSplitPane)
     {
-      // TODO: move this kind of constructor stuff to a factory/controller
-      // method ?
-      /*
-       * Open in split pane. DNA sequence above, protein below.
-       */
-      AlignFrame copyMe = new AlignFrame(thisAlignment,
-              AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
-      copyMe.setTitle(getAlignPanel().alignFrame.getTitle());
-      final AlignFrame proteinFrame = al.isNucleotide() ? copyMe
-              : newAlignFrame;
-      final AlignFrame cdnaFrame = al.isNucleotide() ? newAlignFrame
-              : copyMe;
-      protein = proteinFrame.viewport.getAlignment();
-
-      cdnaFrame.setVisible(true);
-      proteinFrame.setVisible(true);
-      String sep = String.valueOf(File.separatorChar);
-      String proteinShortName = proteinFrame.getTitle().substring(
-              proteinFrame.getTitle().lastIndexOf(sep) + 1);
-      String dnaShortName = cdnaFrame.getTitle().substring(
-              cdnaFrame.getTitle().lastIndexOf(sep) + 1);
-      String linkedTitle = MessageManager.formatMessage(
-              "label.linked_view_title", dnaShortName, proteinShortName);
-      JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame);
-      Desktop.addInternalFrame(splitFrame, linkedTitle,
-              AlignFrame.DEFAULT_WIDTH,
-              AlignFrame.DEFAULT_HEIGHT);
-
-      /*
-       * Set the frames to listen for each other's edit and sort commands.
-       */
-      ssm.addCommandListener(cdnaFrame.getViewport());
-      ssm.addCommandListener(proteinFrame.getViewport());
-
-      /*
-       * 'Coding complement' (dna/protein) views will mirror each others' edits,
-       * selections, sorting etc as decided from time to time by the relevant
-       * authorities.
-       */
-      proteinFrame.getViewport().setCodingComplement(cdnaFrame.getViewport());
+      protein = openSplitFrame(newAlignFrame,
+              thisAlignment.getSequencesArray(), protein.getCodonFrames());
     }
 
     /*
      * Register the mappings (held on the protein alignment) with the
      * StructureSelectionManager (for mouseover linking).
      */
+    final StructureSelectionManager ssm = StructureSelectionManager
+            .getStructureSelectionManager(Desktop.instance);
     ssm.addMappings(protein.getCodonFrames());
 
     return true;
   }
 
+  /**
+   * Helper method to open a new SplitFrame holding linked dna and protein
+   * alignments.
+   * 
+   * @param newAlignFrame
+   *          containing a new alignment to be shown
+   * @param seqs
+   *          'complementary' sequences to show in the other split half
+   * @param mappings
+   * @return the protein alignment in the split frame
+   */
+  protected AlignmentI openSplitFrame(AlignFrame newAlignFrame,
+          SequenceI[] seqs, Set<AlignedCodonFrame> mappings)
+  {
+    AlignmentI complementAlignment = new Alignment(seqs);
+    // TODO: move this to a factory/controller method ?
+    /*
+     * Open in split pane. DNA sequence above, protein below.
+     */
+    AlignFrame copyMe = new AlignFrame(complementAlignment,
+            AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+    copyMe.setTitle(getAlignPanel().alignFrame.getTitle());
+
+    AlignmentI al = newAlignFrame.viewport.getAlignment();
+    final AlignFrame proteinFrame = al.isNucleotide() ? copyMe
+            : newAlignFrame;
+    final AlignFrame cdnaFrame = al.isNucleotide() ? newAlignFrame
+            : copyMe;
+    AlignmentI protein = proteinFrame.viewport.getAlignment();
+    protein.setCodonFrames(mappings);
+
+    cdnaFrame.setVisible(true);
+    proteinFrame.setVisible(true);
+    String linkedTitle = MessageManager
+            .getString("label.linked_view_title");
+    JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame);
+    Desktop.addInternalFrame(splitFrame, linkedTitle, -1, -1);
+
+    return protein;
+  }
+
   public AnnotationColumnChooser getAnnotationColumnSelectionState()
   {
     return annotationColumnSelectionState;
@@ -1207,4 +1150,24 @@ public class AlignViewport extends AlignmentViewport implements
       getAlignPanel().getIdPanel().getIdCanvas().setPreferredSize(idw);
     }
   }
+
+  public Rectangle getExplodedGeometry()
+  {
+    return explodedGeometry;
+  }
+
+  public void setExplodedGeometry(Rectangle explodedPosition)
+  {
+    this.explodedGeometry = explodedPosition;
+  }
+
+  public boolean isGatherViewsHere()
+  {
+    return gatherViewsHere;
+  }
+
+  public void setGatherViewsHere(boolean gatherViewsHere)
+  {
+    this.gatherViewsHere = gatherViewsHere;
+  }
 }