JAL-845 SplitFrame for "show product" and after aligning from SplitFrame
[jalview.git] / src / jalview / gui / AlignFrame.java
index 38940d2..2b92142 100644 (file)
@@ -23,7 +23,6 @@ package jalview.gui;
 import jalview.analysis.AAFrequency;
 import jalview.analysis.AlignmentSorter;
 import jalview.analysis.AlignmentUtils;
-import jalview.analysis.AlignmentUtils.MappingResult;
 import jalview.analysis.Conservation;
 import jalview.analysis.CrossRef;
 import jalview.analysis.Dna;
@@ -33,6 +32,7 @@ import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
+import jalview.api.SplitContainerI;
 import jalview.api.ViewStyleI;
 import jalview.api.analysis.ScoreModelI;
 import jalview.bin.Cache;
@@ -89,7 +89,6 @@ import jalview.schemes.TaylorColourScheme;
 import jalview.schemes.TurnColourScheme;
 import jalview.schemes.UserColourScheme;
 import jalview.schemes.ZappoColourScheme;
-import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.ws.jws1.Discoverer;
@@ -769,104 +768,28 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }).start();
   }
 
+  /**
+   * Configure menu items that vary according to whether the alignment is
+   * nucleotide or protein
+   * 
+   * @param nucleotide
+   */
   public void setGUINucleotide(boolean nucleotide)
   {
     showTranslation.setVisible(nucleotide);
-    cdna.setVisible(!nucleotide);
     conservationMenuItem.setEnabled(!nucleotide);
     modifyConservation.setEnabled(!nucleotide);
     showGroupConservation.setEnabled(!nucleotide);
     rnahelicesColour.setEnabled(nucleotide);
     purinePyrimidineColour.setEnabled(nucleotide);
+    showComplementMenuItem.setText(MessageManager
+            .getString(nucleotide ? "label.protein" : "label.nucleotide"));
+    setColourSelected(jalview.bin.Cache.getDefault(
+            nucleotide ? Preferences.DEFAULT_COLOUR_NUC
+                    : Preferences.DEFAULT_COLOUR_PROT, "None"));
   }
 
   /**
-   * Builds codon mappings from this (protein) alignment to any compatible
-   * nucleotide alignments. Mappings are built between sequences with the same
-   * name and compatible lengths. Also makes the cDNA alignment a
-   * CommandListener for the protein alignment so that edits are mirrored.
-   */
-  @Override
-  protected void linkCdna_actionPerformed()
-  {
-    int linkedCount = 0;
-    int alreadyLinkedCount = 0;
-    final AlignmentI thisAlignment = this.alignPanel.getAlignment();
-
-    for (AlignFrame af : Desktop.getAlignFrames())
-    {
-      if (af.alignPanel != null)
-      {
-        final AlignmentI thatAlignment = af.alignPanel.getAlignment();
-        if (thatAlignment.isNucleotide())
-        {
-          MappingResult mapped = AlignmentUtils.mapProteinToCdna(
-                  thisAlignment, thatAlignment);
-          if (mapped == MappingResult.AlreadyMapped)
-          {
-            alreadyLinkedCount++;
-          }
-          else if (mapped == MappingResult.Mapped)
-          {
-            final StructureSelectionManager ssm = StructureSelectionManager
-                    .getStructureSelectionManager(Desktop.instance);
-            ssm.addMappings(thisAlignment.getCodonFrames());
-            // enable the next line to enable linked editing
-            // ssm.addCommandListener(af.getViewport());
-            linkedCount++;
-          }
-        }
-      }
-    }
-    String msg = "";
-    if (linkedCount == 0 && alreadyLinkedCount == 0)
-    {
-      msg = MessageManager.getString("label.no_cdna");
-    }
-    else if (linkedCount > 0)
-    {
-      msg = MessageManager.formatMessage("label.linked_cdna", linkedCount);
-    }
-    else
-    {
-      msg = MessageManager.formatMessage("label.cdna_all_linked",
-              alreadyLinkedCount);
-    }
-    setStatus(msg);
-  }
-
-  /**
-   * Align any linked cDNA to match the alignment of this (protein) alignment.
-   * Any mapped sequence regions will be realigned, unmapped sequences are not
-   * affected.
-   */
-  @Override
-  protected void alignCdna_actionPerformed()
-  {
-    int seqCount = 0;
-    int alignCount = 0;
-    final AlignmentI thisAlignment = this.alignPanel.getAlignment();
-    for (AlignFrame af : Desktop.getAlignFrames())
-    {
-      if (af.alignPanel != null)
-      {
-        final AlignmentI thatAlignment = af.alignPanel.getAlignment();
-        if (thatAlignment.isNucleotide())
-        {
-          int seqsAligned = thatAlignment.alignAs(thisAlignment);
-          seqCount += seqsAligned;
-          if (seqsAligned > 0)
-          {
-            af.alignPanel.alignmentChanged();
-            alignCount++;
-          }
-        }
-      }
-    }
-    setStatus(MessageManager.formatMessage("label.cdna_aligned", seqCount,
-            alignCount));
-  }
-  /**
    * set up menus for the current viewport. This may be called after any
    * operation that affects the data in the current view (selection changed,
    * etc) to update the menus to reflect the new state.
@@ -2386,15 +2309,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       return;
     }
 
-    List<SequenceI> seqs = new ArrayList<SequenceI>(sg.getSize());
-    SequenceI seq;
-    for (int i = 0; i < sg.getSize(); i++)
-    {
-      seq = sg.getSequenceAt(i);
-      seqs.add(seq);
-    }
-
-    // If the cut affects all sequences, warn, remove highlighted columns
+    /*
+     * If the cut affects all sequences, warn, remove highlighted columns
+     */
     if (sg.getSize() == viewport.getAlignment().getHeight())
     {
       int confirm = JOptionPane.showConfirmDialog(this,
@@ -2411,15 +2328,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               sg.getEndRes() + 1);
     }
 
