Merge remote-tracking branch 'origin/develop' into
[jalview.git] / src / jalview / gui / SeqPanel.java
index 2d44a0f..749b390 100644 (file)
@@ -27,13 +27,16 @@ import jalview.commands.EditCommand.Action;
 import jalview.commands.EditCommand.Edit;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.SequenceAnnotationReport;
+import jalview.renderer.ResidueShaderI;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.SelectionListener;
 import jalview.structure.SelectionSource;
@@ -43,6 +46,7 @@ import jalview.structure.VamsasSource;
 import jalview.util.Comparison;
 import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.BorderLayout;
@@ -56,9 +60,9 @@ import java.awt.event.MouseMotionListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
 import javax.swing.ToolTipManager;
@@ -123,7 +127,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   private final SequenceAnnotationReport seqARep;
 
-  StringBuffer tooltipText = new StringBuffer();
+  StringBuilder tooltipText = new StringBuilder();
 
   String tmpString;
 
@@ -131,7 +135,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   StructureSelectionManager ssm;
 
-  SearchResults lastSearchResults;
+  SearchResultsI lastSearchResults;
 
   /**
    * Creates a new SeqPanel object.
@@ -207,7 +211,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       }
 
       wrappedBlock = y / cHeight;
-      wrappedBlock += av.getStartRes() / cwidth;
+      wrappedBlock += av.getRanges().getStartRes() / cwidth;
 
       res = wrappedBlock * cwidth + x / av.getCharWidth();
 
@@ -220,17 +224,18 @@ public class SeqPanel extends JPanel implements MouseListener,
         // right-hand gutter
         x = seqCanvas.getX() + seqCanvas.getWidth();
       }
-      res = (x / av.getCharWidth()) + av.getStartRes();
-      if (res > av.getEndRes())
+      res = (x / av.getCharWidth()) + av.getRanges().getStartRes();
+      if (res > av.getRanges().getEndRes())
       {
         // moused off right
-        res = av.getEndRes();
+        res = av.getRanges().getEndRes();
       }
     }
 
     if (av.hasHiddenColumns())
     {
-      res = av.getColumnSelection().adjustForHiddenColumns(res);
+      res = av.getAlignment().getHiddenColumns()
+              .adjustForHiddenColumns(res);
     }
 
     return res;
@@ -260,7 +265,9 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
     else
     {
-      seq = Math.min((y / av.getCharHeight()) + av.getStartSeq(), av
+      seq = Math.min((y / av.getCharHeight())
+              + av.getRanges().getStartSeq(),
+              av
               .getAlignment().getHeight() - 1);
     }
 
@@ -334,20 +341,23 @@ public class SeqPanel extends JPanel implements MouseListener,
   {
     seqCanvas.cursorX += dx;
     seqCanvas.cursorY += dy;
+
+    HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+
     if (av.hasHiddenColumns()
-            && !av.getColumnSelection().isVisible(seqCanvas.cursorX))
+ && !hidden.isVisible(seqCanvas.cursorX))
     {
       int original = seqCanvas.cursorX - dx;
       int maxWidth = av.getAlignment().getWidth();
 
-      while (!av.getColumnSelection().isVisible(seqCanvas.cursorX)
+      while (!hidden.isVisible(seqCanvas.cursorX)
               && seqCanvas.cursorX < maxWidth && seqCanvas.cursorX > 0)
       {
         seqCanvas.cursorX += dx;
       }
 
       if (seqCanvas.cursorX >= maxWidth
-              || !av.getColumnSelection().isVisible(seqCanvas.cursorX))
+              || !hidden.isVisible(seqCanvas.cursorX))
       {
         seqCanvas.cursorX = original;
       }
@@ -383,26 +393,27 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
     else
     {
-      while (seqCanvas.cursorY < av.startSeq)
+      while (seqCanvas.cursorY < av.getRanges().getStartSeq())
       {
         ap.scrollUp(true);
       }
-      while (seqCanvas.cursorY + 1 > av.endSeq)
+      while (seqCanvas.cursorY + 1 > av.getRanges().getEndSeq())
       {
         ap.scrollUp(false);
       }
       if (!av.getWrapAlignment())
       {
-        while (seqCanvas.cursorX < av.getColumnSelection()
-                .adjustForHiddenColumns(av.startRes))
+        HiddenColumns hidden = av.getAlignment().getHiddenColumns();
+        while (seqCanvas.cursorX < hidden.adjustForHiddenColumns(av
+                .getRanges().getStartRes()))
         {
           if (!ap.scrollRight(false))
           {
             break;
           }
         }
-        while (seqCanvas.cursorX > av.getColumnSelection()
-                .adjustForHiddenColumns(av.endRes))
+        while (seqCanvas.cursorX > hidden.adjustForHiddenColumns(av
+                .getRanges().getEndRes()))
         {
           if (!ap.scrollRight(true))
           {
@@ -582,6 +593,13 @@ public class SeqPanel extends JPanel implements MouseListener,
     mouseDragging = false;
     mouseWheelPressed = false;
 
+    if (evt.isPopupTrigger()) // Windows: mouseReleased
+    {
+      showPopupMenu(evt);
+      evt.consume();
+      return;
+    }
+
     if (!editingSeqs)
     {
       doMouseReleasedDefineMode(evt);
@@ -608,13 +626,14 @@ public class SeqPanel extends JPanel implements MouseListener,
       return;
     }
 
-    if (evt.isShiftDown() || evt.isAltDown() || evt.isControlDown())
+    boolean isControlDown = Platform.isControlDown(evt);
+    if (evt.isShiftDown() || isControlDown)
     {
-      if (evt.isAltDown() || evt.isControlDown())
+      editingSeqs = true;
+      if (isControlDown)
       {
         groupEditing = true;
       }
-      editingSeqs = true;
     }
     else
     {
@@ -667,7 +686,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * the start of the highlighted region.
    */
   @Override
