From b3cd7fa160c1323a80af9dd69d13e1a45e7c189c Mon Sep 17 00:00:00 2001 From: kiramt Date: Tue, 16 Jan 2018 15:45:59 +0000 Subject: [PATCH] JAL-2759 setup hideBitSet over range for hideInsertions --- src/jalview/datamodel/HiddenColsIterator.java | 6 ++ src/jalview/datamodel/HiddenColumns.java | 81 ++++++++++++++++++++++++- src/jalview/gui/PopupMenu.java | 41 +++---------- test/jalview/gui/PopupMenuTest.java | 30 ++++++--- 4 files changed, 116 insertions(+), 42 deletions(-) diff --git a/src/jalview/datamodel/HiddenColsIterator.java b/src/jalview/datamodel/HiddenColsIterator.java index 55a3d8b..0084912 100644 --- a/src/jalview/datamodel/HiddenColsIterator.java +++ b/src/jalview/datamodel/HiddenColsIterator.java @@ -102,4 +102,10 @@ public class HiddenColsIterator implements Iterator currentPosition++; return currentRegion; } + + @Override + public void remove() + { + localHidden.remove(--currentPosition); + } } diff --git a/src/jalview/datamodel/HiddenColumns.java b/src/jalview/datamodel/HiddenColumns.java index 49f82f5..037afc4 100644 --- a/src/jalview/datamodel/HiddenColumns.java +++ b/src/jalview/datamodel/HiddenColumns.java @@ -1121,7 +1121,7 @@ public class HiddenColumns * Hide columns corresponding to the marked bits * * @param inserts - * - columns map to bits starting from zero + * - columns mapped to bits starting from zero */ public void hideColumns(BitSet inserts) { @@ -1144,6 +1144,85 @@ public class HiddenColumns } /** + * Hide columns corresponding to the marked bits, within the range + * [start,end]. Entries in tohide which are outside [start,end] are ignored. + * + * @param tohide + * columns mapped to bits starting from zero + * @param start + * start of range to hide columns within + * @param end + * end of range to hide columns within + */ + public void hideColumns(BitSet tohide, int start, int end) + { + clearHiddenColumnsInRange(start, end); + + // make sure only bits between start and end are set + tohide.clear(0, start - 1); + tohide.clear(Math.min(end + 1, tohide.length() - 1), + tohide.length() - 1); + + hideColumns(tohide); + } + + /** + * Make all columns in the range [start,end] visible + * + * @param start + * start of range to show columns + * @param end + * end of range to show columns + */ + private void clearHiddenColumnsInRange(int start, int end) + { + try + { + LOCK.writeLock().lock(); + + HiddenCursorPosition pos = cursor.findRegionForColumn(start); + int index = pos.getRegionIndex(); + int startindex = index; // first index in hiddenColumns to remove + + if (index != -1 && index != hiddenColumns.size()) + { + // regionIndex is the region which either contains start + // or lies to the right of start + int[] region = hiddenColumns.get(index); + if (region[0] < start && region[1] >= start) + { + // region contains start, truncate so that it ends just before start + region[1] = start - 1; + startindex++; + } + } + + pos = cursor.findRegionForColumn(end); + index = pos.getRegionIndex(); + int endindex = index - 1; // last index in hiddenColumns to remove + + if (index != -1 && index != hiddenColumns.size()) + { + // regionIndex is the region which either contains end + // or lies to the right of end + int[] region = hiddenColumns.get(index); + if (region[0] <= end && region[1] > end) + { + // region contains end, truncate so that it starts just after end + region[0] = end + 1; + } + } + + hiddenColumns.subList(startindex, endindex + 1).clear(); + cursor.resetCursor(hiddenColumns); + numColumns = 0; + } finally + { + LOCK.writeLock().unlock(); + } + } + + /** * * @param inserts * BitSet where hidden columns will be marked diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 1e4116d..9bc2ca1 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -1453,15 +1453,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener protected void hideInsertions_actionPerformed(ActionEvent actionEvent) { - - HiddenColumns hidden = new HiddenColumns(); - BitSet inserts = new BitSet(), mask = new BitSet(); - - // set mask to preserve existing hidden columns outside selected group - if (ap.av.hasHiddenColumns()) - { - ap.av.getAlignment().getHiddenColumns().markHiddenRegions(mask); - } + HiddenColumns hidden = ap.av.getAlignment().getHiddenColumns(); + BitSet inserts = new BitSet(); boolean markedPopup = false; // mark inserts in current selection @@ -1469,10 +1462,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener { // mark just the columns in the selection group to be hidden inserts.set(ap.av.getSelectionGroup().getStartRes(), - ap.av.getSelectionGroup().getEndRes() + 1); - - // and clear that part of the mask - mask.andNot(inserts); + ap.av.getSelectionGroup().getEndRes() + 1); // TODO why +1? // now clear columns without gaps for (SequenceI sq : ap.av.getSelectionGroup().getSequences()) @@ -1483,29 +1473,18 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } inserts.and(sq.getInsertionsAsBits()); } - } - else - { - // initially, mark all columns to be hidden - inserts.set(0, ap.av.getAlignment().getWidth()); - - // and clear out old hidden regions completely - mask.clear(); + hidden.hideColumns(inserts, ap.av.getSelectionGroup().getStartRes(), + ap.av.getSelectionGroup().getEndRes()); } // now mark for sequence under popup if we haven't already done it - if (!markedPopup && sequence != null) + else if (!markedPopup && sequence != null) { - inserts.and(sequence.getInsertionsAsBits()); - } + inserts.or(sequence.getInsertionsAsBits()); - // finally, preserve hidden regions outside selection - inserts.or(mask); - - // and set hidden columns accordingly - hidden.hideColumns(inserts); - - ap.av.getAlignment().setHiddenColumns(hidden); + // and set hidden columns accordingly + hidden.hideColumns(inserts); + } refresh(); } diff --git a/test/jalview/gui/PopupMenuTest.java b/test/jalview/gui/PopupMenuTest.java index 7e077d0..8f60021 100644 --- a/test/jalview/gui/PopupMenuTest.java +++ b/test/jalview/gui/PopupMenuTest.java @@ -573,14 +573,8 @@ public class PopupMenuTest // get sequences from the alignment List seqs = parentPanel.getAlignment().getSequences(); - // get the Popup Menu for first sequence - no insertions - testee = new PopupMenu(parentPanel, (Sequence) seqs.get(0), null); - testee.hideInsertions_actionPerformed(null); - - HiddenColumns hidden = parentPanel.av.getAlignment().getHiddenColumns(); - Iterator it = hidden.iterator(); - assertFalse(it.hasNext()); - + // add our own seqs to avoid problems with changes to existing sequences + // (gap at end of sequences varies depending on how tests are run!) Sequence seqGap1 = new Sequence("GappySeq", "AAAA----AA-AAAAAAA---AAA-----------AAAAAAAAAA--"); seqGap1.createDatasetSequence(); @@ -589,10 +583,26 @@ public class PopupMenuTest "AAAAAA-AAAAA---AAA--AAAAA--AAAAAAA-AAAAAA"); seqGap2.createDatasetSequence(); seqs.add(seqGap2); - Sequence seqGap3 = new Sequence("OneGapSeq", + Sequence seqGap3 = new Sequence("AnotherGapSeq", "AAAAAA-AAAAAA--AAAAAA-AAAAAAAAAAA---AAAAAAAA"); seqGap3.createDatasetSequence(); seqs.add(seqGap3); + Sequence seqGap4 = new Sequence("NoGaps", + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + seqGap4.createDatasetSequence(); + seqs.add(seqGap4); + + ColumnSelection sel = new ColumnSelection(); + parentPanel.av.getAlignment().getHiddenColumns() + .revealAllHiddenColumns(sel); + + // get the Popup Menu for 7th sequence - no insertions + testee = new PopupMenu(parentPanel, (Sequence) seqs.get(7), null); + testee.hideInsertions_actionPerformed(null); + + HiddenColumns hidden = parentPanel.av.getAlignment().getHiddenColumns(); + Iterator it = hidden.iterator(); + assertFalse(it.hasNext()); // get the Popup Menu for GappySeq - this time we have insertions testee = new PopupMenu(parentPanel, (Sequence) seqs.get(4), null); @@ -627,7 +637,7 @@ public class PopupMenuTest assertFalse(it.hasNext()); - ColumnSelection sel = new ColumnSelection(); + sel = new ColumnSelection(); hidden.revealAllHiddenColumns(sel); // make a sequence group and hide insertions within the group -- 1.7.10.2