Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID
[jalview.git] / src / jalview / gui / AnnotationPanel.java
index 2177a26..8a957bc 100755 (executable)
@@ -72,6 +72,7 @@ import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.viewmodel.ViewportListenerI;
 import jalview.viewmodel.ViewportRanges;
+import jalview.ws.datamodel.MappableContactMatrixI;
 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
 
 /**
@@ -605,7 +606,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     }
     else
     {
-      // no row (or row that can be adjusted) was pressed. Simulate a ruler click
+      // no row (or row that can be adjusted) was pressed. Simulate a ruler
+      // click
       ap.getScalePanel().mousePressed(evt);
     }
   }
@@ -666,24 +668,48 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           if (matrix.hasGroups())
           {
             SequenceI rseq = clicked.sequenceRef;
-            BitSet grp = matrix.getGroupsFor(currentX);
+            BitSet grp = new BitSet();
+            grp.or(matrix.getGroupsFor(currentX));
             // TODO: cXci needs to be mapped to real groups
             for (int c = fr; c <= to; c++)
             {
               BitSet additionalGrp = matrix.getGroupsFor(c);
               grp.or(additionalGrp);
             }
+
             HiddenColumns hc = av.getAlignment().getHiddenColumns();
-            for (int p = grp.nextSetBit(0); p >= 0; p = grp
+            ColumnSelection cs = av.getColumnSelection();
+            
+            for (int p=grp.nextSetBit(0); p >= 0; p = grp
                     .nextSetBit(p + 1))
             {
-              int offp = (rseq != null)
-                      ? rseq.findIndex(rseq.getStart() - 1 + p)
-                      : p;
-
-              if (!av.hasHiddenColumns() || hc.isVisible(offp))
+              if (matrix instanceof MappableContactMatrixI)
               {
-                av.getColumnSelection().addElement(offp);
+                // find the end of this run of set bits
+                int nextp = grp.nextClearBit(p)-1;
+                int[] pos = ((MappableContactMatrixI)matrix).getMappedPositionsFor(rseq, p,nextp);
+                p=nextp;
+                
+                if (pos!=null)
+                {
+                  for (int pos_p = pos[0];pos_p<=pos[1];pos_p++)
+                  {
+                    int col = rseq.findIndex(pos_p)-1;
+                    if (col>=0 && (!av.hasHiddenColumns() || hc.isVisible(col)))
+                    {
+                      cs.addElement(col);
+                    }
+                  }
+                }
+              } else {
+                int offp = (rseq != null)
+                        ? rseq.findIndex(rseq.getStart() - 1 + p)
+                        : p;
+  
+                if (!av.hasHiddenColumns() || hc.isVisible(offp))
+                {
+                  cs.addElement(offp);
+                }
               }
             }
           }
@@ -711,7 +737,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         if (evt.isControlDown()
                 && PAEContactMatrix.PAEMATRIX.equals(clicked.getCalcId()))
         {
-          int c = fr - 1;
+          int c = fr;
           ContactRange cr = forCurrentX.getRangeFor(fr, to);
           double cval;
           // TODO: could use GraphLine instead of arbitrary picking
@@ -721,7 +747,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           // controls feathering - what other elements in row/column
           // should we select
           double thresh = cr.getMean() + (cr.getMax() - cr.getMean()) * .15;
-          while (c > 0)
+          while (c >= 0)
           {
             cval = forCurrentX.getContactAt(c);
             if (// cr.getMin() <= cval &&
@@ -739,27 +765,27 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
             }
             c--;
           }
-            c = to;
-            while (c < forCurrentX.getContactHeight())
+          c = to;
+          while (c < forCurrentX.getContactHeight())
+          {
+            cval = forCurrentX.getContactAt(c);
+            if (// cr.getMin() <= cval &&
+            cval <= thresh)
             {
-              cval = forCurrentX.getContactAt(c);
-              if (// cr.getMin() <= cval &&
-              cval <= thresh)
-              {
-                int[] cols = forCurrentX.getMappedPositionsFor(c, c);
-                if (cols != null)
-                {
-                  av.getColumnSelection().addRangeOfElements(cols, true);
-                }
-              }
-              else
+              int[] cols = forCurrentX.getMappedPositionsFor(c, c);
+              if (cols != null)
               {
-                break;
+                av.getColumnSelection().addRangeOfElements(cols, true);
               }
-              c++;
-
             }
+            else
+            {
+              break;
+            }
+            c++;
+
           }
+        }
       }
     }
     ap.paintAlignment(false, false);
@@ -767,6 +793,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     av.sendSelection();
     return true;
   }
+
   /**
    * Construct and display a context menu at the right-click position
    * 
@@ -1031,7 +1058,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     }
     if (rowIndex[0] != toRowIndex[0])
     {
-      jalview.bin.Console.trace("Drag went to another row. needs to be clipped");
+      jalview.bin.Console
+              .trace("Drag went to another row. needs to be clipped");
     }
 
     // rectangular selection on matrix style annotation
@@ -1050,12 +1078,12 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       ContactGeometry lastXcgeom = new ContactGeometry(forFromX,
               cma.graphHeight);
       ContactGeometry.contactInterval lastXci = lastXcgeom
-              .mapFor(rowIndex[1], rowIndex[1] - deltaY);
+              .mapFor(rowIndex[1], rowIndex[1] + deltaY);
 
       ContactGeometry cXcgeom = new ContactGeometry(forToX,
               cma.graphHeight);
       ContactGeometry.contactInterval cXci = cXcgeom.mapFor(rowIndex[1],
-              rowIndex[1] - deltaY);
+              rowIndex[1] + deltaY);
 
       // mark rectangular region formed by drag
       jalview.bin.Console.trace("Matrix Selection from last(" + fromXc
@@ -1073,16 +1101,16 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         for (int pair = 0; pair < mappedPos.length; pair += 2)
         {
           for (int c = mappedPos[pair]; c <= mappedPos[pair + 1]; c++)
-//          {
-//            if (cma.sequenceRef != null)
-//            {
-//              int col = cma.sequenceRef.findIndex(cma.sequenceRef.getStart()+c);
-//              av.getColumnSelection().addElement(col);
-//            }
-//            else
-            {
-              av.getColumnSelection().addElement(c);
-            }
+          // {
+          // if (cma.sequenceRef != null)
+          // {
+          // int col = cma.sequenceRef.findIndex(cma.sequenceRef.getStart()+c);
+          // av.getColumnSelection().addElement(col);
+          // }
+          // else
+          {
+            av.getColumnSelection().addElement(c);
+          }
         }
       }
       // and again for most recent corner of drag
@@ -1094,16 +1122,17 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         for (int pair = 0; pair < mappedPos.length; pair += 2)
         {
           jalview.bin.Console.trace("Marking " + fr + " to " + to
-                  + " mapping to sequence positions " + mappedPos[pair] + " to "
-                  + mappedPos[pair+1]);
+                  + " mapping to sequence positions " + mappedPos[pair]
+                  + " to " + mappedPos[pair + 1]);
           for (int c = mappedPos[pair]; c <= mappedPos[pair + 1]; c++)
           {
-//            if (cma.sequenceRef != null)
-//            {
-//              int col = cma.sequenceRef.findIndex(cma.sequenceRef.getStart()+c);
-//              av.getColumnSelection().addElement(col);
-//            }
-//            else
+            // if (cma.sequenceRef != null)
+            // {
+            // int col =
+            // cma.sequenceRef.findIndex(cma.sequenceRef.getStart()+c);
+            // av.getColumnSelection().addElement(col);
+            // }
+            // else
             {
               av.getColumnSelection().addElement(c);
             }
@@ -1218,7 +1247,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       {
         row = i;
         res[0] = row;
-        res[1] = height - yPos;
+        res[1] = yPos-lheight;
         break;
       }
     }
@@ -1272,6 +1301,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     // TODO abstract tooltip generator so different implementations can be built
     if (ann.graph == AlignmentAnnotation.CONTACT_MAP)
     {
+      if (rowAndOffset>=ann.graphHeight)
+      {
+        return null;
+      }
       ContactListI clist = av.getContactList(ann, column);
       if (clist != null)
       {
@@ -1280,7 +1313,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         ContactRange cr = clist.getRangeFor(ci.cStart, ci.cEnd);
         tooltip = "Contact from " + clist.getPosition() + ", [" + ci.cStart
                 + " - " + ci.cEnd + "]" + "<br/>Mean:" + cr.getMean();
-        
+
         int col = ann.sequenceRef.findPosition(column);
         int[][] highlightPos;
         int[] mappedPos = clist.getMappedPositionsFor(ci.cStart, ci.cEnd);
@@ -1453,8 +1486,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         return;
       }
     }
-    imgWidth = (av.getRanges().getEndRes() - av.getRanges().getStartRes()
-            + 1) * av.getCharWidth();
+    updateFadedImageWidth();
     if (imgWidth < 1)
     {
       return;
@@ -1475,7 +1507,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           tried = true;
         } catch (IllegalArgumentException exc)
         {
-          System.err.println(
+          jalview.bin.Console.errPrintln(
                   "Serious issue with viewport geometry imgWidth requested was "
                           + imgWidth);
           return;
@@ -1522,6 +1554,13 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     g.drawImage(image, 0, 0, this);
   }
 
+  public void updateFadedImageWidth()
+  {
+    imgWidth = (av.getRanges().getEndRes() - av.getRanges().getStartRes()
+            + 1) * av.getCharWidth();
+
+  }
+
   /**
    * set true to enable redraw timing debug output on stderr
    */
@@ -1611,7 +1650,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
               && (fadedImage == null || fadedImage.getWidth() != imgWidth
                       || fadedImage.getHeight() != image.getHeight()))
       {
-        // System.err.println("redraw faded image ("+(fadedImage==null ?
+        // jalview.bin.Console.errPrintln("redraw faded image ("+(fadedImage==null ?
         // "null image" : "") + " lastGood="+lastImageGood+")");
         fadedImage = new BufferedImage(imgWidth, image.getHeight(),
                 BufferedImage.TYPE_INT_RGB);
@@ -1697,6 +1736,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
   @Override
   public int getFadedImageWidth()
   {
+    updateFadedImageWidth();
     return imgWidth;
   }