-    SequenceI[] cut = new SequenceI[seqs.size()];
-    for (int i = 0; i < seqs.size(); i++)
-    {
-      cut[i] = seqs.get(i);
-    }
+    SequenceI[] cut = sg.getSequences()
+            .toArray(new SequenceI[sg.getSize()]);
 
-    /*
-     * //ADD HISTORY ITEM
-     */
     addHistoryItem(new EditCommand(
             MessageManager.getString("label.cut_sequences"), Action.CUT,
             cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
@@ -2934,6 +2845,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void followHighlight_actionPerformed()
   {
+    /*
+     * Set the 'follow' flag on the Viewport (and scroll to position if now
+     * true).
+     */
     if (viewport.followHighlight = this.followHighlightMenuItem.getState())
     {
       alignPanel.scrollToPosition(
@@ -4810,7 +4725,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           public void actionPerformed(ActionEvent e)
           {
             // TODO: new thread for this call with vis-delay
-            af.showProductsFor(af.viewport.getSequenceSelection(), ds,
+            af.showProductsFor(af.viewport.getSequenceSelection(),
                     isRegSel, dna, source);
           }
 
@@ -4829,14 +4744,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     return showp;
   }
 
-  protected void showProductsFor(SequenceI[] sel, Alignment ds,
-          boolean isRegSel, boolean dna, String source)
+  protected void showProductsFor(final SequenceI[] sel,
+          final boolean isRegSel, final boolean dna, final String source)
   {
-    final boolean fisRegSel = isRegSel;
-    final boolean fdna = dna;
-    final String fsrc = source;
-    final AlignFrame ths = this;
-    final SequenceI[] fsel = sel;
     Runnable foo = new Runnable()
     {
 
@@ -4844,15 +4754,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       public void run()
       {
         final long sttime = System.currentTimeMillis();
-        ths.setProgressBar(MessageManager.formatMessage("status.searching_for_sequences_from", new Object[]{fsrc}), sttime);
+        AlignFrame.this.setProgressBar(MessageManager.formatMessage(
+                "status.searching_for_sequences_from", new Object[]
+                { source }), sttime);
         try
         {
-          Alignment ds = ths.getViewport().getAlignment().getDataset(); // update
-          // our local
-          // dataset
-          // reference
+          // update our local dataset reference
+          Alignment ds = AlignFrame.this.getViewport().getAlignment()
+                  .getDataset();
           Alignment prods = CrossRef
-                  .findXrefSequences(fsel, fdna, fsrc, ds);
+                  .findXrefSequences(sel, dna, source, ds);
           if (prods != null)
           {
             SequenceI[] sprods = new SequenceI[prods.getHeight()];
@@ -4876,16 +4787,38 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             }
             AlignFrame naf = new AlignFrame(al, DEFAULT_WIDTH,
                     DEFAULT_HEIGHT);
-            String newtitle = "" + ((fdna) ? "Proteins " : "Nucleotides ")
-                    + " for " + ((fisRegSel) ? "selected region of " : "")
+            String newtitle = "" + ((dna) ? "Proteins" : "Nucleotides")
+                    + " for " + ((isRegSel) ? "selected region of " : "")
                     + getTitle();
-            Desktop.addInternalFrame(naf, newtitle, DEFAULT_WIDTH,
-                    DEFAULT_HEIGHT);
+            naf.setTitle(newtitle);
+
+            // remove this flag once confirmed we want a split view
+            boolean asSplitFrame = true;
+            if (asSplitFrame)
+            {
+              AlignFrame copyThis = new AlignFrame(
+                      AlignFrame.this.viewport.getAlignment(),
+                      AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+              copyThis.setTitle(AlignFrame.this.getTitle());
+              // SplitFrame with dna above, protein below
+              SplitFrame sf = new SplitFrame(dna ? copyThis : naf,
+                      dna ? naf : copyThis);
+              naf.setVisible(true);
+              copyThis.setVisible(true);
+              String linkedTitle = MessageManager
+                      .getString("label.linked_view_title");
+              Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
+            }
+            else
+            {
+              Desktop.addInternalFrame(naf, newtitle, DEFAULT_WIDTH,
+                      DEFAULT_HEIGHT);
+            }
           }
           else
           {
             System.err.println("No Sequences generated for xRef type "
-                    + fsrc);
+                    + source);
           }
         } catch (Exception e)
         {
@@ -4899,7 +4832,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           jalview.bin.Cache.log.error("Error when finding crossreferences",
                   e);
         }
-        ths.setProgressBar(MessageManager.formatMessage("status.finished_searching_for_sequences_from", new Object[]{fsrc}),
+        AlignFrame.this.setProgressBar(MessageManager.formatMessage(
+                "status.finished_searching_for_sequences_from",
+                new Object[]
+                { source }),
                 sttime);
       }
 
@@ -4968,10 +4904,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               "label.translation_of_params", new Object[]
               { this.getTitle() });
       af.setTitle(newTitle);
-      viewport.openSplitFrame(af, viewport.getAlignment());
+      final SequenceI[] seqs = viewport.getSelectionGroup() == null ? viewport
+              .getAlignment().getSequencesArray() : viewport
+              .getSelectionAsNewSequence();
+      viewport.openSplitFrame(af, seqs);
       // Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
-      // // enable next line for linked editing
-      // viewport.getStructureSelectionManager().addCommandListener(viewport);
     }
   }
 
@@ -6000,9 +5937,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * Open a new alignment window, with the cDNA associated with this (protein)
    * alignment, aligned as is the protein.
    */
-  @Override
   protected void viewAsCdna_actionPerformed()
   {
+    // TODO no longer a menu action - refactor as required
     final AlignmentI alignment = getViewport().getAlignment();
     Set<AlignedCodonFrame> mappings = alignment.getCodonFrames();
     if (mappings == null)
@@ -6041,7 +5978,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     Desktop.addInternalFrame(alignFrame, newtitle,
             AlignFrame.DEFAULT_WIDTH,
             AlignFrame.DEFAULT_HEIGHT);
+  }
 
+  /**
+   * Set visibility of dna/protein complement view (available when shown in a
+   * split frame).
+   * 
+   * @param show
+   */
+  @Override
+  protected void showComplement_actionPerformed(boolean show)
+  {
+    SplitContainerI sf = getSplitViewContainer();
+    if (sf != null) {
+      sf.setComplementVisible(this, show);
+    }
   }
 }