<li><!-- JAL-384 -->Custom shading schemes created via groovy scripts</li>
<li><!-- JAL-2491 -->linked scrolling of CDS/Protein views via Overview or sequence motif search operations</li>
<li><!-- JAL-2526 -->Efficiency improvements for interacting with alignment and overview windows</li>
+ <li><!-- JAL-2388 -->Hidden columns and sequences can be omitted in Overview</li>
<li>
<!-- JAL-2535 -->Posterior probability annotation from
Stockholm files imported as sequence associated annotation
extension when importing structure files without embedded
names or PDB accessions
</li>
+ <li><!-- JAL-2547 -->Amend sequence features dialog box can be opened by double clicking gaps within sequence feature extent</li>
</ul>
<em>Application</em>
<ul>
<li><!-- --></li>
</ul>
<em>Test Suite</em>
- <li><!-- JAL-2474 -->Added PrivelegedAccessor to test suite</li>
+ <li><!-- JAL-2474 -->Added PrivilegedAccessor to test suite</li>
<li><!-- JAL-2326 -->Prevent or clear modal dialogs raised during tests</li>
<li><!-- -->
</ul>
<li>
<!-- JAL-2398, -->Fixed incorrect value in BLOSUM 62 score
matrix - C->R should be '3'<br />Old matrix restored with
- this one-line groovy script:<br />jalview.schemes.ResidueProperties.BLOSUM62[4][1]=3
+ this one-line groovy script:<br />jalview.analysis.scoremodels.ScoreModels.instance.BLOSUM62.@matrix[4][1]=3
</li>
<li>
<!-- JAL-2397 -->Fixed Jalview's treatment of gaps in PCA
<li><!-- JAL-2385 -->Colour threshold slider doesn't update to reflect currently selected view or group's shading thresholds</li>
<li><!-- JAL-2373 -->Percentage identity and conservation menu items do not show a tick or allow shading to be disabled</li>
<li><!-- JAL-2385 -->Conservation shading or PID threshold lost when base colourscheme changed if slider not visible</li>
- <li><!-- JAL-2547 -->Sequence features shown in tooltip for gaps before start of features</li>
+ <li><!-- JAL-2547 -->Sequence features shown in tooltip for gaps before start of features</li>
</ul>
<em>Application</em>
<ul>
Jalview Projects rather than fetched via URL again when
the project is loaded and the structure viewed
</li>
+ <li><!-- JAL-1256 -->Trackpad horizontal scroll gesture adjusts start position in wrap mode</li>
+ <li><!-- JAL-2563 -->Status bar doesn't show positions for ambiguous amino acids</li>
</ul>
<em>Applet</em>
<ul>
<em>New Known Issues</em>
<ul>
<li><!-- JAL-2566 -->Protein/CDS view scrolling not always in phase after a sequence motif find operation</li>
- <li><!-- JAL-2563 -->Status bar doesn't show positions for ambiguous amino acids</li>
<li><!-- JAL-2550 -->Importing annotation file with rows containing just upper and lower case letters are interpreted as WUSS rna secondary structure symbols</li>
</ul>
public List<SequenceI> showAll(
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
- List<SequenceI> revealedSeqs = new ArrayList<SequenceI>();
+ List<SequenceI> revealedSeqs = new ArrayList<>();
+
+ if (hiddenSequences == null)
+ {
+ return revealedSeqs;
+ }
+
for (int i = 0; i < hiddenSequences.length; i++)
{
if (hiddenSequences[i] != null)
public List<SequenceI> showSequence(int alignmentIndex,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
- List<SequenceI> revealedSeqs = new ArrayList<SequenceI>();
+ List<SequenceI> revealedSeqs = new ArrayList<>();
SequenceI repSequence = alignment.getSequenceAt(alignmentIndex);
if (repSequence != null && hiddenRepSequences != null
&& hiddenRepSequences.containsKey(repSequence))
*/
if (centre)
{
- int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2 - 1;
+ int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2
+ - 1;
start = Math.max(start - offset, 0);
end = end + offset - 1;
}
}
else
{
- av.getRanges().scrollToVisible(seqCanvas.cursorX, seqCanvas.cursorY,
- av);
+ av.getRanges().scrollToVisible(seqCanvas.cursorX, seqCanvas.cursorY);
}
setStatusMessage(av.getAlignment().getSequenceAt(seqCanvas.cursorY),
seqCanvas.cursorX, seqCanvas.cursorY);
return null;
}
- public static DataSourceType checkProtocol(String file)
+ /**
+ * Determines the protocol (i.e DataSourceType.{FILE|PASTE|URL}) for the input
+ * data
+ *
+ * @param data
+ * @return the protocol for the input data
+ */
+ public static DataSourceType checkProtocol(String data)
{
- DataSourceType protocol = DataSourceType.FILE;
- String ft = file.toLowerCase().trim();
+ DataSourceType protocol = DataSourceType.PASTE;
+ String ft = data.toLowerCase().trim();
if (ft.indexOf("http:") == 0 || ft.indexOf("https:") == 0
|| ft.indexOf("file:") == 0)
{
protocol = DataSourceType.URL;
}
+ else if (new File(data).exists())
+ {
+ protocol = DataSourceType.FILE;
+ }
return protocol;
}
*/
package jalview.viewmodel;
-import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.HiddenColumns;
public void setStartEndRes(int start, int end)
{
int oldstartres = this.startRes;
- if (start > al.getWidth() - 1)
+ if (start > getVisibleAlignmentWidth() - 1)
{
- startRes = al.getWidth() - 1;
+ startRes = getVisibleAlignmentWidth() - 1;
}
else if (start < 0)
{
{
endRes = 0;
}
+ else if (end > getVisibleAlignmentWidth() - 1)
+ {
+ endRes = getVisibleAlignmentWidth() - 1;
+ }
else
{
endRes = end;
{
int startres = res;
int width = getViewportWidth();
- if (startres + width - 1 > al.getWidth() - 1)
+ if (startres + width - 1 > getVisibleAlignmentWidth() - 1)
{
- startres = al.getWidth() - width;
+ startres = getVisibleAlignmentWidth() - width;
}
setStartEndRes(startres - width + 1, startres);
}
{
int startseq = seq;
int height = getViewportHeight();
- if (startseq + height - 1 > al.getHeight() - 1)
+ if (startseq + height - 1 > getVisibleAlignmentHeight() - 1)
{
- startseq = al.getHeight() - height;
+ startseq = getVisibleAlignmentHeight() - height;
}
setStartEndSeq(startseq, startseq + height - 1);
}
public void setStartEndSeq(int start, int end)
{
int oldstartseq = this.startSeq;
- if (start > al.getHeight() - 1)
+ if (start > getVisibleAlignmentHeight() - 1)
{
- startSeq = al.getHeight() - 1;
+ startSeq = getVisibleAlignmentHeight() - 1;
}
else if (start < 0)
{
}
int oldendseq = this.endSeq;
- if (end >= al.getHeight())
+ if (end >= getVisibleAlignmentHeight())
{
- endSeq = al.getHeight() - 1;
+ endSeq = getVisibleAlignmentHeight() - 1;
}
else if (end < 0)
{
{
vpstart = 0;
}
- else if (vpstart + w - 1 > al.getWidth() - 1)
+ else if ((w <= getVisibleAlignmentWidth())
+ && (vpstart + w - 1 > getVisibleAlignmentWidth() - 1))
+ // viewport width is less than the full alignment and we are running off the
+ // RHS edge
{
- vpstart = al.getWidth() - 1;
+ vpstart = getVisibleAlignmentWidth() - w;
}
setStartEndRes(vpstart, vpstart + w - 1);
}
{
vpstart = 0;
}
- else if (vpstart + h - 1 > al.getHeight() - 1)
+ else if ((h <= getVisibleAlignmentHeight())
+ && (vpstart + h - 1 > getVisibleAlignmentHeight() - 1))
+ // viewport height is less than the full alignment and we are running off
+ // the bottom
{
- vpstart = al.getHeight() - h;
+ vpstart = getVisibleAlignmentHeight() - h;
}
setStartEndSeq(vpstart, vpstart + h - 1);
}
}
else
{
- if (endSeq >= al.getHeight() - 1)
+ if (endSeq >= getVisibleAlignmentHeight() - 1)
{
return false;
}
}
else
{
- if (endRes > al.getWidth() - 1)
+ if (endRes >= getVisibleAlignmentWidth() - 1)
{
return false;
}
* x position in alignment
* @param y
* y position in alignment
- * @param av
- * viewport to be visible in. Here until hidden columns JAL-2388
- * merged, then use alignment to get hidden cols
*/
- public void scrollToVisible(int x, int y, AlignViewportI av)
+ public void scrollToVisible(int x, int y)
{
while (y < startSeq)
{
* local structure files should yield a false ID based on the filename
*/
assertNotNull(structureData.getId());
- assertEquals(structureData.getId(), "localstruct.pdb");
+ assertEquals(structureData.getId(), "localstruct");
assertNotNull(structureData.getSeqs());
/*
* the ID is also the group for features derived from structure data
String featureGroup = structureData.getSeqs().get(0)
.getSequenceFeatures().get(0).featureGroup;
assertNotNull(featureGroup);
- assertEquals(featureGroup, "localstruct.pdb");
-
+ assertEquals(featureGroup, "localstruct");
}
}
import jalview.gui.StructureViewer.ViewerType;
import jalview.io.DataSourceType;
-import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
}
}
- @Test(groups = { "Functional", "Network" })
- public void testStructureLoadingViaURL()
- {
- Cache.setProperty(Preferences.STRUCTURE_DISPLAY, ViewerType.JMOL.name());
- String inFile = "http://www.jalview.org/builds/develop/examples/3W5V.pdb";
- AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
- inFile, DataSourceType.URL);
- assertTrue("Didn't read input file " + inFile, af != null);
- for (SequenceI sq : af.getViewport().getAlignment().getSequences())
- {
- SequenceI dsq = sq.getDatasetSequence();
- while (dsq.getDatasetSequence() != null)
- {
- dsq = dsq.getDatasetSequence();
- }
- if (dsq.getAllPDBEntries() != null
- && dsq.getAllPDBEntries().size() > 0)
- {
- for (int q = 0; q < dsq.getAllPDBEntries().size(); q++)
- {
- final StructureViewer structureViewer = new StructureViewer(af
- .getViewport().getStructureSelectionManager());
- structureViewer.setViewerType(ViewerType.JMOL);
- JalviewStructureDisplayI jmolViewer = structureViewer
- .viewStructures(dsq.getAllPDBEntries().elementAt(q),
- new SequenceI[] { sq }, af.getCurrentView()
- .getAlignPanel());
- /*
- * Wait for viewer load thread to complete
- */
- try
- {
- while (!jmolViewer.getBinding().isFinishedInit())
- {
- Thread.sleep(500);
- }
- } catch (InterruptedException e)
- {
- }
- // System.out.println(">>>>>>>>>>>>>>>>> "
- // + jmolViewer.getBinding().getPdbFile());
- String[] expectedModelFiles = new String[] { "http://www.jalview.org/builds/develop/examples/3W5V.pdb" };
- String[] actualModelFiles = jmolViewer.getBinding().getStructureFiles();
- Assert.assertEqualsNoOrder(actualModelFiles, expectedModelFiles);
- jmolViewer.closeViewer(true);
- // todo: break here means only once through this loop?
- break;
- }
- break;
- }
- }
- }
+
}
StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
sc.populateFilterComboBox(false, false);
int optionsSize = sc.getCmbFilterOption().getItemCount();
- assertEquals(3, optionsSize); // if structures are not discovered then don't
+ assertEquals(2, optionsSize); // if structures are not discovered then don't
// populate filter options
sc.populateFilterComboBox(true, false);
fileLoader.LoadFileWaitTillLoaded(urlFile, DataSourceType.URL,
FileFormat.PDB);
Assert.assertNotNull(fileLoader.file);
- // The FileLoader's file is expected to a temporary file different from the
- // original URL.
- Assert.assertNotEquals(urlFile, fileLoader.file);
- // Data source type expected to be updated from DataSourceType.URL to
- // DataSourceType.FILE
- Assert.assertEquals(DataSourceType.FILE, fileLoader.protocol);
+ // The FileLoader's file is expected to be same as the original URL.
+ Assert.assertEquals(urlFile, fileLoader.file);
+ // Data source type expected to be DataSourceType.URL
+ Assert.assertEquals(DataSourceType.URL, fileLoader.protocol);
}
}
import jalview.analysis.AlignmentGenerator;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.HiddenSequences;
import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class ViewportRangesTest {
AlignmentI al = gen.generate(20, 30, 1, 5, 5);
+ AlignmentI smallAl = gen.generate(7, 2, 2, 5, 5);
+
+ @BeforeMethod
+ public void cleanUp()
+ {
+ ColumnSelection sel = new ColumnSelection();
+ al.getHiddenColumns().revealAllHiddenColumns(sel);
+ al.getHiddenSequences().showAll(null);
+ }
+
@Test(groups = { "Functional" })
public void testViewportRanges()
{
assertEquals(vr.getEndRes(), 19);
vr.setStartEndRes(al.getWidth(), al.getWidth());
- assertEquals(vr.getEndRes(), al.getWidth());
+ assertEquals(vr.getEndRes(), al.getWidth() - 1);
+
+ ViewportRanges vrsmall = new ViewportRanges(smallAl);
+ vrsmall.setStartEndRes(al.getWidth(), al.getWidth());
+ assertEquals(vrsmall.getEndRes(), 6);
}
@Test(groups = { "Functional" })
// reset out of bounds start values to within bounds
vr.setViewportStartAndWidth(35, 5);
assertEquals(vr.getViewportWidth(), 5);
- assertEquals(vr.getStartRes(), 20);
+ assertEquals(vr.getStartRes(), 16);
+
+ // small alignment doesn't get bounds reset
+ ViewportRanges vrsmall = new ViewportRanges(smallAl);
+ vrsmall.setViewportStartAndWidth(0, 63);
+ assertEquals(vrsmall.getViewportWidth(), 7);
+ assertEquals(vrsmall.getStartRes(), 0);
}
@Test(groups = { "Functional" })
vr.pageDown();
// pagedown to bottom does not go beyond end, and height stays same
- assertEquals(vr.getStartSeq(), 23);
+ assertEquals(vr.getStartSeq(), 24);
assertEquals(vr.getViewportHeight(), 6);
}
vr.scrollUp(true);
assertEquals(vr.getStartSeq(), 0);
+ vr.setViewportStartAndHeight(24, 5);
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 25);
+ // can't scroll beyond bottom
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 25);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testScrollUpWithHidden()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+
+ // hide last sequence
+ HiddenSequences hidden = new HiddenSequences(al);
+ hidden.hideSequence(al.getSequenceAt(29));
+
+ vr.setViewportStartAndHeight(1, 5);
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 0);
+ // can't scroll above top
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 0);
+
vr.setViewportStartAndHeight(23, 5);
vr.scrollUp(false);
assertEquals(vr.getStartSeq(), 24);
vr.scrollRight(false);
assertEquals(vr.getStartRes(), 0);
- vr.setViewportStartAndWidth(19, 5);
+ vr.setViewportStartAndWidth(15, 5);
vr.scrollRight(true);
- assertEquals(vr.getStartRes(), 20);
+ assertEquals(vr.getStartRes(), 16);
// can't scroll right past end
vr.scrollRight(true);
- assertEquals(vr.getStartRes(), 20);
+ assertEquals(vr.getStartRes(), 16);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testScrollRightWithHidden()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+
+ // hide last 2 columns
+ HiddenColumns cols = new HiddenColumns();
+ cols.hideColumns(19, 20);
+ al.setHiddenColumns(cols);
+
+ vr.setViewportStartAndWidth(1, 5);
+ vr.scrollRight(false);
+ assertEquals(vr.getStartRes(), 0);
+ // can't scroll left past start
+ vr.scrollRight(false);
+ assertEquals(vr.getStartRes(), 0);
+
+ vr.setViewportStartAndWidth(13, 5);
+ vr.scrollRight(true);
+ assertEquals(vr.getStartRes(), 14);
+ // can't scroll right past last visible col
+ vr.scrollRight(true);
+ assertEquals(vr.getStartRes(), 14);
}
@Test(groups = { "Functional" })
{
ViewportRanges vr = new ViewportRanges(al);
MockPropChangeListener l = new MockPropChangeListener(vr);
- List<String> emptylist = new ArrayList<String>();
+ List<String> emptylist = new ArrayList<>();
vr.setViewportWidth(5);
vr.setViewportHeight(5);
assertTrue(l.verify(1, Arrays.asList("startres")));
l.reset();
- // TODO test scrollToVisibble once hidden columns JAL-2388 merged in
- // to avoid somersaults with align viewport
- /*vr.scrollToVisible(10, 10);
- assertTrue(l.verify(1, Arrays.asList("startres")));
- l.reset();*/
+ vr.scrollToVisible(10, 10);
+ assertTrue(l.verify(4,
+ Arrays.asList("startseq", "startseq", "startseq", "startseq")));
+ l.reset();
vr.scrollToWrappedVisible(5);
assertTrue(l.verify(1, Arrays.asList("startres")));
{
private int firecount = 0;
- private List<String> events = new ArrayList<String>();
+ private List<String> events = new ArrayList<>();
- private List<Integer> newvalues = new ArrayList<Integer>();
+ private List<Integer> newvalues = new ArrayList<>();
public MockPropChangeListener(ViewportRanges vr)
{