From: kiramt Date: Wed, 8 Nov 2017 16:06:14 +0000 (+0000) Subject: Merge branch 'develop' into feature/JAL-2759 X-Git-Tag: Release_2_10_4~55^2~1^2~75 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=0c83c631f7d7db0baad3335805c15dd40c0aed59;p=jalview.git Merge branch 'develop' into feature/JAL-2759 Conflicts: src/jalview/gui/SeqCanvas.java src/jalview/renderer/ScaleRenderer.java test/jalview/datamodel/SequenceTest.java --- 0c83c631f7d7db0baad3335805c15dd40c0aed59 diff --cc src/jalview/gui/SeqCanvas.java index f72acae,2a9c704..6c4391c --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@@ -42,7 -42,7 +43,8 @@@ import java.awt.RenderingHints import java.awt.Shape; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; +import java.util.Iterator; + import java.util.List; import javax.swing.JComponent; @@@ -694,59 -854,54 +856,57 @@@ public class SeqCanvas extends JCompone if (av.hasHiddenColumns() && av.getShowHiddenMarkers()) { - g.setColor(Color.blue); - int res; - HiddenColumns hidden = av.getAlignment().getHiddenColumns(); - - Iterator it = hidden.getBoundedStartIterator(startRes, - endx + 1); - while (it.hasNext()) - { - res = it.next() - startRes; - gg.fillPolygon( - new int[] - { res * charWidth - charHeight / 4, - res * charWidth + charHeight / 4, res * charWidth }, - new int[] - { ypos - (charHeight / 2), ypos - (charHeight / 2), - ypos - (charHeight / 2) + 8 }, 3); - } + drawHiddenColumnMarkers(g, ypos, startCol, endColumn); } - // When printing we have an extra clipped region, - // the Printable page which we need to account for here - Shape clip = g.getClip(); + g.translate(-labelWidthWest, 0); - if (clip == null) - { - g.setClip(0, 0, cWidth * charWidth, canvasHeight); - } - else - { - g.setClip(0, (int) clip.getBounds().getY(), cWidth * charWidth, - (int) clip.getBounds().getHeight()); - } + ypos += wrappedRepeatHeightPx; + startCol += viewportWidth; + widthsDrawn++; + } + } - drawPanel(g, startRes, endx, 0, al.getHeight() - 1, ypos); + /** + * Draws markers (triangles) above hidden column positions between startColumn + * and endColumn. + * + * @param g + * @param ypos + * @param startColumn + * @param endColumn + */ + protected void drawHiddenColumnMarkers(Graphics g, int ypos, + int startColumn, int endColumn) + { + int charHeight = av.getCharHeight(); + int charWidth = av.getCharWidth(); - if (av.isShowAnnotation()) - { - g.translate(0, cHeight + ypos + 3); - if (annotations == null) - { - annotations = new AnnotationPanel(av); - } + g.setColor(Color.blue); ++ int res; + HiddenColumns hidden = av.getAlignment().getHiddenColumns(); - List positions = hidden.findHiddenRegionPositions(); - for (int pos : positions) + - annotations.renderer.drawComponent(annotations, av, g, -1, startRes, - endx + 1); - g.translate(0, -cHeight - ypos - 3); - } - g.setClip(clip); - g.translate(-labelWidthWest, 0); ++ Iterator it = hidden.getBoundedStartIterator(startColumn, ++ endColumn); ++ while (it.hasNext()) + { - int res = pos - startColumn; ++ res = it.next() - startColumn; - ypos += cHeight + annotationHeight + hgap; + if (res < 0 || res > endColumn - startColumn + 1) + { + continue; + } - startRes += cWidth; + /* + * draw a downward-pointing triangle at the hidden columns location + * (before the following visible column) + */ + int xMiddle = res * charWidth; + int[] xPoints = new int[] { xMiddle - charHeight / 4, + xMiddle + charHeight / 4, xMiddle }; + int yTop = ypos - (charHeight / 2); + int[] yPoints = new int[] { yTop, yTop, yTop + 8 }; + g.fillPolygon(xPoints, yPoints, 3); } } diff --cc test/jalview/datamodel/SequenceTest.java index b9f93c3,c0cb09c..549f13a --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@@ -1674,17 -1674,133 +1674,147 @@@ public class SequenceTes } @Test(groups = { "Functional" }) + public void testGapBitset() + { + SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--"); + BitSet bs = sq.gapBitset(); + BitSet expected = new BitSet(); + expected.set(0); + expected.set(4, 7); + expected.set(9); + expected.set(11, 13); + + assertTrue(bs.equals(expected)); + + } ++ + public void testFindFeatures_largeEndPos() + { + /* + * imitate a PDB sequence where end is larger than end position + */ + SequenceI sq = new Sequence("test", "-ABC--DEF--", 1, 20); + sq.createDatasetSequence(); + + assertTrue(sq.findFeatures(1, 9).isEmpty()); + // should be no array bounds exception - JAL-2772 + assertTrue(sq.findFeatures(1, 15).isEmpty()); + + // add feature on BCD + SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 2, 4, 2f, + null); + sq.addSequenceFeature(sfBCD); + + // no features in columns 1-2 (-A) + List found = sq.findFeatures(1, 2); + assertTrue(found.isEmpty()); + + // columns 1-6 (-ABC--) includes BCD + found = sq.findFeatures(1, 6); + assertEquals(1, found.size()); + assertTrue(found.contains(sfBCD)); + + // columns 10-11 (--) should find nothing + found = sq.findFeatures(10, 11); + assertEquals(0, found.size()); + } + + @Test(groups = { "Functional" }) + public void testSetName() + { + SequenceI sq = new Sequence("test", "-ABC---DE-F--"); + assertEquals("test", sq.getName()); + assertEquals(1, sq.getStart()); + assertEquals(6, sq.getEnd()); + + sq.setName("testing"); + assertEquals("testing", sq.getName()); + + sq.setName("test/8-10"); + assertEquals("test", sq.getName()); + assertEquals(8, sq.getStart()); + assertEquals(13, sq.getEnd()); // note end is recomputed + + sq.setName("testing/7-99"); + assertEquals("testing", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); // end may be beyond physical end + + sq.setName("/2-3"); + assertEquals("", sq.getName()); + assertEquals(2, sq.getStart()); + assertEquals(7, sq.getEnd()); + + sq.setName("test/"); // invalid + assertEquals("test/", sq.getName()); + assertEquals(2, sq.getStart()); + assertEquals(7, sq.getEnd()); + + sq.setName("test/6-13/7-99"); + assertEquals("test/6-13", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/0-5"); // 0 is invalid - ignored + assertEquals("test/0-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/a-5"); // a is invalid - ignored + assertEquals("test/a-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/6-5"); // start > end is invalid - ignored + assertEquals("test/6-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/5"); // invalid - ignored + assertEquals("test/5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/-5"); // invalid - ignored + assertEquals("test/-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/5-"); // invalid - ignored + assertEquals("test/5-", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/5-6-7"); // invalid - ignored + assertEquals("test/5-6-7", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName(null); // invalid, gets converted to space + assertEquals("", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + } + + @Test(groups = { "Functional" }) + public void testCheckValidRange() + { + Sequence sq = new Sequence("test/7-12", "-ABC---DE-F--"); + assertEquals(7, sq.getStart()); + assertEquals(12, sq.getEnd()); + + /* + * checkValidRange ensures end is at least the last residue position + */ + PA.setValue(sq, "end", 2); + sq.checkValidRange(); + assertEquals(12, sq.getEnd()); + + /* + * end may be beyond the last residue position + */ + PA.setValue(sq, "end", 22); + sq.checkValidRange(); + assertEquals(22, sq.getEnd()); + } }