From 744e4ade5413aa7e8006a8d4d29fdb718489bf08 Mon Sep 17 00:00:00 2001 From: Ben Soares Date: Tue, 1 Aug 2023 20:22:14 +0100 Subject: [PATCH] JAL-244 More control of automatic idWidth adjustments. Added tests. --- src/jalview/bin/Commands.java | 16 +- src/jalview/gui/AlignmentPanel.java | 16 +- src/jalview/gui/AnnotationLabels.java | 11 ++ src/jalview/gui/IdwidthAdjuster.java | 3 +- src/jalview/gui/StructureChooser.java | 4 +- src/jalview/gui/StructureViewer.java | 24 ++- test/jalview/gui/AnnotationLabelsTest2.java | 238 +++++++++++++++++++++++++++ 7 files changed, 288 insertions(+), 24 deletions(-) create mode 100644 test/jalview/gui/AnnotationLabelsTest2.java diff --git a/src/jalview/bin/Commands.java b/src/jalview/bin/Commands.java index e1c88e1..5211fa7 100644 --- a/src/jalview/bin/Commands.java +++ b/src/jalview/bin/Commands.java @@ -6,7 +6,6 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -553,20 +552,7 @@ public class Commands String sViewer = ArgParser.getFromSubValArgOrPref(avm, Arg.STRUCTUREVIEWER, Position.AFTER, av, subVals, null, null, "jmol"); - ViewerType viewerType = null; - if (!"none".equals(sViewer)) - { - for (ViewerType v : EnumSet.allOf(ViewerType.class)) - { - String name = v.name().toLowerCase(Locale.ROOT) - .replaceAll(" ", ""); - if (sViewer.equals(name)) - { - viewerType = v; - break; - } - } - } + ViewerType viewerType = ViewerType.getFromString(sViewer); // TODO use ssFromStructure StructureViewer sv = StructureChooser diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index c7c03b3..98639be 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -596,14 +596,20 @@ public class AlignmentPanel extends GAlignmentPanel implements annotationHeight); hscroll.addNotify(); - annotationScroller.setPreferredSize( - new Dimension(annotationScroller.getWidth(), annotationHeight)); - Dimension e = idPanel.getSize(); - alabels.setSize(new Dimension(e.width, annotationHeight)); + int idWidth = e.width; + boolean manuallyAdjusted = this.getIdPanel().getIdCanvas() + .manuallyAdjusted(); + annotationScroller.setPreferredSize(new Dimension( + manuallyAdjusted ? idWidth : annotationScroller.getWidth(), + annotationHeight)); + + alabels.setPreferredSize(new Dimension(idWidth, annotationHeight)); annotationSpaceFillerHolder.setPreferredSize(new Dimension( - annotationSpaceFillerHolder.getWidth(), annotationHeight)); + manuallyAdjusted ? idWidth + : annotationSpaceFillerHolder.getWidth(), + annotationHeight)); annotationScroller.validate(); annotationScroller.addNotify(); ap.validate(); diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index c4a40d8..255e1ff 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -1218,7 +1218,13 @@ public class AnnotationLabels extends JPanel { // If no manual adjustment to ID column with has been made then adjust // width match widest of alignment or annotation id widths + boolean allowShrink = Cache.getDefault("ALLOW_SHRINK_ID_WIDTH", + false); width = Math.max(alignmentIdWidth, newAnnotationIdWidth); + if (clip && width < givenWidth && !allowShrink) + { + width = givenWidth; + } } else if (newAnnotationIdWidth != annotationIdWidth && newAnnotationIdWidth > givenWidth @@ -1268,6 +1274,11 @@ public class AnnotationLabels extends JPanel public int drawLabels(Graphics g, boolean clip, int width, boolean actuallyDraw, FontMetrics fmetrics) { + if (clip) + { + clip = Cache.getDefault("MOVE_SEQUENCE_ID_WITH_VISIBLE_ANNOTATIONS", + true); + } int actualWidth = 0; if (g != null) { diff --git a/src/jalview/gui/IdwidthAdjuster.java b/src/jalview/gui/IdwidthAdjuster.java index 0ebdfa1..6de3c97 100755 --- a/src/jalview/gui/IdwidthAdjuster.java +++ b/src/jalview/gui/IdwidthAdjuster.java @@ -154,7 +154,8 @@ public class IdwidthAdjuster extends JPanel public void setWidth(int newWidth) { - if (newWidth < MIN_ID_WIDTH) + if (newWidth < MIN_ID_WIDTH + || ap.getIdPanel().getIdCanvas().manuallyAdjusted()) { return; } diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index 6fce984..d63c94a 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -71,7 +71,6 @@ import jalview.gui.structurechooser.PDBStructureChooserQuerySource; import jalview.gui.structurechooser.StructureChooserQuerySource; import jalview.gui.structurechooser.ThreeDBStructureChooserQuerySource; import jalview.io.DataSourceType; -import jalview.io.FileFormatException; import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; import jalview.jbgui.FilterOption; @@ -85,7 +84,6 @@ import jalview.util.StringUtils; import jalview.ws.DBRefFetcher; import jalview.ws.DBRefFetcher.FetchFinishedListenerI; import jalview.ws.datamodel.alphafold.PAEContactMatrix; -import jalview.ws.dbsources.EBIAlfaFold; import jalview.ws.seqfetcher.DbSourceProxy; import jalview.ws.sifts.SiftsSettings; @@ -1801,7 +1799,9 @@ public class StructureChooser extends GStructureChooser sc.mainFrame.dispose(); if (showRefAnnotations) + { showReferenceAnnotationsForSequence(ap.alignFrame, seq); + } return sv; } diff --git a/src/jalview/gui/StructureViewer.java b/src/jalview/gui/StructureViewer.java index 6cef665..ad3fc6a 100644 --- a/src/jalview/gui/StructureViewer.java +++ b/src/jalview/gui/StructureViewer.java @@ -21,9 +21,11 @@ package jalview.gui; import java.util.ArrayList; +import java.util.EnumSet; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; @@ -66,7 +68,27 @@ public class StructureViewer public enum ViewerType { - JMOL, CHIMERA, CHIMERAX, PYMOL + JMOL, CHIMERA, CHIMERAX, PYMOL; + + public static ViewerType getFromString(String viewerString) + { + ViewerType viewerType = null; + if (!"none".equals(viewerString)) + { + for (ViewerType v : EnumSet.allOf(ViewerType.class)) + { + String name = v.name().toLowerCase(Locale.ROOT).replaceAll(" ", + ""); + if (viewerString.equals(name)) + { + viewerType = v; + break; + } + } + } + return viewerType; + } + }; /** diff --git a/test/jalview/gui/AnnotationLabelsTest2.java b/test/jalview/gui/AnnotationLabelsTest2.java new file mode 100644 index 0000000..e8fa9f1 --- /dev/null +++ b/test/jalview/gui/AnnotationLabelsTest2.java @@ -0,0 +1,238 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.gui; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.io.File; + +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import jalview.bin.Cache; +import jalview.bin.Jalview; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; +import jalview.gui.StructureViewer.ViewerType; +import jalview.io.DataSourceType; +import jalview.io.FileLoader; +import jalview.structure.StructureImportSettings.TFType; + +public class AnnotationLabelsTest2 +{ + @BeforeClass(alwaysRun = true) + public static void setUpBeforeClass() throws Exception + { + if (Desktop.instance != null) + Desktop.instance.closeAll_actionPerformed(null); + + setUpJvOptionPane(); + /* + * use read-only test properties file + */ + Cache.loadProperties("test/jalview/io/testProps.jvprops"); + Jalview.main(new String[] { "--nonews", "--nosplash", }); + } + + @AfterMethod(alwaysRun = true) + public void tearDown() + { + if (Desktop.instance != null) + Desktop.instance.closeAll_actionPerformed(null); + } + + /** + * configure (read-only) properties for test to ensure Consensus is computed + * for colour Above PID testing + */ + @BeforeMethod(alwaysRun = true) + public void setUp() + { + Cache.loadProperties("test/jalview/io/testProps.jvprops"); + Cache.applicationProperties.setProperty("SHOW_IDENTITY", + Boolean.TRUE.toString()); + + } + + public static void setUpJvOptionPane() + { + JvOptionPane.setInteractiveMode(false); + JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); + } + + @Test( + groups = + { "Functional", "testTask1" }, + dataProvider = "openFilesWithIdWidthChanges") + public void testIdWidthChanges(String alignmentFilename, int idWidth1min, + int idWidth1max, int manualWidth, String structureFilename, + String paeFilename, boolean secondaryStructureView, + TFType temperatureFactorType, ViewerType viewerType, + int idWidth2min, int idWidth2max) + { + AlignFrame af = new FileLoader() + .LoadFileWaitTillLoaded(alignmentFilename, DataSourceType.FILE); + try + { + Thread.sleep(200); // to allow alignment annotations to open + } catch (InterruptedException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + AlignViewport av = af.getCurrentView(); + + int idWidth = 0; + + idWidth = av.getIdWidth(); + assertTrue(idWidth > idWidth1min, + "idWidth (" + idWidth + ") is not greater than " + idWidth1min); + assertTrue(idWidth < idWidth1max, "idWidth (" + idWidth + + ") is not less wide than" + idWidth1max); + + AlignmentI al = av.getAlignment(); + SequenceI s = al.getSequenceAt(0); + AlignmentPanel ap = af.alignPanel; + + File structureFile = new File(structureFilename); + File paeFile = new File(paeFilename); + + StructureViewer sv = StructureChooser.openStructureFileForSequence(null, + null, ap, s, false, structureFile.getAbsolutePath(), + temperatureFactorType, paeFile.getAbsolutePath(), true, + secondaryStructureView, false, viewerType); + // give time for annotations to open + try + { + Thread.sleep(200); // to allow alignment annotations to open + } catch (InterruptedException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + idWidth = av.getIdWidth(); + assertTrue(idWidth > idWidth2min, + "idWidth (" + idWidth + ") is not greater than " + idWidth2min); + assertTrue(idWidth < idWidth2max, "idWidth (" + idWidth + + ") is not less wide than" + idWidth2max); + } + + @Test( + groups = + { "Functional", "testTask1" }, + dataProvider = "openFilesWithIdWidthChanges") + public void testIdWidthNoChanges(String alignmentFilename, + int idWidth1min, int idWidth1max, int manualWidth, + String structureFilename, String paeFilename, + boolean secondaryStructureView, TFType temperatureFactorType, + ViewerType viewerType, int idWidth2min, int idWidth2max) + { + AlignFrame af = new FileLoader() + .LoadFileWaitTillLoaded(alignmentFilename, DataSourceType.FILE); + try + { + Thread.sleep(200); // to allow alignment annotations to open + } catch (InterruptedException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + AlignViewport av = af.getCurrentView(); + + int idWidth = 0; + + idWidth = av.getIdWidth(); + assertTrue(idWidth > idWidth1min, + "idWidth (" + idWidth + ") is not greater than " + idWidth1min); + assertTrue(idWidth < idWidth1max, "idWidth (" + idWidth + + ") is not less wide than" + idWidth1max); + + AlignmentI al = av.getAlignment(); + SequenceI s = al.getSequenceAt(0); + AlignmentPanel ap = af.alignPanel; + + // set width manually + av.setIdWidth(manualWidth); + ap.validateAnnotationDimensions(false); + ap.paintAlignment(true, false); + ap.getIdPanel().getIdCanvas().setManuallyAdjusted(true); + + idWidth = av.getIdWidth(); + assertEquals(idWidth, manualWidth, + "idWidth is not set to the manually set width " + manualWidth); + + File structureFile = new File(structureFilename); + File paeFile = new File(paeFilename); + + StructureViewer sv = StructureChooser.openStructureFileForSequence(null, + null, ap, s, false, structureFile.getAbsolutePath(), + temperatureFactorType, paeFile.getAbsolutePath(), false, + secondaryStructureView, false, viewerType); + + idWidth = ap.getIdPanel().getWidth();// av.getIdWidth(); + idWidth = av.getIdWidth(); + assertEquals(idWidth, manualWidth, + "idWidth is not set to the manually set width " + manualWidth + + " after adding structure annotations"); + assertFalse(idWidth > idWidth2min, + "idWidth (" + idWidth + ") is greater than " + idWidth2min); + } + + @DataProvider(name = "openFilesWithIdWidthChanges") + public Object[][] openFilesWithIdWidthChanges() + { + /* + String alignmentFilename, + int idWidth1min, + int idWidth1max, + int manualWidth, // ignored by testIdWidthChanges() + String structureFilename, + String paeFilename, + boolean secondaryStructureView, + TFType temperatureFactorType, + ViewerType viewerType, + int idWidth2min, + int idWidth2max, + */ + return new Object[][] { + // + /* + */ + { + // + "./test/files/annotation_label_width/sample.a2m", 50, 70, 100, + "./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb", + "./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3_scores.json", + true, TFType.PLDDT, null, 115, 130 + // + }, + /* + */ + }; + } + +} -- 1.7.10.2