-  public void highlightSequence(SearchResults results)
+  public void highlightSequence(SearchResultsI results)
   {
     if (results == null || results.equals(lastSearchResults))
     {
@@ -776,7 +795,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       seqARep.appendFeatures(tooltipText, rpos, features,
               this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
     }
-    if (tooltipText.length() == 6) // <html></html>
+    if (tooltipText.length() == 6) // <html>
     {
       setToolTipText(null);
       lastTooltip = null;
@@ -825,6 +844,21 @@ public class SeqPanel extends JPanel implements MouseListener,
   String lastTooltip;
 
   /**
+   * set when the current UI interaction has resulted in a change that requires
+   * overview shading to be recalculated. this could be changed to something
+   * more expressive that indicates what actually has changed, so selective
+   * redraws can be applied
+   */
+  private boolean needOverviewUpdate = false; // TODO: refactor to avcontroller
+
+  /**
+   * set if av.getSelectionGroup() refers to a group that is defined on the
+   * alignment view, rather than a transient selection
+   */
+  // private boolean editingDefinedGroup = false; // TODO: refactor to
+  // avcontroller or viewModel
+
+  /**
    * Set status message in alignment panel
    * 
    * @param sequence
@@ -843,7 +877,8 @@ public class SeqPanel extends JPanel implements MouseListener,
      * Sequence number (if known), and sequence name.
      */
     String seqno = seq == -1 ? "" : " " + (seq + 1);
-    text.append("Sequence" + seqno + " ID: " + sequence.getName());
+    text.append("Sequence").append(seqno).append(" ID: ")
+            .append(sequence.getName());
 
     String residue = null;
     /*
@@ -885,7 +920,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * 
    * @param results
    */
-  private void setStatusMessage(SearchResults results)
+  private void setStatusMessage(SearchResultsI results)
   {
     AlignmentI al = this.av.getAlignment();
     int sequenceIndex = al.findIndex(results);
@@ -894,7 +929,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       return;
     }
     SequenceI ds = al.getSequenceAt(sequenceIndex).getDatasetSequence();
-    for (Match m : results.getResults())
+    for (SearchResultMatchI m : results.getResults())
     {
       SequenceI seq = m.getSequence();
       if (seq.getDatasetSequence() != null)
@@ -1115,8 +1150,10 @@ public class SeqPanel extends JPanel implements MouseListener,
     if (av.hasHiddenColumns())
     {
       fixedColumns = true;
-      int y1 = av.getColumnSelection().getHiddenBoundaryLeft(startres);
-      int y2 = av.getColumnSelection().getHiddenBoundaryRight(startres);
+      int y1 = av.getAlignment().getHiddenColumns()
+              .getHiddenBoundaryLeft(startres);
+      int y2 = av.getAlignment().getHiddenColumns()
+              .getHiddenBoundaryRight(startres);
 
       if ((insertGap && startres > y1 && lastres < y1)
               || (!insertGap && startres < y2 && lastres > y2))
@@ -1191,8 +1228,8 @@ public class SeqPanel extends JPanel implements MouseListener,
         {
           if (sg.getSize() == av.getAlignment().getHeight())
           {
-            if ((av.hasHiddenColumns() && startres < av
-                    .getColumnSelection().getHiddenBoundaryRight(startres)))
+            if ((av.hasHiddenColumns() && startres < av.getAlignment()
+                    .getHiddenColumns().getHiddenBoundaryRight(startres)))
             {
               endEditing();
               return;
@@ -1456,6 +1493,11 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
   }
 
+  /**
+   * Handler for double-click on a position with one or more sequence features.
+   * Opens the Amend Features dialog to allow feature details to be amended, or
+   * the feature deleted.
+   */
   @Override
   public void mouseClicked(MouseEvent evt)
   {
@@ -1474,20 +1516,23 @@ public class SeqPanel extends JPanel implements MouseListener,
               .findFeaturesAtRes(sequence.getDatasetSequence(),
                       sequence.findPosition(findRes(evt)));
 
-      if (features != null && features.size() > 0)
+      if (!features.isEmpty())
       {
-        SearchResults highlight = new SearchResults();
+        /*
+         * highlight the first feature at the position on the alignment
+         */
+        SearchResultsI highlight = new SearchResults();
         highlight.addResult(sequence, features.get(0).getBegin(), features
                 .get(0).getEnd());
         seqCanvas.highlightSearchResults(highlight);
-      }
-      if (features != null && features.size() > 0)
-      {
-        seqCanvas.getFeatureRenderer().amendFeatures(
-                new SequenceI[] { sequence },
-                features.toArray(new SequenceFeature[features.size()]),
-                false, ap);
 
+        /*
+         * open the Amend Features dialog; clear highlighting afterwards,
+         * whether changes were made or not
+         */
+        List<SequenceI> seqs = Collections.singletonList(sequence);
+        seqCanvas.getFeatureRenderer().amendFeatures(seqs, features, false,
+                ap, null);
         seqCanvas.highlightSearchResults(null);
       }
     }
@@ -1531,18 +1576,19 @@ public class SeqPanel extends JPanel implements MouseListener,
    */
   public void doMousePressedDefineMode(MouseEvent evt)
   {
-    int res = findRes(evt);
-    int seq = findSeq(evt);
+    final int res = findRes(evt);
+    final int seq = findSeq(evt);
     oldSeq = seq;
+    needOverviewUpdate = false;
 
     startWrapBlock = wrappedBlock;
 
     if (av.getWrapAlignment() && seq > av.getAlignment().getHeight())
     {
-      JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .getString("label.cannot_edit_annotations_in_wrapped_view"),
               MessageManager.getString("label.wrapped_view_no_edit"),
-              JOptionPane.WARNING_MESSAGE);
+              JvOptionPane.WARNING_MESSAGE);
       return;
     }
 
@@ -1560,64 +1606,30 @@ public class SeqPanel extends JPanel implements MouseListener,
 
     stretchGroup = av.getSelectionGroup();
 
-    if (stretchGroup == null)
+    if (stretchGroup == null || !stretchGroup.contains(sequence, res))
     {
-      stretchGroup = av.getAlignment().findGroup(sequence);
-
-      if ((stretchGroup != null) && (res > stretchGroup.getStartRes())
-              && (res < stretchGroup.getEndRes()))
+      stretchGroup = av.getAlignment().findGroup(sequence, res);
+      if (stretchGroup != null)
       {
+        // only update the current selection if the popup menu has a group to
+        // focus on
         av.setSelectionGroup(stretchGroup);
       }
-      else
-      {
-        stretchGroup = null;
-      }
     }
-    else if (!stretchGroup.getSequences(null).contains(sequence)
-            || (stretchGroup.getStartRes() > res)
-            || (stretchGroup.getEndRes() < res))
-    {
-      stretchGroup = null;
-
-      SequenceGroup[] allGroups = av.getAlignment().findAllGroups(sequence);
-
-      if (allGroups != null)
-      {
-        for (int i = 0; i < allGroups.length; i++)
-        {
-          if ((allGroups[i].getStartRes() <= res)
-                  && (allGroups[i].getEndRes() >= res))
-          {
-            stretchGroup = allGroups[i];
-            break;
-          }
-        }
-      }
-
-      av.setSelectionGroup(stretchGroup);
 
+    if (evt.isPopupTrigger()) // Mac: mousePressed
+    {
+      showPopupMenu(evt);
+      return;
     }
 
-    if (evt.isPopupTrigger())
+    /*
+     * defer right-mouse click handling to mouseReleased on Windows
+     * (where isPopupTrigger() will answer true)
+     * NB isRightMouseButton is also true for Cmd-click on Mac
+     */
+    if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac())
     {
-      List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
-              .findFeaturesAtRes(sequence.getDatasetSequence(),
-                      sequence.findPosition(res));
-      List<String> links = new ArrayList<String>();
-      for (SequenceFeature sf : allFeatures)
-      {
-        if (sf.links != null)
-        {
-          for (String link : sf.links)
-          {
-            links.add(link);
-          }
-        }
-      }
-
-      PopupMenu pop = new PopupMenu(ap, null, links);
-      pop.show(this, evt.getX(), evt.getY());
       return;
     }
 
@@ -1639,20 +1651,20 @@ public class SeqPanel extends JPanel implements MouseListener,
       sg.setEndRes(res);
       sg.addSequence(sequence, false);
       av.setSelectionGroup(sg);
-
       stretchGroup = sg;
 
       if (av.getConservationSelected())
       {
-        SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(),
-                "Background");
+        SliderPanel.setConservationSlider(ap, av.getResidueShading(),
+                ap.getViewName());
       }
 
       if (av.getAbovePIDThreshold())
       {
-        SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(),
-                "Background");
+        SliderPanel.setPIDSliderSource(ap, av.getResidueShading(),
+                ap.getViewName());
       }
+      // TODO: stretchGroup will always be not null. Is this a merge error ?
       if ((stretchGroup != null) && (stretchGroup.getEndRes() == res))
       {
         // Edit end res position of selected group
@@ -1671,6 +1683,37 @@ public class SeqPanel extends JPanel implements MouseListener,
   }
 
   /**
+   * Build and show a pop-up menu at the right-click mouse position
+   * 
+   * @param evt
+   * @param res
+   * @param sequences
+   */
+  void showPopupMenu(MouseEvent evt)
+  {
+    final int res = findRes(evt);
+    final int seq = findSeq(evt);
+    SequenceI sequence = av.getAlignment().getSequenceAt(seq);
+    List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
+            .findFeaturesAtRes(sequence.getDatasetSequence(),
+                    sequence.findPosition(res));
+    List<String> links = new ArrayList<String>();
+    for (SequenceFeature sf : allFeatures)
+    {
+      if (sf.links != null)
+      {
+        for (String link : sf.links)
+        {
+          links.add(link);
+        }
+      }
+    }
+
+    PopupMenu pop = new PopupMenu(ap, null, links);
+    pop.show(this, evt.getX(), evt.getY());
+  }
+
+  /**
    * DOCUMENT ME!
    * 
    * @param evt
@@ -1682,28 +1725,29 @@ public class SeqPanel extends JPanel implements MouseListener,
     {
       return;
     }
-
-    stretchGroup.recalcConservation(); // always do this - annotation has own
-                                       // state
+    // always do this - annotation has own state
+    // but defer colourscheme update until hidden sequences are passed in
+    boolean vischange = stretchGroup.recalcConservation(true);
+    needOverviewUpdate |= vischange && av.isSelectionDefinedGroup();
     if (stretchGroup.cs != null)
     {
       stretchGroup.cs.alignmentChanged(stretchGroup,
               av.getHiddenRepSequences());
 
+      ResidueShaderI groupColourScheme = stretchGroup.getGroupColourScheme();
+      String name = stretchGroup.getName();
       if (stretchGroup.cs.conservationApplied())
       {
-        SliderPanel.setConservationSlider(ap, stretchGroup.cs,
-                stretchGroup.getName());
+        SliderPanel.setConservationSlider(ap, groupColourScheme, name);
       }
-      else
+      if (stretchGroup.cs.getThreshold() > 0)
       {
-        SliderPanel.setPIDSliderSource(ap, stretchGroup.cs,
-                stretchGroup.getName());
+        SliderPanel.setPIDSliderSource(ap, groupColourScheme, name);
       }
     }
     PaintRefresher.Refresh(this, av.getSequenceSetId());
-    ap.paintAlignment(true);
-
+    ap.paintAlignment(needOverviewUpdate);
+    needOverviewUpdate = false;
     changeEndRes = false;
     changeStartRes = false;
     stretchGroup = null;
@@ -1747,9 +1791,9 @@ public class SeqPanel extends JPanel implements MouseListener,
       changeStartRes = true;
     }
 
-    if (res < av.getStartRes())
+    if (res < av.getRanges().getStartRes())
     {
-      res = av.getStartRes();
+      res = av.getRanges().getStartRes();
     }
 
     if (changeEndRes)
@@ -1757,6 +1801,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (res > (stretchGroup.getStartRes() - 1))
       {
         stretchGroup.setEndRes(res);
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
     else if (changeStartRes)
@@ -1764,6 +1809,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (res < (stretchGroup.getEndRes() + 1))
       {
         stretchGroup.setStartRes(res);
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
 
@@ -1797,6 +1843,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (stretchGroup.getSequences(null).contains(nextSeq))
       {
         stretchGroup.deleteSequence(seq, false);
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
       else
       {
@@ -1806,6 +1853,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
 
         stretchGroup.addSequence(nextSeq, false);
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
 
@@ -1879,13 +1927,15 @@ public class SeqPanel extends JPanel implements MouseListener,
       {
         if (evt != null)
         {
-          if (mouseDragging && (evt.getY() < 0) && (av.getStartSeq() > 0))
+          if (mouseDragging && (evt.getY() < 0)
+                  && (av.getRanges().getStartSeq() > 0))
           {
             running = ap.scrollUp(true);
           }
 
           if (mouseDragging && (evt.getY() >= getHeight())
-                  && (av.getAlignment().getHeight() > av.getEndSeq()))
+                  && (av.getAlignment().getHeight() > av.getRanges()
+                          .getEndSeq()))
           {
             running = ap.scrollUp(false);
           }
@@ -1915,7 +1965,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    */
   @Override
   public void selection(SequenceGroup seqsel, ColumnSelection colsel,
-          SelectionSource source)
+          HiddenColumns hidden, SelectionSource source)
   {
     // TODO: fix this hack - source of messages is align viewport, but SeqPanel
     // handles selection messages...
@@ -1923,9 +1973,20 @@ public class SeqPanel extends JPanel implements MouseListener,
     // shared between viewports.
     boolean iSentTheSelection = (av == source || (source instanceof AlignViewport && ((AlignmentViewport) source)
             .getSequenceSetId().equals(av.getSequenceSetId())));
-    if (iSentTheSelection || !av.followSelection)
+
+    if (iSentTheSelection)
     {
-      return;
+      // respond to our own event by updating dependent dialogs
+      if (ap.getCalculationDialog() != null)
+      {
+        ap.getCalculationDialog().validateCalcTypes();
+      }
+
+      // process further ?
+      if (!av.followSelection)
+      {
+        return;
+      }
     }
 
     /*
@@ -1940,7 +2001,7 @@ public class SeqPanel extends JPanel implements MouseListener,
      * Check for selection in a view of which this one is a dna/protein
      * complement.
      */
-    if (selectionFromTranslation(seqsel, colsel, source))
+    if (selectionFromTranslation(seqsel, colsel, hidden, source))
     {
       return;
     }
@@ -1959,8 +2020,8 @@ public class SeqPanel extends JPanel implements MouseListener,
     {
       if (av.getAlignment() == null)
       {
-        Cache.log.warn("alignviewport av SeqSetId="
-                + av.getSequenceSetId() + " ViewId=" + av.getViewId()
+        Cache.log.warn("alignviewport av SeqSetId=" + av.getSequenceSetId()
+                + " ViewId=" + av.getViewId()
                 + " 's alignment is NULL! returning immediately.");
         return;
       }
@@ -2003,7 +2064,8 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          av.getColumnSelection().setElementsFrom(colsel);
+          av.getColumnSelection().setElementsFrom(colsel,
+                  av.getAlignment().getHiddenColumns());
         }
       }
       av.isColSelChanged(true);
@@ -2012,8 +2074,8 @@ public class SeqPanel extends JPanel implements MouseListener,
 
     if (copycolsel
             && av.hasHiddenColumns()
-            && (av.getColumnSelection() == null || av.getColumnSelection()
-                    .getHiddenColumns() == null))
+            && (av.getAlignment().getHiddenColumns() == null || av
+                    .getAlignment().getHiddenColumns().getListOfCols() == null))
     {
       System.err.println("Bad things");
     }
@@ -2023,6 +2085,13 @@ public class SeqPanel extends JPanel implements MouseListener,
       PaintRefresher.Refresh(this, av.getSequenceSetId());
       // ap.paintAlignment(false);
     }
+
+    // lastly, update dependent dialogs
+    if (ap.getCalculationDialog() != null)
+    {
+      ap.getCalculationDialog().validateCalcTypes();
+    }
+
   }
 
   /**
@@ -2035,7 +2104,8 @@ public class SeqPanel extends JPanel implements MouseListener,
    * @param source
    */
   protected boolean selectionFromTranslation(SequenceGroup seqsel,
-          ColumnSelection colsel, SelectionSource source)
+          ColumnSelection colsel, HiddenColumns hidden,
+          SelectionSource source)
   {
     if (!(source instanceof AlignViewportI))
     {
@@ -2058,9 +2128,19 @@ public class SeqPanel extends JPanel implements MouseListener,
     /*
      * Map column selection
      */
-    ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
-            av);
+    // ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
+    // av);
+    ColumnSelection cs = new ColumnSelection();
+    HiddenColumns hs = new HiddenColumns();
+    MappingUtils.mapColumnSelection(colsel, hidden, sourceAv, av, cs, hs);
     av.setColumnSelection(cs);
+    av.getAlignment().setHiddenColumns(hs);
+
+    // lastly, update any dependent dialogs
+    if (ap.getCalculationDialog() != null)
+    {
+      ap.getCalculationDialog().validateCalcTypes();
+    }
 
     PaintRefresher.Refresh(this, av.getSequenceSetId());