Merge branch 'develop' into bug/JAL-4289_group_boundary_not_drawn_properly_in_fastpai... bug/JAL-4289_group_boundary_not_drawn_properly_in_fastpaint_or_paint
authorBen Soares <b.soares@dundee.ac.uk>
Wed, 25 Oct 2023 10:28:15 +0000 (11:28 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Wed, 25 Oct 2023 10:28:15 +0000 (11:28 +0100)
144 files changed:
build.gradle
doc/building.md
examples/groovy/ComputePeptideVariants.groovy
examples/groovy/JvLoadTester.groovy
examples/groovy/PIDmatrix.groovy
examples/groovy/alignLoadedFile.groovy
examples/groovy/annotationForSelectedSequence.groovy
examples/groovy/parseproperties.groovy
examples/groovy/printtitle.groovy
examples/groovy/removeFeaturesByGroup.groovy
examples/groovy/selectColumnsByFeatureAndGroup.groovy
examples/groovy/sitesForSelectedColumns.groovy
examples/groovy/stripUniprotPrefixes.groovy
examples/groovy/visibleFeaturesCounter.groovy
getdown/lib/FJVL_VERSION
getdown/lib/JVL_VERSION
getdown/lib/getdown-core.jar
getdown/lib/getdown-launcher-local.jar
getdown/lib/getdown-launcher.jar
getdown/src/getdown/ant/pom.xml
getdown/src/getdown/core/pom.xml
getdown/src/getdown/core/src/main/java/com/threerings/getdown/data/Application.java
getdown/src/getdown/launcher/pom.xml
getdown/src/getdown/mvn_cmd
getdown/src/getdown/pom.xml
gradle.properties
help/help/html/features/annotation.html
help/help/html/features/clarguments-reference.html
help/help/html/features/groovy.html
help/help/html/features/paematrices.html
help/help/html/features/search.html
help/help/html/features/search.png
help/help/html/features/viewingpdbs.html
help/help/html/groovy/featuresCounter.html
help/help/html/menus/alwannotationpanel.html
help/markdown/releases/release-2_11_3_0.md
help/markdown/whatsnew/whatsnew-2_11_3_0.md
help/templates/whatsNew.html
j11lib/getdown-core.jar
j11lib/groovy-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-all-2.4.21-indy.jar [deleted file]
j11lib/groovy-ant-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-astbuilder-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-cli-commons-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-cli-picocli-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-console-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-contracts-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-datetime-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-dateutil-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-docgenerator-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-ginq-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-groovydoc-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-groovysh-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-jmx-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-json-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-jsr223-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-macro-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-macro-library-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-nio-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-servlet-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-sql-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-swing-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-templates-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-test-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-test-junit5-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-testng-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-toml-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-typecheckers-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-xml-4.0.15.jar [new file with mode: 0644]
j11lib/groovy-yaml-4.0.15.jar [new file with mode: 0644]
j11lib/javaparser-core-3.25.5.jar [new file with mode: 0644]
j8lib/getdown-core.jar
j8lib/groovy-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-all-2.4.21-indy.jar [deleted file]
j8lib/groovy-ant-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-astbuilder-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-cli-commons-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-cli-picocli-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-console-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-contracts-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-datetime-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-dateutil-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-docgenerator-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-ginq-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-groovydoc-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-groovysh-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-jmx-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-json-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-jsr223-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-macro-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-macro-library-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-nio-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-servlet-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-sql-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-swing-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-templates-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-test-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-test-junit5-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-testng-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-toml-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-typecheckers-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-xml-4.0.15.jar [new file with mode: 0644]
j8lib/groovy-yaml-4.0.15.jar [new file with mode: 0644]
j8lib/javaparser-core-3.25.5.jar [new file with mode: 0644]
resources/lang/Messages.properties
src/jalview/analysis/TreeModel.java
src/jalview/bin/Cache.java
src/jalview/bin/Commands.java
src/jalview/bin/Console.java
src/jalview/bin/Jalview.java
src/jalview/bin/argparser/Arg.java
src/jalview/bin/argparser/ArgParser.java
src/jalview/bin/argparser/BootstrapArgs.java
src/jalview/bin/groovy/JalviewObject.java [new file with mode: 0644]
src/jalview/bin/groovy/JalviewObjectI.java [new file with mode: 0644]
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/SearchResultMatchI.java
src/jalview/datamodel/SearchResults.java
src/jalview/datamodel/SearchResultsI.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/Console.java
src/jalview/gui/Desktop.java
src/jalview/gui/JvOptionPane.java
src/jalview/gui/QuitHandler.java
src/jalview/gui/SplashScreen.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/WsJobParameters.java
src/jalview/io/DataSourceType.java
src/jalview/io/FileLoader.java
src/jalview/io/VamsasAppDatastore.java
src/jalview/project/Jalview2XML.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/structures/models/AAStructureBindingModel.java
src/jalview/workers/AlignmentAnnotationFactory.java
test/jalview/bin/CommandsTest.java
test/jalview/bin/CommandsTest2.java
test/jalview/datamodel/SearchResultsTest.java
test/jalview/gui/DesktopTests.java
test/jalview/io/CrossRef2xmlTests.java
test/jalview/io/cache/JvCacheableInputBoxTest.java
test/jalview/project/Jalview2xmlTests.java
test/jalview/renderer/seqfeatures/FeatureRendererTest.java

index c4ed582..e5abc77 100644 (file)
@@ -52,7 +52,7 @@ plugins {
   id 'application'
   id 'eclipse'
   id "com.diffplug.gradle.spotless" version "3.28.0"
-  id 'com.github.johnrengelman.shadow' version '4.0.3'
+  id 'com.github.johnrengelman.shadow' version '7.1.2'
   id 'com.install4j.gradle' version '10.0.3'
   id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
   id 'com.palantir.git-version' version '0.13.0' apply false
@@ -1783,6 +1783,27 @@ task testTask1(type: Test) {
   }
 }
 
+task testTask2(type: Test) {
+  group = "Verification"
+  description = "Tests that need to be isolated from the main test run"
+  useTestNG() {
+    includeGroups name
+    excludeGroups testng_excluded_groups.split(",")
+    preserveOrder true
+    useDefaultListeners=true
+  }
+}
+task testTask3(type: Test) {
+  group = "Verification"
+  description = "Tests that need to be isolated from the main test run"
+  useTestNG() {
+    includeGroups name
+    excludeGroups testng_excluded_groups.split(",")
+    preserveOrder true
+    useDefaultListeners=true
+  }
+}
+
 /* insert more testTaskNs here -- change N to next digit or other string */
 /*
 task testTaskN(type: Test) {
@@ -1830,7 +1851,9 @@ tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { te
     showExceptions true
     showCauses true
     showStackTraces true
-
+    if (test_output) {
+      showStandardStreams true
+    }
     info.events = [ TestLogEvent.FAILED ]
   }
 
@@ -2133,12 +2156,33 @@ shadowJar {
   if (buildDist) {
     dependsOn makeDist
   }
-  from ("${jalviewDir}/${libDistDir}") {
-    include("*.jar")
-  }
-  manifest {
-    attributes "Implementation-Version": JALVIEW_VERSION,
-    "Application-Name": applicationName
+
+  def jarFiles = fileTree(dir: "${jalviewDir}/${libDistDir}", include: "*.jar", exclude: "regex.jar").getFiles()
+  def groovyJars = jarFiles.findAll {it1 -> file(it1).getName().startsWith("groovy-swing")}
+  def otherJars = jarFiles.findAll {it2 -> !file(it2).getName().startsWith("groovy-swing")}
+  from groovyJars
+  from otherJars
+
+  // we need to include the groovy-swing Include-Package for it to run in the shadowJar
+  doFirst {
+    def jarFileManifests = []
+    groovyJars.each { jarFile ->
+      def mf = zipTree(jarFile).getFiles().find { it.getName().equals("MANIFEST.MF") }
+      if (mf != null) {
+        jarFileManifests += mf
+      }
+    }
+
+    manifest {
+      attributes "Implementation-Version": JALVIEW_VERSION, "Application-Name": applicationName
+      from (jarFileManifests) {
+        eachEntry { details ->
+          if (!details.key.equals("Import-Package")) {
+            details.exclude()
+          }
+        }
+      }
+    }
   }
 
   duplicatesStrategy "INCLUDE"
index 34d5d67..aee827d 100644 (file)
@@ -336,7 +336,7 @@ the `tests/` folder.  A summary of results should appear in your console.
 You can run different defined groups of tests with
 
 ```bash
-gradle test -PtestngGroups=Network
+gradle test -Ptestng_groups=Network
 ```
 
 Available groups include Functional (default), Network, External. 
@@ -348,9 +348,15 @@ Some of Jalview's Functional tests don't pass reliably in all environments. We t
 To exclude one or more groups of tests, add them as a comma separated list in testngExcludedGroups.
 
 ```bash
-gradle test -PtestngExcludedGroups=Not-bamboo
+gradle test -Ptestng_excluded_groups=Not-bamboo
 ```
+#### Viewing stdout and stderr for tests
 
+By default, gradle doesn't report any of the output or error streams produced by tests. You can enable output by setting the following:
+
+```bash
+gradle test -Ptest_output=1
+```
 
 ### Installer packaging with *install4j*
 
index 6caa69c..e5ece51 100644 (file)
@@ -1,6 +1,6 @@
 import jalview.datamodel.SequenceFeature
 import jalview.gui.Desktop
-def af = jalview.bin.Jalview.currentAlignFrame
+def af = Jalview.getCurrentAlignFrame()
 def av = af.viewport
 def fr = Desktop.getAlignFrameFor(av.codingComplement).getFeatureRenderer()
 def counts = 0
@@ -29,4 +29,4 @@ for (seq in av.alignment.sequences)
 }
 af.getFeatureRenderer().featuresAdded()
 af.alignPanel.paintAlignment(true, true)
-println "Added " + countm + " missense and " + counts + " synonymous variants"
\ No newline at end of file
+println "Added " + countm + " missense and " + counts + " synonymous variants"
index d844d62..cc92e40 100644 (file)
@@ -21,7 +21,7 @@
 import jalview.gui.*;
 import jalview.io.*;
 
-def class JvLoadTest {
+class JvLoadTest {
     FileLoader fl = null;
     def String safename = null;
     JvLoadTest(String sname) { 
@@ -155,4 +155,4 @@ def JvLoadTest newJvLoadTest(String tempFile) {
        System.gc();
        jalview.gui.Desktop.instance.desktop.showMemoryUsage(true);
        return new JvLoadTest(tempFile)
-}
\ No newline at end of file
+}
index b97abcc..76b9de7 100644 (file)
@@ -56,7 +56,7 @@ printSimilarityMatrix(true,true,SimilarityParams.Jalview)
 
 void printSimilarityMatrix(boolean selview=false, boolean includeids=true, SimilarityParams pidMethod) {
 
-  def currentAlignFrame = jalview.bin.Jalview.getCurrentAlignFrame()
+  def currentAlignFrame = Jalview.getCurrentAlignFrame()
 
   jalview.gui.AlignViewport av = currentAlignFrame.getCurrentView()
 
@@ -96,4 +96,4 @@ void printSimilarityMatrix(boolean selview=false, boolean includeids=true, Simil
 
     print "\n"
   }
-}
\ No newline at end of file
+}
index 764fdae..df68e2b 100644 (file)
@@ -20,6 +20,7 @@
  */
 // run an alignment on the current alignFrame
 import jalview.ws.jws2.*;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.datamodel.*;
 
 // First get the JABA service discoverer and see if there are any services.
@@ -33,7 +34,7 @@ if (!disc.isRunning() && !disc.hasServices())
   disc.run();
 }
 
-for (jalview.ws.jws2.Jws2Discoverer.Jws2Instance service: disc.getServices()) {
+for (jalview.ws.jws2.jabaws2.Jws2Instance service: disc.getServices()) {
 
 if (service.serviceType.indexOf("uscle")>-1) {
   // now - go through the services if any, and find a Muscle service
index abfad35..7cb3082 100644 (file)
@@ -31,7 +31,7 @@ import java.awt.datatransfer.StringSelection
 import static java.awt.Toolkit.*
 
 
-def curviewport = Jalview.getAlignFrames()[Jalview.getAlignFrames().length-1].getViewport();
+def curviewport = Jalview.getCurrentAlignFrame().getViewport();
 
 // TSV output by default.
 // change "\t" to "," to output CSV file
index 879bd49..ceec6d2 100644 (file)
@@ -1,19 +1,19 @@
 /*
  * 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 
+ * 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 
+ *
+ * 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 <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
@@ -23,10 +23,9 @@ import jalview.datamodel.*;
 import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
 
-def af = Jalview.getAlignFrames();
-def al = af[0].viewport.alignment;
+def al = Jalview.getCurrentAlignFrame().viewport.alignment;
 ParseProperties pp = new ParseProperties(al);
-pp.getScoresFromDescription("Score", "ScanPS Raw Score", "([-0-9.+]+)");
+pp.getScoresFromDescription("Score", "ScanPS Raw Score", "([-0-9.+]+)", true);
 def sqs = al.getSequenceAt(0);
 def annots = sqs.getAnnotation();
 
index b3387ea..a048d65 100644 (file)
@@ -1,35 +1,35 @@
 /*
  * 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 
+ * 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 
+ *
+ * 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 <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 // do something groovy in jalview
 println "Hello World.\n"
-println "First sequence is " + currentAlFrame.viewport.alignment.getSequenceAt(0).getDisplayId(true)
+println "First sequence is " + Jalview.getCurrentAlignFrame().viewport.alignment.getSequenceAt(0).getDisplayId(true)
 
 def alf = Jalview.getAlignFrames()
 for (ala in alf)
 {
-       // ala is an jalview.gui.AlignFrame object 
+       // ala is an jalview.gui.AlignFrame object
        println ala.getTitle()
        // get the parent jalview.datamodel.Alignment from the alignment viewport
        def alignment = ala.viewport.alignment
        // get the first sequence from the jalview.datamodel.Alignment object
-       def seq = alignment.getSequenceAt(0) 
+       def seq = alignment.getSequenceAt(0)
 }
 Jalview.quit()
index 341e06f..c947a5b 100644 (file)
@@ -46,6 +46,7 @@ for (ala in af)
                        }
                }
        }
+       ala.repaint();
 }
        
 
index b8edaa7..aaa3405 100644 (file)
@@ -23,7 +23,7 @@ import jalview.datamodel.*;
 import jalview.gui.AlignFrame;
 import jalview.gui.AlignViewport;
 import java.util.BitSet;
-import javax.swing.JOptionPane;
+import jalview.gui.JvOptionPane;
 import groovy.swing.SwingBuilder;
 def toselect = getFeatureInput(); // change this to select the desired feature type
 
@@ -81,7 +81,7 @@ for (ala in Jalview.getAlignFrames()) {
         cs.addElement(i);
         }
       ala.viewport.setColumnSelection(cs);
-      ala.alignPanel.paintAlignment(true);
+      ala.alignPanel.paintAlignment(true, true);
       ala.statusBar.setText("Marked "+bs.cardinality()+" columns containing features of type "+toselect)
       } else {
         ala.statusBar.setText("No features of type "+toselect+" found.");
@@ -96,4 +96,4 @@ String getFeatureInput(){
                    null, 'Select columns by feature by type','Enter type of feature', JvOptionPane.OK_OPTION)
 
         return response
-    }
\ No newline at end of file
+    }
index 8165373..f775f18 100644 (file)
@@ -29,7 +29,7 @@
 import java.awt.datatransfer.StringSelection
 import static java.awt.Toolkit.*
 
-def curviewport = Jalview.getAlignFrames()[Jalview.getAlignFrames().length-1].getViewport()
+def curviewport = Jalview.getCurrentAlignFrame().getViewport()
 
 def debug = false
 
index 71b3a9f..5a01da4 100644 (file)
@@ -29,7 +29,7 @@ def af = Jalview.getAlignFrames();
 
 for (ala in af)
 {
-       def al = ala.viewport.alignment;
+       def al = ala.getViewport().getAlignment();
        if (al!=null)
        {
                SequenceI[] seqs = al.getSequencesArray();
@@ -47,5 +47,6 @@ for (ala in af)
                        }
                }
        }
+       ala.repaint();
 }
-       
\ No newline at end of file
+       
index b3180f8..510f600 100644 (file)
@@ -1,38 +1,37 @@
 /*
  * 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 
+ * 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 
+ *
+ * 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 <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
-import jalview.bin.Jalview
 import jalview.workers.FeatureSetCounterI
 import jalview.workers.AlignmentAnnotationFactory
 
 /*
  * Demonstration of FeatureSetCounterI
- * compute annotation tracks counting number of displayed 
+ * compute annotation tracks counting number of displayed
  * features of each type in each column
  */
 
 /*
  * discover features on the current view
  */
-def featuresDisp=Jalview.currentAlignFrame.currentView.featuresDisplayed
+
+def featuresDisp=Jalview.getCurrentAlignFrame().currentView.featuresDisplayed
 if (featuresDisp == null) {
     print 'Need at least one feature visible on alignment'
 }
@@ -40,12 +39,12 @@ def visibleFeatures=featuresDisp.visibleFeatures.toList()
 assert 'java.util.ArrayList' == visibleFeatures.class.name
 
 /*
- * A closure that returns an array of features present 
+ * A closure that returns an array of features present
  * for each feature type in visibleFeatures
- * Argument 'features' will be a list of SequenceFeature 
+ * Argument 'features' will be a list of SequenceFeature
  */
-def getCounts = 
-    { features -> 
+def getCounts =
+    { features ->
         int[] obs = new int[visibleFeatures.size]
         for (sf in features)
         {
@@ -56,9 +55,9 @@ def getCounts =
              * or sf.getValue(attributeName) for GFF 'column 9' properties
              */
             int pos = 0
-            for (type in visibleFeatures) 
+            for (type in visibleFeatures)
             {
-              if (type.equals(sf.type)) 
+              if (type.equals(sf.type))
               {
                   obs[pos]++
               }
@@ -67,19 +66,19 @@ def getCounts =
         }
         obs
 }
-  
+
 /*
  * Define something that counts each visible feature type
  */
 def columnSetCounter =
     [
-     getNames: { visibleFeatures as String[] }, 
+     getNames: { visibleFeatures as String[] },
      getDescriptions:  { visibleFeatures as String[] },
      getMinColour: { [0, 255, 255] as int[] }, // cyan
      getMaxColour: { [0, 0, 255] as int[] }, // blue
-     count: 
-         { res, feats -> 
-             getCounts.call(feats) 
+     count:
+         { res, feats ->
+             getCounts.call(feats)
          }
      ] as FeatureSetCounterI
 
index 25d39f4..2d83e61 100644 (file)
@@ -1 +1 @@
-1.8.3-1.3.0_FJVL
+1.8.3-1.3.1_FJVL
index 12110b2..7d618e2 100644 (file)
@@ -1 +1 @@
-1.8.3-1.3.0_JVL
+1.8.3-1.3.1_JVL
index fb8f1bc..3fc97b5 100644 (file)
Binary files a/getdown/lib/getdown-core.jar and b/getdown/lib/getdown-core.jar differ
index c74dcc5..6ba0a6d 100644 (file)
Binary files a/getdown/lib/getdown-launcher-local.jar and b/getdown/lib/getdown-launcher-local.jar differ
index e1f1726..7c75a34 100644 (file)
Binary files a/getdown/lib/getdown-launcher.jar and b/getdown/lib/getdown-launcher.jar differ
index d8bb7e9..4c91f74 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.threerings.getdown</groupId>
     <artifactId>getdown</artifactId>
-    <version>1.8.3-1.3.0_FJVL</version>
+    <version>1.8.3-1.3.1_FJVL</version>
   </parent>
 
   <artifactId>getdown-ant</artifactId>
index 6126686..2e43522 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.threerings.getdown</groupId>
     <artifactId>getdown</artifactId>
-    <version>1.8.3-1.3.0_FJVL</version>
+    <version>1.8.3-1.3.1_FJVL</version>
   </parent>
 
   <artifactId>getdown-core</artifactId>
index 9d9fe14..435ebbd 100644 (file)
@@ -1137,7 +1137,6 @@ public class Application
                 String query = jalviewUri.getQuery();
                 
                 _appargs.clear();
-                _appargs.add("-open");
                 if (host != null && host.length() > 0) {
                   URL newUrl = new URL(
                           (https?"https":"http")
@@ -1253,8 +1252,6 @@ public class Application
           }
           if (ext != null && LOCATOR_FILE_EXTENSION.equals(ext.toLowerCase(Locale.ROOT))) {
             // this file extension should have been dealt with in Getdown class
-          } else {
-            _appargs.add(0, "-open");
           }
         }
 
index 4374899..c6b9ff3 100644 (file)
@@ -4,7 +4,7 @@
   <parent>
     <groupId>com.threerings.getdown</groupId>
     <artifactId>getdown</artifactId>
-    <version>1.8.3-1.3.0_FJVL</version>
+    <version>1.8.3-1.3.1_FJVL</version>
   </parent>
 
   <artifactId>getdown-launcher</artifactId>
index ba092a7..10942f8 100755 (executable)
@@ -3,7 +3,7 @@
 if [ x$JVLVERSION != x ]; then
   export VERSION=$JVLVERSION
 else
-  export VERSION=1.8.3-1.3.0_JVL
+  export VERSION=1.8.3-1.3.1_JVL
 fi
 
 if [ x${VERSION%_JVL} = x$VERSION ]; then
index 51e9514..cf32333 100644 (file)
@@ -10,7 +10,7 @@
   <groupId>com.threerings.getdown</groupId>
   <artifactId>getdown</artifactId>
   <packaging>pom</packaging>
-  <version>1.8.3-1.3.0_FJVL</version>
+  <version>1.8.3-1.3.1_FJVL</version>
 
   <name>getdown</name>
   <description>An application installer and updater.</description>
index c2e217f..79fb11d 100644 (file)
@@ -28,6 +28,8 @@ jalview_keydig = SHA1
 
 testng_groups = Functional
 testng_excluded_groups = 
+test_output =
 
 j8libDir = j8lib
 j11libDir = j11lib
index b63d20b..76b23eb 100755 (executable)
@@ -29,7 +29,7 @@
 
   <p>
     In addition to the definition of groups and sequence features,
-    Jalview can display symbols and graphs under the columns of an
+    Jalview can display symbols, line graphs, histograms and heatmaps under the columns of an
     alignment. These annotation tracks are displayed in the annotation
     area below the alignment. The annotation area's visibility is
     controlled with the <strong>View&#8594;Show Annotation</strong>
   <ul>
     <li><a name="seqannots"><strong>Sequence
           associated annotation.</strong></a><br />Data displayed on sequence
-      annotation rows are associated with the positions of a sequence.
+      associated annotation rows are associated with the positions of a sequence.
       Often this is 'Reference annotation' such as secondary structure
       information derived from 3D structure data, or from the results of
       sequence based prediction of <a href="../webServices/jnet.html">secondary
         structure</a> and <a href="../webServices/proteinDisorder.html">disorder</a>.
-      If reference annotation is available for a the currently selected
-      sequences, it can be shown by selecting the <strong>Add
+      If reference annotations are available for a particular sequence or the current selections, they can be shown by selecting the <strong>Add
         Reference Annotation</strong> option in the sequence or selection popup
-      menu.</li>
+      menu.<br/>Jalview currently supports the following sources of sequence associated annotation:<ul><li>Protein and RNA Secondary Structure<br/>These can be obtained from JPred and RNAAliFold secondary structure prediction services, and also for imported 3D Structure data.</li><li>Temperature factor, Model Quality or AlphaFold Reliability</br>Jalview extracts and displays values from the 'Temperature Factor' column of PDB and mmCIF files, interpreted in various ways. For regular PDB files, these are imported directly as 'Temperature Factor', but for structures from computational methods such as EBI-AlphaFold, these values are interpreted and shown as 'AlphaFold Reliability' or 'Model Quality' according to the source.</li><li><a href="paematrices.html">Predicted Alignment Error</a> heatmaps<br/>These are displayed for models retrieved from EBI-AlphaFold or when a supported JSON format PAE file is provided when importing a <a href="structurechooser.html#loadpdbfile">local 3D structure file</a>.</li></ul></li>
     <li><strong>Group associated annotation.</strong><br />Data can
       be associated with groups defined on the alignment. If sequence
       groups are defined, <a href="../calculations/conservation.html">Conservation</a>
       alignment</a>. Annotations can also be used to <a
       href="../features/columnFilterByAnnotation.html">select or
       hide columns</a> via the dialog opened from the <strong>Selection</strong>
-    menu.
+    menu. You can also colour, select or hide columns of the alignment using any displayed annotation row by right-clicking its label and selecting the option from the displayed pop-up menu.
   </p>
   <p>
+    <strong>Adjusting the height of histograms, line graphs and heatmaps</strong><br/>The height of line graphs, bar charts and <a href="paematrices.html">predicted alignment error (PAE) matrix heatmaps</a> can be adjusted simply by click-dragging them up or down to increase or decrease the height. Hold down <em><strong>SHIFT</strong></em> to adjust the height of all instances of a particular type of annotation row.</p>
+  <p>
     <strong>Sequence Highlighting and Selection from Annotation</strong>
   </p>
   <p>
       (Mac CMD) double-click</strong> will toggle inclusion of associated
     sequences in the selection.
   <p>
+    <strong>Selecting, analysing and exploring heatmap annotation</strong>
+  </p><p>Mouseovers on heap annotation tracks result in a tooltip displaying information about the range of values under the mouse, and their associated row and column in the heatmap.<br/>For <a href="paematrices.html">Predicted Alignment Error (PAE) matrices</a>, the only form of heatmap annotation currently supported by Jalview, both the vertical and horizontal positions in the heatmap correspond to positions in linked 3D structures and the associated sequence in the alignment - so clicking any position in a heatmap will select columns in the alignment corresponding to the selected row(s) and column under the mouse.
+    <ul>
+      <li>Rows and columns in the heatmap corresponding to currently selected columns in the alignment are shown as red horizontal and vertical bands.</li>
+      <li><em>Rectangular Selections</em> can be created by pressing <em>CMD (or Window/Meta key)</em> whilst click-dragging across an area of the annotation.</li>
+      <li><em>Data driven selections</em> - e.g. selecting regions of low values of Predicted Alignment Error in a heatmap can be dome by pressing <em>CTRL</em> whilst clicking a region of an alignment.</li>
+    </ul>
+    Heatmap annotations can also be clustered, enabling columns of the alignment to be grouped based on similarity of the sets of values in the heatmap. <em>Double clicking</em> a region of a clustered heatmap annotation will select both the row and columns of the alignment grouped by the clustering. See <a href="paematrices.html#clustering">clustering PAE matrices</a> for more information.
+  <p>
     <strong>Interactive Alignment Annotation</strong>
   </p>
   <p>
         in 2.5)</em><br> <em>Selecting this toggles whether column
         labels will be shrunk to fit within each column, or displayed
         using the view's standard font size.</em></li>
+    <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+    <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+    <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+    <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+    <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+    <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+    
   </ul>
   <p>
     <strong>Editing labels and secondary structure annotation
index b2e29e9..b1588e5 100644 (file)
     </tr>
 
     <tr valign="top">
+    <td><code>&#8209;&#8209;javaconsole / &#8209;&#8209;nojavaconsole</code></td>
+    <td>Show (/ or don't show) the Java Console.  Using one of these overrides any saved Preference.</td>
+    </tr>
+
+    <tr valign="top">
     <td><code>&#8209;&#8209;questionnaire / &#8209;&#8209;noquestionnaire</code></td>
     <td>Show (/ or don't show) the questionnaire if one is available.</td>
     </tr>
index cb0b10c..6b5c4c0 100644 (file)
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
 <head>
-<title>Groovy Shell</title>
+<title>Groovy Console</title>
 </head>
 <body>
   <p>
-    <strong>The Groovy Shell</strong>
+    <strong>The Groovy Console</strong>
   </p>
   <p>
     Groovy (<a href="http://www.groovy-lang.org/">www.groovy-lang.org</a>)
@@ -41,8 +41,8 @@
     short pause, you should then see the <a
       href="https://groovy-lang.org/groovyconsole.html">Groovy
       Console</a> appear. This allows you to interactively execute Groovy
-    scripts whilst Jalview is running. We've also provided a <strong>Calculations&#8594;Execute
-      Groovy Script</strong> button so you can execute the currently loaded
+    scripts whilst Jalview is running. We've also provided a <strong>Calculations&#8594;Run
+      Groovy Console Script</strong> button so you can execute the currently loaded
     groovy script whilst viewing an alignment.
   </p>
   <p>
     we recommend you also take a look at Jalview's source, since all the
     public methods of the jalview class hierarchy can be called from
     Groovy scripts. In addition, the following objects are also defined:
+  </p>
 
-
-  
   <ul>
-    <li><strong>Jalview</strong> - this is bound to <code>jalview.bin.Jalview</code>.<br />Useful
-      methods include:
+    <li><strong>Jalview</strong> - this is bound to <code>jalview.bin.groovy.JalviewObject</code> providing access to the following useful
+      methods:
       <ul>
         <li>Jalview.getAlignFrames() - returns a list of
           jalview.gui.AlignFrame objects</li>
         <li>Jalview.getCurrentAlignFrame() - returns the alignment
-          window which is currently being looked at by the user</li>
+          window which has most recently been in focus.  If you change focus to another alignment window then re-running <code>Jalview.getCurrentAlignFrame()</code> will return the new <code>AlignFrame</code>.</li>
       </ul></li>
-    <li><strong>currentAlFrame</strong> - this is only defined when
-      running a Groovy script via the --groovy command line argument. It
-      returns the first alignment window created after acting on the
-      other arguments passed on the command line.</li>
+    <li><strong>currentAlFrame</strong> When used on the command line this refers to the current opened alignment.
+    <br/>
+    When used from the Groovy Console, it refers to the alignment that was in focus when the Groovy Console was opened.
+    <br/>
+    When a Groovy Console script is run from <em>Calculate</em>-&gt;<em>Run Groovy Console Script</em>, <code>currentAlFrame</code> us updated to that alignment.</li>
   </ul>
   <p>
+    If you specify a <code>--groovy</code> argument before an <code>--open</code> argument
+    then you should ensure your script doesn't refer to <code>currentAlFrame</code>.
+  <p>
+
+  <p>
     <em>A simple script</em><br />
   <ul>
     <li>Getting the title, alignment and first sequence from the
       current alignFrame<br> <pre>
-def alf = Jalview.getAlignFrames();
-print alf[0].getTitle();
-def alignment = alf[0].viewport.alignment;
+def al = Jalview.getCurrentAlignFrame();
+print al.getTitle();
+def alignment = al.viewport.alignment;
 def seq = alignment.getSequenceAt(0);
 </pre>
     </li>
index 8d180ee..2f00e19 100644 (file)
                        href="https://alphafold.ebi.ac.uk/entry/O04090">O04090 3D model</a>
                at EBI-AlphaFoldDB).
        </p>
-       <div style="display:flex; flex-wrap:wrap;"align="center" width="100%">
-       <figure><img src="../structures/epas1_annotdetail.png" height="300"/><figcaption>Alignment of EPAS1 homologs from Human, Rat and Cow, with predicted alignment error shown in Jalview</figcaption></figure>
-       <figure><img src="../structures/epas1_pae_ebiaf.png" height="300"/><figcaption>Predicted Alignment Error Matrix<br/>from <a href="https://alphafold.ebi.ac.uk/entry/Q99814">https://alphafold.ebi.ac.uk/entry/Q99814</a></figcaption></figure>
+       <div style="display: flex; flex-wrap: wrap;" align="center"
+               width="100%">
+               <figure>
+                       <img src="../structures/epas1_annotdetail.png" height="300" />
+                       <figcaption>
+                               Alignment of EPAS1 homologs from Human, Rat and Cow<br />with
+                               predicted alignment error shown for Human
+                       </figcaption>
+               </figure>
+               <figure>
+                       <img src="../structures/epas1_pae_ebiaf.png" height="300" />
+                       <figcaption>
+                               Predicted Alignment Error for Human EPAS1<br />from <a
+                                       href="https://alphafold.ebi.ac.uk/entry/Q99814">https://alphafold.ebi.ac.uk/entry/Q99814</a>
+                       </figcaption>
+               </figure>
        </div>
        <p>
                <strong>Importing PAE Matrices</strong>
                        href="../features/structurechooser.html">Jalview's structure
                        chooser</a> GUI. If you have produced your own models and accompanying
                PAE matrices using a pipeline such as ColabFold, then you can load
-               them both together via the
-               <a href="../features/structurechooser.html#loadpdbfile">Load PDB
-                       File</a> dropdown menu in the 3D structure chooser, providing it is
-               in a
+               them both together via the <a
+                       href="../features/structurechooser.html#loadpdbfile">Load PDB
+                       File</a> dropdown menu in the 3D structure chooser, providing it is in a
                <a href="../io/paematrixformat.html">supported PAE format</a>.
        </p>
        <p>
                sequences and locate the option in the Selection submenu. You can do
                this in any alignment window (or view) where a sequence with
                associated PAE data appears.</p>
-       <p></p>
+       <p>
+               <strong>Adjusting the height of PAE matrix annotations</strong>
+       </p>
+       <p>
+               PAE annotations behave in the same way as Jalview's line graph and
+               histogram tracks. Click+dragging up and down with the left (select)
+               mouse button held down will increase or decrease the height of the
+               annotation. You can also hold down <strong><em>SHIFT</em></strong>
+               whilst doing this to adjust the height of all PAE rows at once.
+       </p>
+       <p>PAE matrix annotation rows behave like any other sequence
+               associated annotation, with the following additional features:</p>
+       <ul>
+               <li>The vertical axis of the PAE heatmap is mapped to positions
+                       on the linked 3D structure.
+                       <ul>
+                               <li>Mousing over the matrix shows a tooltip giving information
+                                       on the range of values under the mouse.<br />Positions in the
+                                       associated 3D structure are also highlighted in any linked views.
+                               </li>
+                               <li>Clicking on positions in the matrix selects columns of the
+                                       alignment corresponding to the row and column in the matrix.</li>
+                       </ul>
+               </li>
+               <li>Rectangular selections (created by Cmd (or Alt)+Click
+                       dragging on the matrix) can be created to select multiple ranges of
+                       columns at once.</li>
+               <li>Columns corresponding to adjacent regions with similarly low
+                       levels of predicted alignment error can be selected by Ctrl+Clicking
+                       on a region in the matrix.</li>
+               <li>Columns of an alignment showing a PAE matrix can be grouped
+                       and selected by clustering the matrix.</li>
+       </ul>
+       <p>
+               <strong><a name="clustering">Clustering PAE Matrices</a></strong>
+       </p>
+       <p>PAE matrices are useful for identifying regions of 3D structure
+               predictions that are likely to be positioned in space in the same or
+               similar way as shown in the predicted structure data. Regions of low
+               PAE often correlate with high alphafold reliability (PLDDT) scores,
+               but also complement them since they highlight well-folded regions such
+               as domains, and how well those regions have been predicted to be
+               positioned relative to eachother, which is important when evaluating
+               whether domain-domain interactions or other contacts can be trusted.</p>
+       <p>To make it more easy to identify regions of low PAE, Jalview can
+               cluster the PAE matrix, allowing columns of the matrix to be grouped
+               according to their similarity, using an Average Distance (UPGMA) tree
+               algorithm and the sum of differences between each column's PAE values.</p>
+       <p>
+               <strong><em>dist<sub>ij</sub></em> = &#8741; <em><u>p</u><sub>i</sub>-<u>p</u><sub>j</sub></em>
+                       &#8741;</strong>
+       </p>
+       <p>
+               To create a PAE matrix tree, right click on a PAE annotation's label
+               to open the annotation popup menu, and select <strong><em>Cluster
+                               Matrix</em></strong>. Once the calculation has finished, a tree viewer will open,
+               and columns of the matrix are then partitioned into groups such that
+               the third left-most node from the root is placed in its own group.
+               Colours are randomly assigned to each group, and by default these will
+               also be overlaid on the matrix annotation row.
+       <p>
+       <ul>
+               <li>The PAE matrix tree viewer behaves like other tree views in
+                       Jalview, except selecting nodes or groups of nodes in the tree select
+                       columns in the alignment rather than sequences, and clicking adjust
+                       the matrix's partition.</li>
+               <li>Only one tree and clustering can be defined for a PAE matrix,
+                       regardless of whether it is displayed in different views or
+                       alignments.</li>
+               <li>Double clicking on a position in the PAE annotation where a
+                       clustering has been defined will select both the row and column
+                       clusters for the clicked position. This makes it easy to select
+                       clusters corresponding to pairs of interacting regions.</li>
+               <li>Cluster colours for a PAE matrix can be used to colour
+                       sequences or columns of the alignment via the <strong><em><a
+                                       href="../colourSchemes/annotationColouring.html">Colour by
+                                               Annotation.. dialog</a></em></strong>
+                                               (opened by right-clicking the annotation label
+                       and selecting from the popup menu).
+               </li>
+       </ul>
+       <p>
+               <strong>PAE matrices and Jalview Projects</strong>
+       </p>
+       <p>Any PAE matrices imported to Jalview are saved along side any
+               trees and clustering defined on them in Jalview Projects.</p>
        <p>
                <em>Support for visualision and analysis of predicted alignment
                        error matrices was added in Jalview 2.11.3. </em>
index d559db8..6889d84 100755 (executable)
@@ -36,7 +36,7 @@ td {
   </p>
   <p>The search box is displayed by pressing Control and F or
     selecting &quot;Find...&quot; from the &quot;Search&quot; menu.</p>
-  <img src="search.png" width="400" height="152">
+  <img src="search.png"  height="152">
   <p>&quot;Find next&quot; will find the next occurrence of the
     query and adjust the alignment window view to show it, and
     &quot;Find all&quot; highlights all matches for a query. The
@@ -46,18 +46,24 @@ td {
   <ul>
     <li>The search uses regular expressions. (understands a mixture
       of posix and perl style regex - see below for a summary)</li>
-    <li>Gaps are ignored when matching the query to the sequences
-      in the alignment.</li>
-    <li>Hidden columns can optionally be ignored (<em>since Jalview 2.11</em>)</li>
-    <li>The search is applied to both sequences and their IDs. It can
-      optionally also be applied to the description string (<em>since Jalview
-        2.10</em>), and sequence feature descriptions (<em>since Jalview 2.11.2.5</em>).
-    </li>
-    <li>If a region is selected, then search will <strong>only</strong>
+               <li>If a region is selected, then search will <strong>only</strong>
       be performed on that region.<br />
     <em>Tip: to quickly clear the current selection, click the
         alignment view you wish to search, then press 'Escape'.</em>
     </li>
+    <li>Gaps are ignored when matching the query to the sequences
+      in the alignment.</li>
+    <li>Hidden columns can optionally be ignored (<em>since Jalview 2.11</em>)</li>
+               <li>The search is applied to both sequences and their IDs. <br />
+                       Check boxes also enable searching of:
+                       <ul>
+                               <li><strong>Sequence description</strong> (<em>since Jalview 2.10</em>)
+                               </li>
+                               <li><strong>Sequence Feature</strong> type and description for currently displayed features (<em>since Jalview
+                                               2.11.3.0</em>)
+                               </li>
+                       </ul>
+               </li>
     <li>Tick the &quot;Match Case&quot; box to perform a case
       sensitive search.</li>
     <li>To access a <a href="#queryhistory">previously used
@@ -87,9 +93,11 @@ td {
   <strong>Copying highlighted regions to a new alignment</strong>
   </p>
   <p>
-    You can copy the currently highlighted matching regions of sequences to the clipboard with alt-Command-C.    
+       Press <strong>Copy</strong> button or type Ctrl (Cmd on OSX) + Shift +
+       C to copy highlighted search results to the clipboard, enabling them
+       to be pasted to a new alignment (via Shift+Ctrl (or Cmd) + V).
   </p>
-  <p>
+       <p>
 
     <strong>A quick Regular Expression Guide</strong>
   </p>
index 47c18f4..9178b9a 100644 (file)
Binary files a/help/help/html/features/search.png and b/help/help/html/features/search.png differ
index 947b96b..df76f89 100755 (executable)
@@ -87,7 +87,7 @@
     <strong>Structure Viewers in the Jalview Desktop</strong><br /> The
     <a href="jmol.html">Jmol viewer</a> has been included since Jalview
     2.3. Jalview 2.8.2 included support for <a href="chimera.html">Chimera</a>,
-    provided it is installed and can be launched by Jalview. ChimeraX and PyMOL
+    provided it is installed and can be launched by Jalview. ChimeraX and <a href="pymol.html">PyMOL</a>
     support is included from Jalview 2.11.2. The default
     viewer can be configured in the <a href="preferences.html#structure">Structure
       tab</a> in the <strong>Tools&rarr;Preferences</strong> dialog box.
     un-tick the <strong>Superpose Structures</strong> checkbox.
 
   </p>
-  <p>
-    <em>Superposing structures</em><br/>Jalview superposes structures using
-    the visible portions of any associated sequence alignments. A
-    message in the structure viewer's status bar will be shown if not
-    enough aligned columns were available to perform a superposition.
-  </p>
-  <p>
-  See the <a href="jmol.html">Jmol
-    </a> and <a href="chimera.html">Chimera</a> help pages for
-      more information about their capabilities.</p>
-  
-
-  <p>
+       <p>
+               <em>Superposing structures</em><br />Jalview superposes structures
+               using the currently selected columns (if more than 3 columns are
+               selected), or the visible portions of any associated sequence
+               alignments. Depending on the viewer, Root Mean Squared Deviation (RMS
+               or RMSD) for each pair of superpositions may be output in the
+               structure viewer's console.
+       </p>
+       <p>A message in the structure viewer's status bar will be shown if
+               not enough aligned columns were available to perform a superposition.
+       </p>
+       <p>
+               See the <a href="jmol.html">Jmol</a>, <a href="chimera.html">Chimera/X</a>
+               and <a href="pymol.html">Pymol</a> help pages for more information
+               about their individual capabilities.
+       </p>
+       <p>
     <strong>Retrieving sequences from the PDB</strong><br>You can
     retrieve sequences from the PDB using the <a
       href="pdbsequencefetcher.html">Sequence Fetcher</a>. The sequences
index bd7144e..494dd3e 100644 (file)
@@ -36,7 +36,7 @@
     <li>Copy and paste it into the groovy script console</li>
     <li>Load the example Feredoxin project (the one that opens by
       default when you first launched Jalview)</li>
-    <li>Select <strong>Calculations&#8594;Execute Groovy
+    <li>Select <strong>Calculations&#8594;Run Groovy Console
         Script</strong> from the alignment window's menu bar to run the script on
       the current view.
     </li>
index cd09693..ff53d0b 100755 (executable)
@@ -86,6 +86,7 @@
             highly variable regions.</em></li>
 
         <li>
+       </li>
         <li><strong>Copy Consensus Sequence</strong><br>
           Copies the consensus sequence to the clipboard in Fasta
           format, to allow the consensus sequence to be added to an
index 8eba74a..8847eb2 100644 (file)
@@ -1,40 +1,31 @@
 ---
 version: 2.11.3.0
-date: 2023-07-19
+date: 2023-10-03
 channel: "release"
 ---
 
 ## New Features
 - <!-- JAL-4064 --> Native M1 build for macOS using Adoptium JRE 11 macos-aarch64
-- <!-- JAL-4054 --> Installers built with install4j10
-- <!-- JAL-3676 --> Allow log level configuration via Jalview's Java Console, and a Copy to Clipboard button
-- <!-- JAL-3416 --> FlatLAF default look and feel on Linux, OSX and everywhere else
-
+- <!-- JAL-3416 --> Jalview now uses a standard 'look and feel' (FlatLaf) on Linux, OSX and everywhere else
 - <!-- JAL-4019 --> Ambiguous Base Colourscheme
 - <!-- JAL-4061 --> Find can search sequence features' type and description
 - <!-- JAL-4062 --> Hold down Shift + CMD/CTRL C to copy highlighted regions as new sequences
-- <!-- JAL-1556 --> Quickly enable select and/or colour by for displayed annotation row via its popup menu
+- <!-- JAL-1556 --> Quickly enable select and/or colour by for displayed annotation row via annotation panel popup menu
 - <!-- JAL-4094 --> Shift+Click+Drag to adjust height of all annotation tracks of same type
 - <!-- JAL-4190 --> Pressing escape in tree panel clears any current selection
-
 - <!-- JAL-4089 --> Use selected columns for superposition
 - <!-- JAL-4086 --> Highlight aligned positions on all associated structures when mousing over a column
-
 - <!-- JAL-4221 --> sequence descriptions are updated from database reference sources if not already defined
 - <!-- JAL-4273 --> Visible adjuster marks to grab and adjust annotation panel height and id width
 - <!-- JAL-4260 --> Adjustable ID margin when alignment is wrapped
-
 - <!-- JAL-4274 --> Command line options and configurable bitmap export preferences for height, width and scale factor
 
 ### Improved support for working with computationally determined models
-
 - <!-- JAL-3895 --> Alphafold red/orange/yellow/green colourscheme for structures
 - <!-- JAL-4095 --> Interactive picking of low pAE score regions
 - <!-- JAL-4027 --> contact matrix datatype in Jalview
 - <!-- JAL-4033 --> Selections with visual feedback via contact matrix annotation
-
 - <!-- JAL-3855 --> Discover and import alphafold2 models and metadata from https://alphafold.ebi.ac.uk/
-
 - <!-- JAL-4091 --> Visual indication of relationship with associated sequence to distinguish different sequence associated annotation rows
 - <!-- JAL-4123 --> GUI and command line allows configuration of how temperature factor in imported 3D structure data should be interpreted
 - <!-- JAL-3914 --> Import model reliability scores encoded as temperature factor annotation with their correct name and semantics
@@ -43,17 +34,17 @@ channel: "release"
 - <!-- JAL-4124 --> Store/Restore PAE data and visualisation settings from Jalview Project
 - <!-- JAL-4083 --> Multiple residue sidechain highlighting in structure viewers from PAE mouseovers
 
-
 ### Jalview on the command line
-
 - <!-- JAL-4160,JAL-629,JAL-4262,JAL-4265, --> New command line argument framework allowing flexible batch processing, import of structures, pae matrices and other sequence associated data, and alignment and structure figure generation.
+- <!-- JAL-3830 --> Command-line wrapper script for macOS bundle, linux and Windows installations (bash, powershell and .bat wrappers)
 - <!-- JAL-4121 --> Assume --headless when jalview is run with a command line argument that generates output
 - <!-- JAL-244 --> Automatically adjust Left margin on import to avoid cropping of annotation labels & sequence IDs
 - <!-- JAL-901 --> Specify alignment title on import via --title argument
+- <!-- JAL-4195,JAL-4194,JAL-4193 --> sensible responses from the CLI when things go wrong during image export
+- Add a command line option to set Jalview properties for this session only
+- Add a command line option to suppress opening the startup file for this session
 
 ### Other improvements
-
-
 - <!-- JAL-4250 --> Secondary structure annotation glyphs are rendered anti-aliasing when enabled
 - <!-- JAL-325 --> Helix and Sheet glyphs vertically centered with respect to grey coil secondary structure annotation track
 - <!-- JAL-4253 --> Lower line of the sequence group border does not align with vertical and background residue box
@@ -61,38 +52,18 @@ channel: "release"
 - <!-- JAL-3119 --> Name of alignment and view included in overview window's title
 - <!-- JAL-4213 --> "add reference annotation" add all positions in reference annotation tracks, not just positions in the currently highlighted columns/selection range
 - <!-- JAL-4119 --> EMBL-EBI SIFTS file downloads now use split directories
-
-- <!-- JAL-4195,JAL-4194,JAL-4193 --> sensible responses from the CLI when things go wrong during image export
-Add a command line option to set Jalview properties for this session only
-Add a command line option to suppress opening the startup file for this session
-
-
-JAL-4187        Powershell launcher script fails when given no arguments with the old ArgsParser
-
-known issue ? <!-- JAL-4127    --> 'Reload' for a jalview project results in all windows being duplicated
-
-
-- <!-- JAL-3830 --> Command-line wrapper script for macOS bundle, linux and Windows installations (bash, powershell and .bat wrappers)
 - <!-- JAL-3820 --> In Linux desktops' task-managers, the grouped Jalview windows get a generic name
 - <!-- JAL-4206 --> Improved file chooser's 'recent files' view and added filter for 'All known alignment files'
 - <!-- JAL-4206 --> Relative files added to recent files list via import from command line are selected when Jalview opened from same location
-
-
-       
-## Still in progress (delete on release)
-
-- <!-- JAL-2382 --> Import and display sequence-associated contact predictions in CASP-RR format
-- <!-- JAL-2349 --> Contact prediction visualisation
-- <!-- JAL-2348 --> modularise annotation renderer
+- <!-- JAL-3676 --> Allow log level configuration via Jalview's Java Console, and a Copy to Clipboard button
 
 ### Development and Deployment
-
+- <!-- JAL-4054 --> Installers built with install4j10
 - <!-- JAL-4167 --> Create separate gradle test task for some tests
 - <!-- JAL-4212 --> Prevent gradle test on macOS continuously grabbing focus
 - <!-- JAL-4111 --> Allow gradle build to create suffixed DEVELOP-... builds with channel appbase
 - <!-- JAL-4243 --> Jalview bio.tools description maintained under jalview's git repo and bundled with source release
 
-
 ## Issues Resolved
 - <!-- JAL-2961 --> Jmol view not always centred on structures when multiple structures are viewed
 - <!-- JAL-3776 --> Cancelling interactive calculation leaves empty progress bar.
@@ -116,10 +87,12 @@ known issue ? <!-- JAL-4127        --> 'Reload' for a jalview project results in all wi
 - <!-- JAL-4189 --> macOS Dock and KDE taskbar names Jalview icon "java" when running
 - <!-- JAL-2910 --> HeadlessException in console in headless mode (actually fixed in 2.11.{0,1,2))
 
-
 ## New Known defects
+- <!-- JAL-4303 --> EBI-AlphaFold PLDDT colours cannot be overlaid on alignment via 'Colour by annotation' unless the alignment's colourscheme has been set to 'None' via the Colours menu.
+- <!-- JAL-4302 --> Tree renderer doesn't show bottom-most leaves of tree when Fit-To-Window is enabled.
 - <!-- JAL-4178 --> Cannot cancel structure view open action once it has been started via the structure chooser dialog
 - <!-- JAL-4142 --> Example project's multiple views do not open in distinct locations when eXpand views is used to show them all separately
+- <!-- JAL-4127 --> 'Reload' for a jalview project results in all windows being duplicated
 - <!-- JAL-4165 --> Missing last letter when copying consensus sequence from alignment if first column is hidden
 - <!-- JAL-4261 --> Last sequence ID in alignment not shown and annotation labels are misaligned in HTML export
 - <!-- JAL-3024 --> Files opened via command line with a relative path are added as relative paths to Recent files list (since 2.0.x)
index cf91e3a..b6c1b0d 100644 (file)
@@ -1,4 +1,4 @@
-The 2.11.3 Jalview release features a new and more powerful command line interface, support for in-depth exploration of predicted alignment error (PAE) matrices from AlphaFold in the context of multiple alignments, AlphaFold's standard Blue-Orange-Red confidence colourscheme, and a host of minor improvements and bug fixes.
+The 2.11.3 Jalview release features a new and more powerful command line interface, support for in-depth exploration of predicted alignment error (PAE) matrices from AlphaFold in the context of multiple alignments, AlphaFold's standard Blue-Orange-Red confidence colourscheme, and a host of [minor improvements and bug fixes](releases.html#Jalview.2.11.3.0)
 
 **Interactive exploration of AlphaFold Predicted Alignment Error Matrices**
 
index 70deea4..301ea4b 100755 (executable)
     <strong>Welcome to Jalview Version __VERSION__ (released __DISPLAY_DATE__)!!</strong><br/>
   </p>
 __WHATS_NEW__
-  <p>
-    The 2.11.2 release series provides support for two popular 3D
-    structure visualisation tools, new features for discovery of 3D
-    structures, improved platform integration and a new command line
-    tool allowing Jalview to be more easily called from scripts.</p>
-
-  <p>
-    <strong>View predicted protein structures via 3D-Beacons</strong> <br>
-    Jalview 2.11.2's <a href="features/structurechooser.html">Structure
-      Chooser includes a client for the 3D-Beacons Network</a>. Launched in
-    2021, the 3D-Beacons network (<a
-      href="https://www.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/">www.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/</a>)
-    provides a central point for the retrieval of predicted and observed
-    3D structures for sequences in Uniprot, including homology models
-    from Swiss-model and deep learning based predictions from the EBI's
-    Alphafold database (Orengo et al. 2020, <a
-      href="https://doi.org/10.12688/f1000research.20559.1">doi:10.12688/f1000research.20559.1</a>).<br>
-  </p>
-
-  <p>
-    <strong>Support for viewing structures with ChimeraX and
-      Pymol</strong><br> Jalview's 3D structure viewer system has been
-    re-architected to allow easier integration of external structure
-    viewers, and takes advantage of the strucViz2 Chimera communications
-    library developed by Scooter Morris (<a
-      href="https://doi.org/10.1093/bioinformatics/btm329">doi:10.1093/bioinformatics/btm329</a>).<br /> <br />
-    The <a href="features/preferences.html#structure">Structures
-      Preferences tab</a> provides new options allowing ChimeraX and
-    Pymol to be used for visualising external 3D structures. Views
-    from all structure viewers are saved in Jalview Projects, allowing
-    them to be shared with others using Jalview 2.11.2 or later,
-    providing they have the same viewer installed and configured to be
-    used with Jalview.<br/><br/>Jalview
-    2.11.2 has been tested with <strong>Pymol 2.5.0 (community)</strong> and <strong>2.5.2
-    (incentive)</strong>. For <strong>ChimeraX, we recommend using v1.3 or later</strong>.
-  </p>
-  <p>Other highlights include:</p>
-  <ul>
-    <li>Import of annotated DNA and RNA loci via GenBank and EMBL
-      style flatfile</li>
-    <li><strong>Easier configuration of <a
-        href="features/preferences.html#startup">Jalview's memory
-          allocation</a></strong></li>
-    <li>Scripts for <a href="features/commandline.html">running
-        Jalview via the command line</a> on macOS, Linux/Unix and Windows.
-    </li>
-  </ul>
-
-
-  <p>
-      For the full details, see <a
-        href="releases.html#Jalview.2.11.2">the Jalview 2.11.2 series
-        release notes</a>.
-    </p>
-  <p>
-    <strong>Known Issues</strong> <br />The following known issues will
-    be addressed in a minor patch release.
-  
-  <ul>
-    <li>Display of RESNUM sequence features are not suppressed when
-      structures associated with a sequence are viewed with an external
-      viewer (Regression from 2.11.1 series)</li>
-  </ul>
-    <p></p>
 </body>
 </html>
index fb8f1bc..3fc97b5 100644 (file)
Binary files a/j11lib/getdown-core.jar and b/j11lib/getdown-core.jar differ
diff --git a/j11lib/groovy-4.0.15.jar b/j11lib/groovy-4.0.15.jar
new file mode 100644 (file)
index 0000000..8423d99
Binary files /dev/null and b/j11lib/groovy-4.0.15.jar differ
diff --git a/j11lib/groovy-all-2.4.21-indy.jar b/j11lib/groovy-all-2.4.21-indy.jar
deleted file mode 100644 (file)
index 15ee98d..0000000
Binary files a/j11lib/groovy-all-2.4.21-indy.jar and /dev/null differ
diff --git a/j11lib/groovy-ant-4.0.15.jar b/j11lib/groovy-ant-4.0.15.jar
new file mode 100644 (file)
index 0000000..b6a39ac
Binary files /dev/null and b/j11lib/groovy-ant-4.0.15.jar differ
diff --git a/j11lib/groovy-astbuilder-4.0.15.jar b/j11lib/groovy-astbuilder-4.0.15.jar
new file mode 100644 (file)
index 0000000..f341fac
Binary files /dev/null and b/j11lib/groovy-astbuilder-4.0.15.jar differ
diff --git a/j11lib/groovy-cli-commons-4.0.15.jar b/j11lib/groovy-cli-commons-4.0.15.jar
new file mode 100644 (file)
index 0000000..b482258
Binary files /dev/null and b/j11lib/groovy-cli-commons-4.0.15.jar differ
diff --git a/j11lib/groovy-cli-picocli-4.0.15.jar b/j11lib/groovy-cli-picocli-4.0.15.jar
new file mode 100644 (file)
index 0000000..3223ba9
Binary files /dev/null and b/j11lib/groovy-cli-picocli-4.0.15.jar differ
diff --git a/j11lib/groovy-console-4.0.15.jar b/j11lib/groovy-console-4.0.15.jar
new file mode 100644 (file)
index 0000000..04a402a
Binary files /dev/null and b/j11lib/groovy-console-4.0.15.jar differ
diff --git a/j11lib/groovy-contracts-4.0.15.jar b/j11lib/groovy-contracts-4.0.15.jar
new file mode 100644 (file)
index 0000000..6825657
Binary files /dev/null and b/j11lib/groovy-contracts-4.0.15.jar differ
diff --git a/j11lib/groovy-datetime-4.0.15.jar b/j11lib/groovy-datetime-4.0.15.jar
new file mode 100644 (file)
index 0000000..312575a
Binary files /dev/null and b/j11lib/groovy-datetime-4.0.15.jar differ
diff --git a/j11lib/groovy-dateutil-4.0.15.jar b/j11lib/groovy-dateutil-4.0.15.jar
new file mode 100644 (file)
index 0000000..5893f97
Binary files /dev/null and b/j11lib/groovy-dateutil-4.0.15.jar differ
diff --git a/j11lib/groovy-docgenerator-4.0.15.jar b/j11lib/groovy-docgenerator-4.0.15.jar
new file mode 100644 (file)
index 0000000..bf76564
Binary files /dev/null and b/j11lib/groovy-docgenerator-4.0.15.jar differ
diff --git a/j11lib/groovy-ginq-4.0.15.jar b/j11lib/groovy-ginq-4.0.15.jar
new file mode 100644 (file)
index 0000000..46f561e
Binary files /dev/null and b/j11lib/groovy-ginq-4.0.15.jar differ
diff --git a/j11lib/groovy-groovydoc-4.0.15.jar b/j11lib/groovy-groovydoc-4.0.15.jar
new file mode 100644 (file)
index 0000000..b818919
Binary files /dev/null and b/j11lib/groovy-groovydoc-4.0.15.jar differ
diff --git a/j11lib/groovy-groovysh-4.0.15.jar b/j11lib/groovy-groovysh-4.0.15.jar
new file mode 100644 (file)
index 0000000..253eff6
Binary files /dev/null and b/j11lib/groovy-groovysh-4.0.15.jar differ
diff --git a/j11lib/groovy-jmx-4.0.15.jar b/j11lib/groovy-jmx-4.0.15.jar
new file mode 100644 (file)
index 0000000..8667ac4
Binary files /dev/null and b/j11lib/groovy-jmx-4.0.15.jar differ
diff --git a/j11lib/groovy-json-4.0.15.jar b/j11lib/groovy-json-4.0.15.jar
new file mode 100644 (file)
index 0000000..76b486a
Binary files /dev/null and b/j11lib/groovy-json-4.0.15.jar differ
diff --git a/j11lib/groovy-jsr223-4.0.15.jar b/j11lib/groovy-jsr223-4.0.15.jar
new file mode 100644 (file)
index 0000000..5ae9f69
Binary files /dev/null and b/j11lib/groovy-jsr223-4.0.15.jar differ
diff --git a/j11lib/groovy-macro-4.0.15.jar b/j11lib/groovy-macro-4.0.15.jar
new file mode 100644 (file)
index 0000000..e5f7abb
Binary files /dev/null and b/j11lib/groovy-macro-4.0.15.jar differ
diff --git a/j11lib/groovy-macro-library-4.0.15.jar b/j11lib/groovy-macro-library-4.0.15.jar
new file mode 100644 (file)
index 0000000..92c208f
Binary files /dev/null and b/j11lib/groovy-macro-library-4.0.15.jar differ
diff --git a/j11lib/groovy-nio-4.0.15.jar b/j11lib/groovy-nio-4.0.15.jar
new file mode 100644 (file)
index 0000000..e6e2ad8
Binary files /dev/null and b/j11lib/groovy-nio-4.0.15.jar differ
diff --git a/j11lib/groovy-servlet-4.0.15.jar b/j11lib/groovy-servlet-4.0.15.jar
new file mode 100644 (file)
index 0000000..711a1e2
Binary files /dev/null and b/j11lib/groovy-servlet-4.0.15.jar differ
diff --git a/j11lib/groovy-sql-4.0.15.jar b/j11lib/groovy-sql-4.0.15.jar
new file mode 100644 (file)
index 0000000..058db44
Binary files /dev/null and b/j11lib/groovy-sql-4.0.15.jar differ
diff --git a/j11lib/groovy-swing-4.0.15.jar b/j11lib/groovy-swing-4.0.15.jar
new file mode 100644 (file)
index 0000000..848d074
Binary files /dev/null and b/j11lib/groovy-swing-4.0.15.jar differ
diff --git a/j11lib/groovy-templates-4.0.15.jar b/j11lib/groovy-templates-4.0.15.jar
new file mode 100644 (file)
index 0000000..3cd0245
Binary files /dev/null and b/j11lib/groovy-templates-4.0.15.jar differ
diff --git a/j11lib/groovy-test-4.0.15.jar b/j11lib/groovy-test-4.0.15.jar
new file mode 100644 (file)
index 0000000..e600dc7
Binary files /dev/null and b/j11lib/groovy-test-4.0.15.jar differ
diff --git a/j11lib/groovy-test-junit5-4.0.15.jar b/j11lib/groovy-test-junit5-4.0.15.jar
new file mode 100644 (file)
index 0000000..abcc69a
Binary files /dev/null and b/j11lib/groovy-test-junit5-4.0.15.jar differ
diff --git a/j11lib/groovy-testng-4.0.15.jar b/j11lib/groovy-testng-4.0.15.jar
new file mode 100644 (file)
index 0000000..60c1b58
Binary files /dev/null and b/j11lib/groovy-testng-4.0.15.jar differ
diff --git a/j11lib/groovy-toml-4.0.15.jar b/j11lib/groovy-toml-4.0.15.jar
new file mode 100644 (file)
index 0000000..ad49634
Binary files /dev/null and b/j11lib/groovy-toml-4.0.15.jar differ
diff --git a/j11lib/groovy-typecheckers-4.0.15.jar b/j11lib/groovy-typecheckers-4.0.15.jar
new file mode 100644 (file)
index 0000000..dc113c3
Binary files /dev/null and b/j11lib/groovy-typecheckers-4.0.15.jar differ
diff --git a/j11lib/groovy-xml-4.0.15.jar b/j11lib/groovy-xml-4.0.15.jar
new file mode 100644 (file)
index 0000000..21aeea0
Binary files /dev/null and b/j11lib/groovy-xml-4.0.15.jar differ
diff --git a/j11lib/groovy-yaml-4.0.15.jar b/j11lib/groovy-yaml-4.0.15.jar
new file mode 100644 (file)
index 0000000..207d47d
Binary files /dev/null and b/j11lib/groovy-yaml-4.0.15.jar differ
diff --git a/j11lib/javaparser-core-3.25.5.jar b/j11lib/javaparser-core-3.25.5.jar
new file mode 100644 (file)
index 0000000..92eed53
Binary files /dev/null and b/j11lib/javaparser-core-3.25.5.jar differ
index fb8f1bc..3fc97b5 100644 (file)
Binary files a/j8lib/getdown-core.jar and b/j8lib/getdown-core.jar differ
diff --git a/j8lib/groovy-4.0.15.jar b/j8lib/groovy-4.0.15.jar
new file mode 100644 (file)
index 0000000..8423d99
Binary files /dev/null and b/j8lib/groovy-4.0.15.jar differ
diff --git a/j8lib/groovy-all-2.4.21-indy.jar b/j8lib/groovy-all-2.4.21-indy.jar
deleted file mode 100644 (file)
index 15ee98d..0000000
Binary files a/j8lib/groovy-all-2.4.21-indy.jar and /dev/null differ
diff --git a/j8lib/groovy-ant-4.0.15.jar b/j8lib/groovy-ant-4.0.15.jar
new file mode 100644 (file)
index 0000000..b6a39ac
Binary files /dev/null and b/j8lib/groovy-ant-4.0.15.jar differ
diff --git a/j8lib/groovy-astbuilder-4.0.15.jar b/j8lib/groovy-astbuilder-4.0.15.jar
new file mode 100644 (file)
index 0000000..f341fac
Binary files /dev/null and b/j8lib/groovy-astbuilder-4.0.15.jar differ
diff --git a/j8lib/groovy-cli-commons-4.0.15.jar b/j8lib/groovy-cli-commons-4.0.15.jar
new file mode 100644 (file)
index 0000000..b482258
Binary files /dev/null and b/j8lib/groovy-cli-commons-4.0.15.jar differ
diff --git a/j8lib/groovy-cli-picocli-4.0.15.jar b/j8lib/groovy-cli-picocli-4.0.15.jar
new file mode 100644 (file)
index 0000000..3223ba9
Binary files /dev/null and b/j8lib/groovy-cli-picocli-4.0.15.jar differ
diff --git a/j8lib/groovy-console-4.0.15.jar b/j8lib/groovy-console-4.0.15.jar
new file mode 100644 (file)
index 0000000..04a402a
Binary files /dev/null and b/j8lib/groovy-console-4.0.15.jar differ
diff --git a/j8lib/groovy-contracts-4.0.15.jar b/j8lib/groovy-contracts-4.0.15.jar
new file mode 100644 (file)
index 0000000..6825657
Binary files /dev/null and b/j8lib/groovy-contracts-4.0.15.jar differ
diff --git a/j8lib/groovy-datetime-4.0.15.jar b/j8lib/groovy-datetime-4.0.15.jar
new file mode 100644 (file)
index 0000000..312575a
Binary files /dev/null and b/j8lib/groovy-datetime-4.0.15.jar differ
diff --git a/j8lib/groovy-dateutil-4.0.15.jar b/j8lib/groovy-dateutil-4.0.15.jar
new file mode 100644 (file)
index 0000000..5893f97
Binary files /dev/null and b/j8lib/groovy-dateutil-4.0.15.jar differ
diff --git a/j8lib/groovy-docgenerator-4.0.15.jar b/j8lib/groovy-docgenerator-4.0.15.jar
new file mode 100644 (file)
index 0000000..bf76564
Binary files /dev/null and b/j8lib/groovy-docgenerator-4.0.15.jar differ
diff --git a/j8lib/groovy-ginq-4.0.15.jar b/j8lib/groovy-ginq-4.0.15.jar
new file mode 100644 (file)
index 0000000..46f561e
Binary files /dev/null and b/j8lib/groovy-ginq-4.0.15.jar differ
diff --git a/j8lib/groovy-groovydoc-4.0.15.jar b/j8lib/groovy-groovydoc-4.0.15.jar
new file mode 100644 (file)
index 0000000..b818919
Binary files /dev/null and b/j8lib/groovy-groovydoc-4.0.15.jar differ
diff --git a/j8lib/groovy-groovysh-4.0.15.jar b/j8lib/groovy-groovysh-4.0.15.jar
new file mode 100644 (file)
index 0000000..253eff6
Binary files /dev/null and b/j8lib/groovy-groovysh-4.0.15.jar differ
diff --git a/j8lib/groovy-jmx-4.0.15.jar b/j8lib/groovy-jmx-4.0.15.jar
new file mode 100644 (file)
index 0000000..8667ac4
Binary files /dev/null and b/j8lib/groovy-jmx-4.0.15.jar differ
diff --git a/j8lib/groovy-json-4.0.15.jar b/j8lib/groovy-json-4.0.15.jar
new file mode 100644 (file)
index 0000000..76b486a
Binary files /dev/null and b/j8lib/groovy-json-4.0.15.jar differ
diff --git a/j8lib/groovy-jsr223-4.0.15.jar b/j8lib/groovy-jsr223-4.0.15.jar
new file mode 100644 (file)
index 0000000..5ae9f69
Binary files /dev/null and b/j8lib/groovy-jsr223-4.0.15.jar differ
diff --git a/j8lib/groovy-macro-4.0.15.jar b/j8lib/groovy-macro-4.0.15.jar
new file mode 100644 (file)
index 0000000..e5f7abb
Binary files /dev/null and b/j8lib/groovy-macro-4.0.15.jar differ
diff --git a/j8lib/groovy-macro-library-4.0.15.jar b/j8lib/groovy-macro-library-4.0.15.jar
new file mode 100644 (file)
index 0000000..92c208f
Binary files /dev/null and b/j8lib/groovy-macro-library-4.0.15.jar differ
diff --git a/j8lib/groovy-nio-4.0.15.jar b/j8lib/groovy-nio-4.0.15.jar
new file mode 100644 (file)
index 0000000..e6e2ad8
Binary files /dev/null and b/j8lib/groovy-nio-4.0.15.jar differ
diff --git a/j8lib/groovy-servlet-4.0.15.jar b/j8lib/groovy-servlet-4.0.15.jar
new file mode 100644 (file)
index 0000000..711a1e2
Binary files /dev/null and b/j8lib/groovy-servlet-4.0.15.jar differ
diff --git a/j8lib/groovy-sql-4.0.15.jar b/j8lib/groovy-sql-4.0.15.jar
new file mode 100644 (file)
index 0000000..058db44
Binary files /dev/null and b/j8lib/groovy-sql-4.0.15.jar differ
diff --git a/j8lib/groovy-swing-4.0.15.jar b/j8lib/groovy-swing-4.0.15.jar
new file mode 100644 (file)
index 0000000..848d074
Binary files /dev/null and b/j8lib/groovy-swing-4.0.15.jar differ
diff --git a/j8lib/groovy-templates-4.0.15.jar b/j8lib/groovy-templates-4.0.15.jar
new file mode 100644 (file)
index 0000000..3cd0245
Binary files /dev/null and b/j8lib/groovy-templates-4.0.15.jar differ
diff --git a/j8lib/groovy-test-4.0.15.jar b/j8lib/groovy-test-4.0.15.jar
new file mode 100644 (file)
index 0000000..e600dc7
Binary files /dev/null and b/j8lib/groovy-test-4.0.15.jar differ
diff --git a/j8lib/groovy-test-junit5-4.0.15.jar b/j8lib/groovy-test-junit5-4.0.15.jar
new file mode 100644 (file)
index 0000000..abcc69a
Binary files /dev/null and b/j8lib/groovy-test-junit5-4.0.15.jar differ
diff --git a/j8lib/groovy-testng-4.0.15.jar b/j8lib/groovy-testng-4.0.15.jar
new file mode 100644 (file)
index 0000000..60c1b58
Binary files /dev/null and b/j8lib/groovy-testng-4.0.15.jar differ
diff --git a/j8lib/groovy-toml-4.0.15.jar b/j8lib/groovy-toml-4.0.15.jar
new file mode 100644 (file)
index 0000000..ad49634
Binary files /dev/null and b/j8lib/groovy-toml-4.0.15.jar differ
diff --git a/j8lib/groovy-typecheckers-4.0.15.jar b/j8lib/groovy-typecheckers-4.0.15.jar
new file mode 100644 (file)
index 0000000..dc113c3
Binary files /dev/null and b/j8lib/groovy-typecheckers-4.0.15.jar differ
diff --git a/j8lib/groovy-xml-4.0.15.jar b/j8lib/groovy-xml-4.0.15.jar
new file mode 100644 (file)
index 0000000..21aeea0
Binary files /dev/null and b/j8lib/groovy-xml-4.0.15.jar differ
diff --git a/j8lib/groovy-yaml-4.0.15.jar b/j8lib/groovy-yaml-4.0.15.jar
new file mode 100644 (file)
index 0000000..207d47d
Binary files /dev/null and b/j8lib/groovy-yaml-4.0.15.jar differ
diff --git a/j8lib/javaparser-core-3.25.5.jar b/j8lib/javaparser-core-3.25.5.jar
new file mode 100644 (file)
index 0000000..92eed53
Binary files /dev/null and b/j8lib/javaparser-core-3.25.5.jar differ
index 70eeb95..129dd54 100644 (file)
@@ -1246,8 +1246,8 @@ label.mapping_method = Sequence \u27f7 Structure mapping method
 status.cancelled_image_export_operation = Cancelled {0} export operation
 info.error_creating_file = Error creating {0} file
 exception.outofmemory_loading_mmcif_file = Out of memory loading mmCIF File
-label.run_groovy = Run Groovy console script
-label.run_groovy_tip = Run the script in the Groovy console over this alignment
+label.run_groovy = Run Groovy Console Script
+label.run_groovy_tip = Run the script in the Groovy Console over this alignment
 label.couldnt_run_groovy_script = Failed to run Groovy script
 label.uniprot_sequence_fetcher = UniProt Sequence Fetcher
 action.next_page= >> 
index 90fe089..ce79a65 100644 (file)
@@ -353,6 +353,7 @@ public class TreeModel
 
     if ((nd.left() == null) && (nd.right() == null))
     {
+       // TODO FIX FOR COLUMN TREES
       jalview.bin.Console.outPrintln("Leaf = " + ((SequenceI) nd.element()).getName());
       jalview.bin.Console.outPrintln("Dist " + nd.dist);
       jalview.bin.Console.outPrintln("Boot " + nd.getBootstrap());
@@ -430,7 +431,7 @@ public class TreeModel
 
     if ((nd.left() == null) && (nd.right() == null))
     {
-      nd.height = ((BinaryNode) nd.parent()).height + nd.dist;
+      nd.height = nd.parent().height + nd.dist;
 
       if (nd.height > maxheight)
       {
@@ -445,7 +446,7 @@ public class TreeModel
     {
       if (nd.parent() != null)
       {
-        nd.height = ((BinaryNode) nd.parent()).height + nd.dist;
+        nd.height = nd.parent().height + nd.dist;
       }
       else
       {
index 1abb171..483b1fc 100755 (executable)
@@ -54,6 +54,8 @@ import javax.swing.LookAndFeel;
 import javax.swing.UIManager;
 
 import jalview.analytics.Plausible;
+import jalview.bin.argparser.Arg;
+import jalview.bin.argparser.ArgParser;
 import jalview.datamodel.PDBEntry;
 import jalview.gui.Preferences;
 import jalview.gui.UserDefinedColours;
@@ -1663,27 +1665,36 @@ public class Cache
     }
     if (file == null || !file.exists())
     {
+      if (file != null)
+      {
+        jalview.bin.Console
+                .errPrintln("Could not load bootstrap preferences file '"
+                        + file.getPath() + "'");
+      }
       String channelPrefsFilename = ChannelProperties
               .getProperty("preferences.filename");
       String propertiesFilename = System.getProperty("user.home")
               + File.separatorChar + channelPrefsFilename;
+      jalview.bin.Console.errPrintln(
+              "Using default properties file '" + propertiesFilename + "'");
       file = new File(propertiesFilename);
     }
     if (file == null || !file.exists())
+
     {
       String releasePrefsFilename = fallbackPropertiesFile;
       String releasePropertiesFilename = System.getProperty("user.home")
               + File.separatorChar + releasePrefsFilename;
+      jalview.bin.Console.errPrintln("Falling back to properties file '"
+              + releasePropertiesFilename + "'");
       file = new File(releasePropertiesFilename);
     }
 
-    if (filename == null)
-      return null;
     if (!file.exists())
     {
       jalview.bin.Console
               .errPrintln("Could not load bootstrap preferences file '"
-                      + filename + "'");
+                      + file.getPath() + "'");
       return null;
     }
 
@@ -1723,4 +1734,10 @@ public class Cache
   {
     return key == null ? null : sessionProperties.get(key);
   }
+
+  public static boolean getArgCacheDefault(Arg a, String pref, boolean def)
+  {
+    ArgParser ap = Jalview.getInstance().getArgParser();
+    return ap.isSet(a) ? ap.getBoolean(a) : getDefault(pref, def);
+  }
 }
index 5d3b50d..e02d132 100644 (file)
@@ -775,10 +775,11 @@ public class Commands
                   // RESTORE SESSION AFTER EXPORT IF NEED BE
                   if (sessionToRestore != null)
                   {
-                    Console.debug("Restoring session from "
-                            + sessionToRestore);
-                    
-                    sview.getBinding().restoreSession(sessionToRestore.getAbsolutePath());
+                    Console.debug(
+                            "Restoring session from " + sessionToRestore);
+
+                    sview.getBinding().restoreSession(
+                            sessionToRestore.getAbsolutePath());
 
                   }
                 } catch (ImageOutputException ioexec)
@@ -789,11 +790,14 @@ public class Commands
                   continue;
                 } finally
                 {
-                  try {
+                  try
+                  {
                     this.colourAlignFrame(af, originalColourScheme);
                   } catch (Exception t)
                   {
-                    addError("Unexpected error when restoring colourscheme to alignment after temporary change for export.",t);
+                    addError(
+                            "Unexpected error when restoring colourscheme to alignment after temporary change for export.",
+                            t);
                   }
                 }
               }
@@ -838,21 +842,29 @@ public class Commands
     ArgValuesMap avm = argParser.getLinkedArgs(id);
     AlignFrame af = afMap.get(id);
 
-    if (af == null)
+    if (avm != null && !avm.containsArg(Arg.GROOVY))
     {
-      addWarn("Did not have an alignment window for id=" + id);
+      // nothing to do
       return;
     }
 
+    if (af == null)
+    {
+      addWarn("Groovy script does not have an alignment window.  Proceeding with caution!");
+    }
+
     if (avm.containsArg(Arg.GROOVY))
     {
-      String groovyscript = avm.getValue(Arg.GROOVY);
-      if (groovyscript != null)
+      for (ArgValue groovyAv : avm.getArgValueList(Arg.GROOVY))
       {
-        // Execute the groovy script after we've done all the rendering stuff
-        // and before any images or figures are generated.
-        Console.info("Executing script " + groovyscript);
-        Jalview.getInstance().executeGroovyScript(groovyscript, af);
+        String groovyscript = groovyAv.getValue();
+        if (groovyscript != null)
+        {
+          // Execute the groovy script after we've done all the rendering stuff
+          // and before any images or figures are generated.
+          Console.info("Executing script " + groovyscript);
+          Jalview.getInstance().executeGroovyScript(groovyscript, af);
+        }
       }
     }
   }
@@ -862,9 +874,16 @@ public class Commands
     ArgValuesMap avm = argParser.getLinkedArgs(id);
     AlignFrame af = afMap.get(id);
 
+    if (avm != null && !avm.containsArg(Arg.IMAGE))
+    {
+      // nothing to do
+      return true;
+    }
+
     if (af == null)
     {
-      addWarn("Did not have an alignment window for id=" + id);
+      addWarn("Do not have an alignment window to create image from (id="
+              + id + ").  Not proceeding.");
       return false;
     }
 
@@ -991,9 +1010,16 @@ public class Commands
     ArgValuesMap avm = argParser.getLinkedArgs(id);
     AlignFrame af = afMap.get(id);
 
+    if (avm != null && !avm.containsArg(Arg.OUTPUT))
+    {
+      // nothing to do
+      return true;
+    }
+
     if (af == null)
     {
-      addWarn("Did not have an alignment window for id=" + id);
+      addWarn("Do not have an alignment window (id=" + id
+              + ").  Not proceeding.");
       return false;
     }
 
index 1b230ec..1bb8162 100644 (file)
 package jalview.bin;
 
 import java.io.PrintStream;
-import java.util.Locale;
 
 import jalview.log.JLogger;
-import jalview.log.JLoggerI;
 import jalview.log.JLoggerI.LogLevel;
 import jalview.log.JLoggerLog4j;
 import jalview.util.ChannelProperties;
@@ -241,7 +239,7 @@ public class Console
     {
       JLogger.LogLevel logLevel = JLogger.LogLevel.INFO;
 
-      if (JLogger.isLevel(providedLogLevel))
+      if (providedLogLevel != null && JLogger.isLevel(providedLogLevel))
       {
         logLevel = Console.getLogLevel(providedLogLevel);
       }
@@ -292,19 +290,23 @@ public class Console
 
   public static void setLogLevel(String logLevelString)
   {
-    for (LogLevel logLevel : JLoggerI.LogLevel.values())
+    LogLevel l = null;
+    try
+    {
+      l = LogLevel.valueOf(logLevelString);
+    } catch (IllegalArgumentException | NullPointerException e1)
+    {
+      Console.debug("Invalid log level '" + logLevelString + "'");
+      return;
+    }
+    if (l != null)
     {
-      if (logLevel.toString().toLowerCase(Locale.ROOT)
-              .equals(logLevelString.toLowerCase(Locale.ROOT)))
+      log.setLevel(l);
+      if (!Platform.isJS())
       {
-        log.setLevel(logLevel);
-        if (!Platform.isJS())
-        {
-          Log4j.init(logLevel);
-        }
-        JLoggerLog4j.getLogger("org.apache.axis", logLevel);
-        break;
+        Log4j.init(l);
       }
+      JLoggerLog4j.getLogger("org.apache.axis", l);
     }
   }
 
index b7d15e5..e343b0f 100755 (executable)
@@ -73,6 +73,8 @@ import jalview.bin.argparser.Arg.Opt;
 import jalview.bin.argparser.Arg.Type;
 import jalview.bin.argparser.ArgParser;
 import jalview.bin.argparser.BootstrapArgs;
+import jalview.bin.groovy.JalviewObject;
+import jalview.bin.groovy.JalviewObjectI;
 import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
@@ -118,7 +120,7 @@ import jalview.ws.jws2.Jws2Discoverer;
  * @author $author$
  * @version $Revision$
  */
-public class Jalview
+public class Jalview implements JalviewObjectI
 {
   static
   {
@@ -138,7 +140,7 @@ public class Jalview
 
   protected Commands cmds;
 
-  public static AlignFrame currentAlignFrame;
+  public AlignFrame currentAlignFrame = null;
 
   private ArgParser argparser = null;
 
@@ -447,7 +449,7 @@ public class Jalview
       }
       else if (bootstrapArgs.contains(Arg.DEBUG))
       {
-        logLevel = "DEBUG";
+        logLevel = bootstrapArgs.getBoolean(Arg.DEBUG) ? "DEBUG" : "INFO";
       }
       if (logLevel == null && !(bootstrapProperties == null))
       {
@@ -642,14 +644,12 @@ public class Jalview
     try
     {
       Console.initLogger();
-    } catch (
-
-    NoClassDefFoundError error)
+    } catch (NoClassDefFoundError error)
     {
       error.printStackTrace();
       String message = "\nEssential logging libraries not found."
               + "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
-      Jalview.exit(message, ExitCode.OK);
+      Jalview.exit(message, ExitCode.NO_LOGGING);
     }
     desktop = null;
 
@@ -1633,8 +1633,7 @@ public class Jalview
     PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
             "USAGESTATS",
             MessageManager.getString("prompt.analytics_title"),
-            MessageManager.getString("prompt.analytics"),
-            new Runnable()
+            MessageManager.getString("prompt.analytics"), new Runnable()
             {
               @Override
               public void run()
@@ -1752,12 +1751,11 @@ public class Jalview
     }
     try
     {
+      JalviewObjectI j = new JalviewObject(this);
       Map<String, java.lang.Object> vbinding = new HashMap<>();
-      vbinding.put("Jalview", this);
-      if (af != null)
-      {
-        vbinding.put("currentAlFrame", af);
-      }
+      vbinding.put(JalviewObjectI.jalviewObjectName, j);
+      vbinding.put(JalviewObjectI.currentAlFrameName,
+              af != null ? af : getCurrentAlignFrame());
       Binding gbinding = new Binding(vbinding);
       GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
       gse.run(sfile.toString(), gbinding);
@@ -1773,7 +1771,6 @@ public class Jalview
               .errPrintln("Exception Whilst trying to execute file " + sfile
                       + " as a groovy script.");
       e.printStackTrace(System.err);
-
     }
   }
 
@@ -1787,30 +1784,32 @@ public class Jalview
     return false;
   }
 
+  @Override
   public AlignFrame[] getAlignFrames()
   {
     return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
-            : Desktop.getAlignFrames();
-
+            : Desktop.getDesktopAlignFrames();
   }
 
   /**
    * jalview.bin.Jalview.quit() will just run the non-GUI shutdownHook and exit
    */
+  @Override
   public void quit()
   {
     // System.exit will run the shutdownHook first
     Jalview.exit("Quitting now. Bye!", ExitCode.OK);
   }
 
-  public static AlignFrame getCurrentAlignFrame()
+  @Override
+  public AlignFrame getCurrentAlignFrame()
   {
-    return Jalview.currentAlignFrame;
+    return currentAlignFrame;
   }
 
-  public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
+  public void setCurrentAlignFrame(AlignFrame af)
   {
-    Jalview.currentAlignFrame = currentAlignFrame;
+    this.currentAlignFrame = af;
   }
 
   public Commands getCommands()
@@ -1862,7 +1861,7 @@ public class Jalview
     // only add new ones to the end of the list (to preserve ordinal values)
     OK, FILE_NOT_FOUND, FILE_NOT_READABLE, NO_FILES, INVALID_FORMAT,
     INVALID_ARGUMENT, INVALID_VALUE, MIXED_CLI_ARGUMENTS,
-    ERROR_RUNNING_COMMANDS;
+    ERROR_RUNNING_COMMANDS, NO_LOGGING, GROOVY_ERROR;
   }
 
   /******************************
@@ -2041,8 +2040,8 @@ public class Jalview
               j.getArgParser().getMixedExamples());
       String quit = MessageManager.getString("action.quit");
 
-      Desktop.instance.nonBlockingDialog(title, warning, quit,
-              JvOptionPane.WARNING_MESSAGE, false, true);
+      Desktop.instance.nonBlockingDialog(title, warning, null, quit,
+              JvOptionPane.WARNING_MESSAGE, false, false, true, 30000);
 
       Jalview.exit(
               "Exiting due to mixed old and new command line arguments.",
@@ -2066,8 +2065,8 @@ public class Jalview
       {
         String cont = MessageManager.getString("label.continue");
 
-        Desktop.instance.nonBlockingDialog(32, 2, title, warning, url, cont,
-                JvOptionPane.WARNING_MESSAGE, false, true, true);
+        Desktop.instance.nonBlockingDialog(title, warning, url, cont,
+                JvOptionPane.WARNING_MESSAGE, false, true, true, 30000);
       }
     }
     if (j.getCommands() != null && j.getCommands().getErrors().size() > 0)
@@ -2087,7 +2086,7 @@ public class Jalview
                 Math.max(message.length(), Math.min(60, shortest)),
                 Math.min(errors.size(), 20), title, message,
                 j.getCommands().errorsToString(), ok,
-                JvOptionPane.WARNING_MESSAGE, true, false, true);
+                JvOptionPane.WARNING_MESSAGE, true, false, true, -1);
       }
     }
   }
index 2a3a4a1..93156ac 100644 (file)
@@ -44,6 +44,8 @@ public enum Arg
   QUESTIONNAIRE(Type.CONFIG,
           "Show (or don't show) the questionnaire if one is available.",
           true, Opt.BOOLEAN, Opt.BOOTSTRAP),
+  JAVACONSOLE(Type.CONFIG, "Show (or don't show) the Java Console.", false,
+          Opt.BOOLEAN, Opt.BOOTSTRAP),
   NOUSAGESTATS(Type.CONFIG, "Don't send initial launch usage stats.",
           Opt.UNARY, Opt.BOOTSTRAP),
   NOSTARTUPFILE(Type.CONFIG, "Don't show the default startup file.",
index 1b8e6ad..155f69e 100644 (file)
@@ -318,9 +318,13 @@ public class ArgParser
     }
 
     if (bsa != null)
+    {
       this.bootstrapArgs = bsa;
+    }
     else
+    {
       this.bootstrapArgs = BootstrapArgs.getBootstrapArgs(args);
+    }
     parse(args, initsubstitutions, allowPrivate);
   }
 
index d32a5b2..5c21d03 100644 (file)
@@ -214,6 +214,13 @@ public class BootstrapArgs
         }
       }
     }
+
+    // if in an argfile, remove it from the hashset so it can be re-used in
+    // another argfile
+    if (inArgFile != null)
+    {
+      argFiles.remove(inArgFile);
+    }
   }
 
   public boolean contains(Arg a)
diff --git a/src/jalview/bin/groovy/JalviewObject.java b/src/jalview/bin/groovy/JalviewObject.java
new file mode 100644 (file)
index 0000000..e271c3c
--- /dev/null
@@ -0,0 +1,42 @@
+package jalview.bin.groovy;
+
+import jalview.bin.Jalview.ExitCode;
+import jalview.gui.AlignFrame;
+
+public class JalviewObject implements JalviewObjectI
+{
+  private JalviewObjectI object = null;
+
+  public JalviewObject(JalviewObjectI j)
+  {
+    this.object = j;
+  }
+
+  @Override
+  public AlignFrame[] getAlignFrames()
+  {
+    return object == null ? null : object.getAlignFrames();
+  }
+
+  @Override
+  public AlignFrame getCurrentAlignFrame()
+  {
+    return object == null ? null : object.getCurrentAlignFrame();
+  }
+
+  @Override
+  public void quit()
+  {
+    if (object != null)
+    {
+      object.quit();
+    }
+    else
+    {
+      jalview.bin.Jalview.exit(
+              "Groovy console quit without Jalview object.",
+              ExitCode.GROOVY_ERROR);
+    }
+  }
+
+}
diff --git a/src/jalview/bin/groovy/JalviewObjectI.java b/src/jalview/bin/groovy/JalviewObjectI.java
new file mode 100644 (file)
index 0000000..f365d30
--- /dev/null
@@ -0,0 +1,16 @@
+package jalview.bin.groovy;
+
+import jalview.gui.AlignFrame;
+
+public interface JalviewObjectI
+{
+  public AlignFrame[] getAlignFrames();
+
+  public AlignFrame getCurrentAlignFrame();
+
+  public final static String currentAlFrameName = "currentAlFrame";
+
+  public final static String jalviewObjectName = "Jalview";
+
+  public void quit();
+}
index 4a38ec0..b427739 100644 (file)
@@ -340,10 +340,12 @@ public class ColumnSelection
 
   /**
    * Returns a read-only view of the (possibly empty) list of selected columns
+   * (base 1)
    * <p>
-   * The list contains no duplicates but is not necessarily ordered. It also may
-   * include columns hidden from the current view. To modify (for example sort)
-   * the list, you should first make a copy.
+   * The list contains no duplicates but is not necessarily ordered. Columns are
+   * reported in alignment coordinates (base 1), so may also include columns
+   * hidden from the current view. To modify (for example sort) the list, you
+   * should first make a copy.
    * <p>
    * The list is not thread-safe: iterating over it could result in
    * ConcurrentModificationException if it is modified by another thread.
index 661ad6c..dedb960 100644 (file)
@@ -57,4 +57,13 @@ public interface SearchResultMatchI
    * @return
    */
   boolean contains(SequenceI seq, int start, int end);
+
+  /**
+   *
+   * @param seq
+   * @param from - first position to highlight
+   * @param to - last position to highlight (assumed higher than from)
+   * @return true iff from-to intersects or marks positions either side of start/end
+   */
+  boolean adjacent(SequenceI seq, int from, int to);
 }
\ No newline at end of file
index 8d6cbb1..546dd6f 100755 (executable)
@@ -35,13 +35,13 @@ public class SearchResults implements SearchResultsI
 {
   private int count;
 
-  private List<SearchResultMatchI> matches = new ArrayList<>();
+  private ArrayList<SearchResultMatchI> matches = new ArrayList<>();
 
   /**
    * One match consists of a sequence reference, start and end positions.
    * Discontiguous ranges in a sequence require two or more Match objects.
    */
-  public class Match implements SearchResultMatchI
+  public class Match implements SearchResultMatchI, Comparable<SearchResultMatchI>
   {
     final SequenceI sequence;
 
@@ -160,6 +160,39 @@ public class SearchResults implements SearchResultsI
     {
       return (sequence == seq && start <= from && end >= to);
     }
+    @Override
+    public boolean adjacent(SequenceI seq, int from, int to)
+    {
+      return (sequence == seq && ((start <= from && end >= to) || (from<=(end+1) && to >=(end+1)) || (from<=(start-1) && to>=(start-1))));
+    }
+
+    @Override
+    public int compareTo(SearchResultMatchI o)
+    {
+      if (start<o.getStart())
+      {
+        return -1;
+      }
+      if (start > o.getStart())
+      {
+        return +1;
+      }
+      if (end < o.getEnd())
+      {
+        return -1;
+      }
+      if (end > o.getEnd())
+      {
+        return +1;
+      }
+      if (sequence!=o.getSequence())
+      {
+        int hashc =sequence.hashCode(),oseq=o.getSequence().hashCode();
+        return (hashc < oseq) ? -1 : 1;
+      }
+      return 0;
+    }
+    
   }
 
   @Override
@@ -191,8 +224,56 @@ public class SearchResults implements SearchResultsI
       count = beforeCount + 1;
     }
   }
+  
 
   @Override
+  public boolean appendResult(SequenceI sequence, int start, int end)
+  {
+
+    Match m = new Match(sequence, start, end);
+    
+    boolean appending=false;
+    
+    // we dynamically maintain an interval to add as we test each range in the list
+    
+    int cstart=start,cend=end;
+    List<SearchResultMatchI> toRemove=new ArrayList<>();
+    for (SearchResultMatchI thatm:matches)
+    {
+      if (thatm.getSequence()==sequence)
+      {
+        if (thatm.contains(sequence,cstart,cend))
+        {
+          // found a match containing the current range. nothing else to do except report if we operated on the list
+          return appending;
+        }
+        if (thatm.adjacent(sequence, cstart, cend))
+        {
+          // update the match to add with the adjacent start/end
+          start = Math.min(m.start, thatm.getStart());
+          end = Math.max(m.end, thatm.getEnd());
+          // and check if we keep or remove the old one
+          if (thatm.getStart()!=start || thatm.getEnd()!=end)
+          { 
+            toRemove.add(thatm);
+            count--;
+            cstart = start;
+            cend = end;
+            appending=true;
+          } else {
+            return false;
+          }
+        }
+      }
+    }
+    matches.removeAll(toRemove);
+    {
+      matches.add(new Match(sequence,cstart,cend));
+      count++;
+    }
+    return appending;
+  }
+  @Override
   public boolean involvesSequence(SequenceI sequence)
   {
     final int start = sequence.getStart();
@@ -393,4 +474,5 @@ public class SearchResults implements SearchResultsI
     }
     return seqs;
   }
+
 }
index 7946824..d682de1 100644 (file)
@@ -51,6 +51,19 @@ public interface SearchResultsI
    */
   void addResult(SequenceI seq, int[] positions);
 
+
+  /**
+   * Adds the given start/end region to this search result. If sequence already
+   * has a search result and the range is adjacent to already highlighted
+   * positions, they will be merged
+   * 
+   * @param sequence
+   * @param start
+   * @param end
+   * @return true if an existing range was updated with this one
+   */
+  boolean appendResult(SequenceI sequence, int start, int end);
+
   /**
    * adds all match results in the argument to this set
    * 
index 870db65..dc18369 100644 (file)
@@ -267,16 +267,30 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   {
     if (atoms != null)
     {
-      boolean useScriptWait = atoms.size() > 1;
       if (resetLastRes.length() > 0)
       {
-        jmolScript(resetLastRes.toString(), useScriptWait);
+        jmolScript(resetLastRes.toString());
         resetLastRes.setLength(0);
       }
+      StringBuilder highlightCommands=null;
       for (AtomSpec atom : atoms)
       {
-        highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
-                atom.getChain(), atom.getPdbFile(), useScriptWait);
+        StringBuilder thisAtom = highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
+                atom.getChain(), atom.getPdbFile());
+        if (thisAtom!=null) {
+          if (highlightCommands==null)
+          {
+            highlightCommands=thisAtom;                  
+          } else {
+            highlightCommands.append(thisAtom);
+          }
+        }
+      }
+      if (highlightCommands!=null)
+      {
+        jmolHistory(false);
+        jmolScript(highlightCommands.toString());
+        jmolHistory(true);
       }
       // Highlight distances between atoms with a 'measure' command - not yet
       // working
@@ -306,17 +320,15 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   }
 
   // jmol/ssm only
-  public void highlightAtom(int atomIndex, int pdbResNum, String chain,
-          String pdbfile, boolean useScriptWait)
+  private StringBuilder highlightAtom(int atomIndex, int pdbResNum, String chain,
+          String pdbfile)
   {
     String modelId = getModelIdForFile(pdbfile);
     if (modelId.isEmpty())
     {
-      return;
+      return null;
     }
 
-    jmolHistory(false, useScriptWait);
-
     StringBuilder selection = new StringBuilder(32);
     StringBuilder cmd = new StringBuilder(64);
     selection.append("select ").append(String.valueOf(pdbResNum));
@@ -333,8 +345,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     resetLastRes.append(selection).append(";wireframe 0;").append(selection)
             .append(" and not hetero; spacefill 0;");
 
-    jmolScript(cmd.toString(), useScriptWait);
-    jmolHistory(true, useScriptWait);
+    return cmd;
   }
 
   private boolean debug = true;
index f3cb012..ac8ffb9 100644 (file)
@@ -95,6 +95,7 @@ import jalview.api.analysis.SimilarityParamsI;
 import jalview.bin.Cache;
 import jalview.bin.Console;
 import jalview.bin.Jalview;
+import jalview.bin.groovy.JalviewObjectI;
 import jalview.commands.CommandI;
 import jalview.commands.EditCommand;
 import jalview.commands.EditCommand.Action;
@@ -503,7 +504,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       @Override
       public void focusGained(FocusEvent e)
       {
-        Jalview.setCurrentAlignFrame(AlignFrame.this);
+        Jalview.getInstance().setCurrentAlignFrame(AlignFrame.this);
       }
     });
 
@@ -5963,12 +5964,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void runGroovy_actionPerformed()
   {
-    Jalview.setCurrentAlignFrame(this);
-    groovy.ui.Console console = Desktop.getGroovyConsole();
+    Jalview.getInstance().setCurrentAlignFrame(this);
+    groovy.console.ui.Console console = Desktop.getGroovyConsole();
     if (console != null)
     {
       try
       {
+        console.setVariable(JalviewObjectI.currentAlFrameName, this);
         console.runScript();
       } catch (Exception ex)
       {
index ef9e575..a8bc815 100644 (file)
@@ -997,7 +997,7 @@ public class AlignViewport extends AlignmentViewport
    */
   protected boolean noReferencesTo(AlignedCodonFrame acf)
   {
-    AlignFrame[] frames = Desktop.getAlignFrames();
+    AlignFrame[] frames = Desktop.getDesktopAlignFrames();
     if (frames == null)
     {
       return true;
index 6a6cb56..921a418 100644 (file)
@@ -50,6 +50,7 @@ import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
 import javax.swing.border.Border;
 import javax.swing.text.DefaultCaret;
 
@@ -106,7 +107,7 @@ public class Console extends WindowAdapter
 
   private JComboBox<LogLevel> logLevelCombo = new JComboBox<LogLevel>();
 
-  protected LogLevel startingLogLevel = LogLevel.INFO;
+  protected LogLevel startingLogLevel = null;
 
   public Console()
   {
@@ -147,6 +148,7 @@ public class Console extends WindowAdapter
     scrollPane.setBorder(noBorder);
     textArea.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mouseClicked(MouseEvent e)
       {
         if (e.getButton() == MouseEvent.BUTTON1)
@@ -172,6 +174,7 @@ public class Console extends WindowAdapter
             MessageManager.getString("label.copy_to_clipboard"));
     copyToClipboardButton.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         copyConsoleTextToClipboard();
@@ -183,12 +186,14 @@ public class Console extends WindowAdapter
 
       private Color fg = textArea.getForeground();
 
+      @Override
       public void mousePressed(MouseEvent e)
       {
         textArea.setBackground(textArea.getSelectionColor());
         textArea.setForeground(textArea.getSelectedTextColor());
       }
 
+      @Override
       public void mouseReleased(MouseEvent e)
       {
         textArea.setBackground(bg);
@@ -212,11 +217,19 @@ public class Console extends WindowAdapter
     // logLevelCombo.addItem(LogLevel.ERROR);
     // logLevelCombo.addItem(LogLevel.OFF);
     // set startingLogLevel
-    startingLogLevel = jalview.bin.Console.log == null ? LogLevel.INFO
-            : jalview.bin.Console.log.getLevel();
+    
+    if (jalview.bin.Console.getLogger() == null)
+    {
+      startingLogLevel = jalview.bin.Console.getCachedLogLevel();
+    }
+    else
+    {
+      startingLogLevel = jalview.bin.Console.getLogger().getLevel();
+    }
     setChosenLogLevelCombo();
     logLevelCombo.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         if (jalview.bin.Console.log != null)
@@ -313,7 +326,7 @@ public class Console extends WindowAdapter
         boolean added = false;
         for (int i = 0; i < logLevelCombo.getItemCount(); i++)
         {
-          LogLevel l = (LogLevel) logLevelCombo.getItemAt(i);
+          LogLevel l = logLevelCombo.getItemAt(i);
           if (l.compareTo(setLogLevel) >= 0)
           {
             logLevelCombo.insertItemAt(setLogLevel, i);
@@ -475,36 +488,32 @@ public class Console extends WindowAdapter
    */
   public Console(Desktop desktop)
   {
-    this(desktop, true);
-  }
-
-  /**
-   * attach a console to the desktop - the desktop will open it if requested.
-   * 
-   * @param desktop
-   * @param showjconsole
-   *          - if true, then redirect stdout immediately
-   */
-  public Console(Desktop desktop, boolean showjconsole)
-  {
     parent = desktop;
     // window name - get x,y,width, height possibly scaled
-    Rectangle bounds = desktop.getLastKnownDimensions("JAVA_CONSOLE_");
-    if (bounds == null)
+    Rectangle bounds = parent == null ? null
+            : parent.getLastKnownDimensions("JAVA_CONSOLE_");
+    if (bounds != null)
     {
       frame = initFrame(
               ChannelProperties.getProperty("app_name") + " Java Console",
-              desktop.getWidth() / 2, desktop.getHeight() / 4,
-              desktop.getX(), desktop.getY());
+              bounds.width, bounds.height, bounds.x, bounds.y);
+    }
+    else if (parent != null && parent.getWidth() > 0
+            && parent.getHeight() > 0)
+    {
+      frame = initFrame(
+              ChannelProperties.getProperty("app_name") + " Java Console",
+              parent.getWidth() / 2, parent.getHeight() / 4, parent.getX(),
+              parent.getY());
     }
     else
     {
       frame = initFrame(
               ChannelProperties.getProperty("app_name") + " Java Console",
-              bounds.width, bounds.height, bounds.x, bounds.y);
+              MIN_WIDTH, MIN_HEIGHT, 10, 10);
     }
     frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
-    // desktop.add(frame);
+    // parent.add(frame);
     initConsole(false);
     LogLevel level = (LogLevel) logLevelCombo.getSelectedItem();
     if (!Platform.isJS())
@@ -537,6 +546,7 @@ public class Console extends WindowAdapter
         pin.close();
       } catch (Exception e)
       {
+        jalview.bin.Console.debug("pin.close() error", e);
       }
       try
       {
@@ -544,12 +554,14 @@ public class Console extends WindowAdapter
         pin2.close();
       } catch (Exception e)
       {
+        jalview.bin.Console.debug("pin2.close() error", e);
       }
       try
       {
         textAppender.join(10);
       } catch (Exception e)
       {
+        jalview.bin.Console.debug("textAppender.join(10) error", e);
       }
     }
     /*
@@ -610,12 +622,9 @@ public class Console extends WindowAdapter
           try
           {
             this.wait(100);
-            if (pin.available() == 0)
-            {
-              trimBuffer(false);
-            }
           } catch (InterruptedException ie)
           {
+            jalview.bin.Console.debug("pin.available() error", ie);
           }
         }
 
@@ -641,13 +650,14 @@ public class Console extends WindowAdapter
         {
           try
           {
-            this.wait(100);
+            this.wait(100); // ##### implicated BLOCKED
             if (pin2.available() == 0)
             {
               trimBuffer(false);
             }
           } catch (InterruptedException ie)
           {
+            jalview.bin.Console.debug("pin.available() error", ie);
           }
         }
         while (pin2.available() != 0)
@@ -672,23 +682,23 @@ public class Console extends WindowAdapter
           // check string buffer - if greater than console, clear console and
           // replace with last segment of content, otherwise, append all to
           // content.
-          long count;
           while (displayPipe.length() > 0)
           {
-            count = 0;
             StringBuffer tmp = new StringBuffer(), replace;
             synchronized (displayPipe)
             {
               replace = displayPipe;
               displayPipe = tmp;
             }
-            // simply append whole buffer
-            textArea.append(replace.toString());
-            count += replace.length();
-            if (count > byteslim)
+            // Append formatted message to textarea using the Swing Thread.
+            SwingUtilities.invokeLater(new Runnable()
             {
-              trimBuffer(false);
-            }
+              public void run()
+              {
+                textArea.append(replace.toString());
+                trimBuffer(false);
+              }
+            });
           }
           if (displayPipe.length() == 0)
           {
@@ -697,10 +707,18 @@ public class Console extends WindowAdapter
               this.wait(100);
               if (displayPipe.length() == 0)
               {
-                trimBuffer(false);
+                // post a trim on Swing Thread.
+                SwingUtilities.invokeLater(new Runnable()
+                {
+                  public void run()
+                  {
+                    trimBuffer(false);
+                  }
+                });
               }
             } catch (InterruptedException e)
             {
+              jalview.bin.Console.debug("displayPipe.length() error", e);
             }
           }
         }
@@ -711,7 +729,7 @@ public class Console extends WindowAdapter
             this.wait(100);
           } catch (InterruptedException e)
           {
-
+            jalview.bin.Console.debug("this.wait(100) error", e);
           }
         }
         if (quit)
@@ -738,6 +756,7 @@ public class Console extends WindowAdapter
         this.wait(1000);
       } catch (InterruptedException ie)
       {
+        jalview.bin.Console.debug("this.wait(1000) error", ie);
       }
       throw new NullPointerException(
               MessageManager.getString("exception.application_test_npe"));
@@ -757,9 +776,7 @@ public class Console extends WindowAdapter
       @Override
       public void run()
       {
-        displayPipe.append(input); // change to stringBuffer
-        // displayPipe.flush();
-
+        displayPipe.append(input); 
       }
     });
     // stderr.println("Time taken to Spawnappend:\t" + (System.nanoTime() -
@@ -781,7 +798,7 @@ public class Console extends WindowAdapter
                 + "\nTruncated...\n";
       } catch (Exception e)
       {
-        e.printStackTrace();
+        jalview.bin.Console.warn("textArea Exception", e);
       }
     }
     // trim the buffer
@@ -805,7 +822,7 @@ public class Console extends WindowAdapter
           }
         } catch (Exception e)
         {
-          e.printStackTrace();
+          jalview.bin.Console.warn("textArea Exception", e);
         }
         // lines = textArea.getLineCount();
       }
index e785431..35afb69 100644 (file)
@@ -113,6 +113,9 @@ import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.bin.Jalview.ExitCode;
+import jalview.bin.argparser.Arg;
+import jalview.bin.groovy.JalviewObject;
+import jalview.bin.groovy.JalviewObjectI;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.Sequence;
@@ -157,7 +160,7 @@ import jalview.ws.utils.UrlDownloadClient;
  */
 public class Desktop extends jalview.jbgui.GDesktop
         implements DropTargetListener, ClipboardOwner, IProgressIndicator,
-        jalview.api.StructureSelectionManagerProvider
+        jalview.api.StructureSelectionManagerProvider, JalviewObjectI
 {
   private static final String CITATION;
   static
@@ -498,7 +501,28 @@ public class Desktop extends jalview.jbgui.GDesktop
 
     boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", false);
 
-    boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE", false);
+    boolean showjconsole = Cache.getArgCacheDefault(Arg.JAVACONSOLE,
+            "SHOW_JAVA_CONSOLE", false);
+
+    // start dialogue queue for single dialogues
+    startDialogQueue();
+
+    if (!Platform.isJS())
+    /**
+     * Java only
+     * 
+     * @j2sIgnore
+     */
+    {
+      Desktop.instance.acquireDialogQueue();
+
+      jconsole = new Console(this);
+      jconsole.setHeader(Cache.getVersionDetailsForConsole());
+      showConsole(showjconsole);
+
+      Desktop.instance.releaseDialogQueue();
+    }
+
     desktop = new MyDesktopPane(selmemusage);
 
     showMemusage.setSelected(selmemusage);
@@ -545,9 +569,6 @@ public class Desktop extends jalview.jbgui.GDesktop
       setBounds(xPos, yPos, 900, 650);
     }
 
-    // start dialogue queue for single dialogues
-    startDialogQueue();
-
     if (!Platform.isJS())
     /**
      * Java only
@@ -555,10 +576,6 @@ public class Desktop extends jalview.jbgui.GDesktop
      * @j2sIgnore
      */
     {
-      jconsole = new Console(this, showjconsole);
-      jconsole.setHeader(Cache.getVersionDetailsForConsole());
-      showConsole(showjconsole);
-
       showNews.setVisible(false);
 
       experimentalFeatures.setSelected(showExperimental());
@@ -787,17 +804,17 @@ public class Desktop extends jalview.jbgui.GDesktop
         iw = (int) (iw * sw);
         iy = (int) (iy * sh);
         ih = (int) (ih * sh);
-        while (ix >= screenSize.width)
+        if (ix >= screenSize.width)
         {
           jalview.bin.Console.debug(
                   "Window geometry location recall error: shifting horizontal to within screenbounds.");
-          ix -= screenSize.width;
+          ix = ix % screenSize.width;
         }
-        while (iy >= screenSize.height)
+        if (iy >= screenSize.height)
         {
           jalview.bin.Console.debug(
                   "Window geometry location recall error: shifting vertical to within screenbounds.");
-          iy -= screenSize.height;
+          iy = iy % screenSize.height;
         }
         jalview.bin.Console.debug(
                 "Got last known dimensions for " + windowName + ": x:" + ix
@@ -1041,7 +1058,7 @@ public class Desktop extends jalview.jbgui.GDesktop
         {
           if (itf instanceof AlignFrame)
           {
-            Jalview.setCurrentAlignFrame((AlignFrame) itf);
+            Jalview.getInstance().setCurrentAlignFrame((AlignFrame) itf);
           }
           itf.requestFocus();
         }
@@ -1460,62 +1477,73 @@ public class Desktop extends jalview.jbgui.GDesktop
     desktopQuit(true, false);
   }
 
-  public QuitHandler.QResponse desktopQuit(boolean ui, boolean disposeFlag)
-  {
-    final Runnable doDesktopQuit = () -> {
-      Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
-      Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
-      Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
-      storeLastKnownDimensions("", new Rectangle(getBounds().x,
-              getBounds().y, getWidth(), getHeight()));
+  /**
+   * close everything, stash window geometries, and shut down all associated threads/workers  
+   * @param dispose - sets the dispose on close flag - JVM may terminate when set
+   * @param terminateJvm - quit with prejudice - stops the JVM.
+   */
+  public void quitTheDesktop(boolean dispose, boolean terminateJvm) {
+    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+    Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
+    Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
+    storeLastKnownDimensions("", new Rectangle(getBounds().x,
+            getBounds().y, getWidth(), getHeight()));
 
-      if (jconsole != null)
-      {
-        storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
-        jconsole.stopConsole();
-      }
+    if (jconsole != null)
+    {
+      storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
+      jconsole.stopConsole();
+    }
 
-      if (jvnews != null)
-      {
-        storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
-      }
+    if (jvnews != null)
+    {
+      storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
+    }
 
-      // Frames should all close automatically. Keeping external
-      // viewers open should already be decided by user.
-      closeAll_actionPerformed(null);
+    // Frames should all close automatically. Keeping external
+    // viewers open should already be decided by user.
+    closeAll_actionPerformed(null);
 
-      // check for aborted quit
-      if (QuitHandler.quitCancelled())
-      {
-        jalview.bin.Console.debug("Desktop aborting quit");
-        return;
-      }
+    if (dialogExecutor != null)
+    {
+      dialogExecutor.shutdownNow();
+    }
 
-      if (dialogExecutor != null)
-      {
-        dialogExecutor.shutdownNow();
-      }
+    if (groovyConsole != null)
+    {
+      // suppress a possible repeat prompt to save script
+      groovyConsole.setDirty(false);
+      groovyConsole.exit();
+    }
 
-      if (groovyConsole != null)
-      {
-        // suppress a possible repeat prompt to save script
-        groovyConsole.setDirty(false);
-        groovyConsole.exit();
-      }
+    if (terminateJvm)
+    {
+      // note that shutdown hook will not be run
+      jalview.bin.Console.debug("Force Quit selected by user");
+      Runtime.getRuntime().halt(0);
+    }
 
-      if (QuitHandler.gotQuitResponse() == QResponse.FORCE_QUIT)
-      {
-        // note that shutdown hook will not be run
-        jalview.bin.Console.debug("Force Quit selected by user");
-        Runtime.getRuntime().halt(0);
-      }
+    jalview.bin.Console.debug("Quit selected by user");
+    if (dispose)
+    {
+      instance.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+      // instance.dispose();
+    }
+  }
+  public QuitHandler.QResponse desktopQuit(boolean ui, boolean disposeFlag)
+  {
+    final Runnable doDesktopQuit = () -> {
 
-      jalview.bin.Console.debug("Quit selected by user");
-      if (disposeFlag)
+      // FIRST !!  check for aborted quit
+      if (QuitHandler.quitCancelled())
       {
-        instance.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-        // instance.dispose();
+        jalview.bin.Console.debug("Quit was cancelled - Desktop aborting quit");
+        return;
       }
+      
+      // Proceed with quitting
+      quitTheDesktop(disposeFlag, QuitHandler.gotQuitResponse() == QResponse.FORCE_QUIT);
+      // and exit the JVM
       instance.quit();
     };
 
@@ -1524,7 +1552,14 @@ public class Desktop extends jalview.jbgui.GDesktop
   }
 
   /**
-   * Don't call this directly, use desktopQuit() above. Exits the program.
+   * Exits the program and the JVM. 
+   * 
+   * Don't call this directly
+   * 
+   * - use desktopQuit() above to tidy up first.
+   * 
+   * - use closeDesktop() to shutdown Jalview without shutting down the JVM 
+   * 
    */
   @Override
   public void quit()
@@ -1664,7 +1699,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       {
       }
     }
-    Jalview.setCurrentAlignFrame(null);
+    Jalview.getInstance().setCurrentAlignFrame(null);
     jalview.bin.Console.info("ALL CLOSED");
 
     /*
@@ -2123,7 +2158,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       return null;
     }
     List<AlignmentPanel> aps = new ArrayList<>();
-    AlignFrame[] frames = getAlignFrames();
+    AlignFrame[] frames = Desktop.getDesktopAlignFrames();
     if (frames == null)
     {
       return null;
@@ -2160,7 +2195,7 @@ public class Desktop extends jalview.jbgui.GDesktop
     List<AlignmentViewport> viewp = new ArrayList<>();
     if (desktop != null)
     {
-      AlignFrame[] frames = Desktop.getAlignFrames();
+      AlignFrame[] frames = Desktop.getDesktopAlignFrames();
 
       for (AlignFrame afr : frames)
       {
@@ -2521,12 +2556,12 @@ public class Desktop extends jalview.jbgui.GDesktop
    * 
    * @return an array of AlignFrame, or null if none found
    */
-  public static AlignFrame[] getAlignFrames()
+  @Override
+  public AlignFrame[] getAlignFrames()
   {
-    if (Jalview.isHeadlessMode())
+    if (desktop == null)
     {
-      // Desktop.desktop is null in headless mode
-      return new AlignFrame[] { Jalview.currentAlignFrame };
+      return null;
     }
 
     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
@@ -2568,6 +2603,25 @@ public class Desktop extends jalview.jbgui.GDesktop
   }
 
   /**
+   * static version
+   */
+  public static AlignFrame[] getDesktopAlignFrames()
+  {
+    if (Jalview.isHeadlessMode())
+    {
+      // Desktop.desktop is null in headless mode
+      return Jalview.getInstance().getAlignFrames();
+    }
+
+    if (instance != null && desktop != null)
+    {
+      return instance.getAlignFrames();
+    }
+
+    return null;
+  }
+
+  /**
    * Returns an array of any AppJmol frames in the Desktop (or null if none).
    * 
    * @return
@@ -2609,7 +2663,7 @@ public class Desktop extends jalview.jbgui.GDesktop
       openGroovyConsole();
     } catch (Exception ex)
     {
-      jalview.bin.Console.error("Groovy Shell Creation failed.", ex);
+      jalview.bin.Console.error("Groovy Console creation failed.", ex);
       JvOptionPane.showInternalMessageDialog(Desktop.desktop,
 
               MessageManager.getString("label.couldnt_create_groovy_shell"),
@@ -2625,8 +2679,11 @@ public class Desktop extends jalview.jbgui.GDesktop
   {
     if (groovyConsole == null)
     {
-      groovyConsole = new groovy.ui.Console();
-      groovyConsole.setVariable("Jalview", this);
+      JalviewObjectI j = new JalviewObject(this);
+      groovyConsole = new groovy.console.ui.Console();
+      groovyConsole.setVariable(JalviewObjectI.jalviewObjectName, j);
+      groovyConsole.setVariable(JalviewObjectI.currentAlFrameName,
+              getCurrentAlignFrame());
       groovyConsole.run();
 
       /*
@@ -2699,7 +2756,7 @@ public class Desktop extends jalview.jbgui.GDesktop
      */
     groovyShell.setEnabled(!enabled);
 
-    AlignFrame[] alignFrames = getAlignFrames();
+    AlignFrame[] alignFrames = getDesktopAlignFrames();
     if (alignFrames != null)
     {
       for (AlignFrame af : alignFrames)
@@ -3108,7 +3165,7 @@ public class Desktop extends jalview.jbgui.GDesktop
    */
   private Semaphore block = new Semaphore(0);
 
-  private static groovy.ui.Console groovyConsole;
+  private static groovy.console.ui.Console groovyConsole;
 
   /**
    * add another dialog thread to the queue
@@ -3370,7 +3427,7 @@ public class Desktop extends jalview.jbgui.GDesktop
     myTopFrame.setDisplayedView(myTopFrame.alignPanel);
   }
 
-  public static groovy.ui.Console getGroovyConsole()
+  public static groovy.console.ui.Console getGroovyConsole()
   {
     return groovyConsole;
   }
@@ -3661,32 +3718,34 @@ public class Desktop extends jalview.jbgui.GDesktop
   }
 
   /**
-   * closes the current instance window, disposes and forgets about it.
+   * closes the current instance window, but leaves the JVM running.
+   * Bypasses any shutdown prompts, but does not set window dispose on close in case JVM terminates.
    */
   public static void closeDesktop()
   {
     if (Desktop.instance != null)
     {
-      Desktop.instance.closeAll_actionPerformed(null);
-      Desktop.instance.setVisible(false);
       Desktop us = Desktop.instance;
-      Desktop.instance = null;
+      Desktop.instance.quitTheDesktop(false, false);
       // call dispose in a separate thread - try to avoid indirect deadlocks
-      new Thread(new Runnable()
+      if (us != null)
       {
-        @Override
-        public void run()
+        new Thread(new Runnable()
         {
-          ExecutorService dex = us.dialogExecutor;
-          if (dex != null)
+          @Override
+          public void run()
           {
-            dex.shutdownNow();
-            us.dialogExecutor = null;
-            us.block.drainPermits();
+            ExecutorService dex = us.dialogExecutor;
+            if (dex != null)
+            {
+              dex.shutdownNow();
+              us.dialogExecutor = null;
+              us.block.drainPermits();
+            }
+            us.dispose();
           }
-          us.dispose();
-        }
-      }).start();
+        }).start();
+      }
     }
   }
 
@@ -3747,13 +3806,21 @@ public class Desktop extends jalview.jbgui.GDesktop
   public void nonBlockingDialog(String title, String message, String button,
           int type, boolean scrollable, boolean modal)
   {
-    nonBlockingDialog(32, 2, title, message, null, button, type, scrollable,
-            false, modal);
+    nonBlockingDialog(title, message, null, button, type, scrollable, false,
+            modal, -1);
+  }
+
+  public void nonBlockingDialog(String title, String message,
+          String boxtext, String button, int type, boolean scrollable,
+          boolean html, boolean modal, int timeout)
+  {
+    nonBlockingDialog(32, 2, title, message, boxtext, button, type,
+            scrollable, html, modal, timeout);
   }
 
   public void nonBlockingDialog(int width, int height, String title,
           String message, String boxtext, String button, int type,
-          boolean scrollable, boolean html, boolean modal)
+          boolean scrollable, boolean html, boolean modal, int timeout)
   {
     if (type < 0)
     {
@@ -3815,9 +3882,16 @@ public class Desktop extends jalview.jbgui.GDesktop
 
     jvp.setResponseHandler(JOptionPane.YES_OPTION, () -> {
     });
+    jvp.setTimeout(timeout);
+    JButton jb = new JButton(button);
     jvp.showDialogOnTopAsync(this, jp, title, JOptionPane.YES_OPTION, type,
             null, new Object[]
-            { button }, button, modal, null, false);
+            { button }, button, modal, new JButton[] { jb }, false);
   }
 
+  @Override
+  public AlignFrame getCurrentAlignFrame()
+  {
+    return Jalview.getInstance().getCurrentAlignFrame();
+  }
 }
index 3f5de0a..7a5daf7 100644 (file)
@@ -88,6 +88,13 @@ public class JvOptionPane extends JOptionPane
 
   private Map<Object, Runnable> callbacks = new HashMap<>();
 
+  private int timeout = -1;
+
+  public void setTimeout(int i)
+  {
+    timeout = i;
+  }
+
   /*
    * JalviewJS reports user choice in the dialog as the selected option (text);
    * this list allows conversion to index (int)
@@ -851,6 +858,42 @@ public class JvOptionPane extends JOptionPane
                   "Supplied buttons array not the same length as supplied options array.");
           break NOTNULL;
         }
+
+        // run through buttons for initialValue first so we can set (and start)
+        // a final timeoutThreadF to include (and interrupt) in the button
+        // actions
+        Thread timeoutThread = null;
+        for (int i = 0; i < options.length; i++)
+        {
+          Object o = options[i];
+          JButton jb = buttons[i];
+          if (o.equals(initialValue))
+          {
+            if (timeout > 0 && jb != null && jb instanceof JButton)
+            {
+              // after timeout ms click the default button
+              timeoutThread = new Thread(() -> {
+                try
+                {
+                  Thread.sleep(timeout);
+                } catch (InterruptedException e)
+                {
+                  Console.debug(
+                          "Dialog timeout interrupted.  Probably a button pressed.");
+                }
+                jb.doClick();
+              });
+            }
+            initialValueButton = jb;
+            break;
+          }
+        }
+        final Thread timeoutThreadF = timeoutThread;
+        if (timeoutThreadF != null)
+        {
+          timeoutThreadF.start();
+        }
+
         int[] buttonActions = { JOptionPane.YES_OPTION,
             JOptionPane.NO_OPTION, JOptionPane.CANCEL_OPTION };
         for (int i = 0; i < options.length; i++)
@@ -860,9 +903,6 @@ public class JvOptionPane extends JOptionPane
                   "Setting button " + i + " to '" + o.toString() + "'");
           JButton jb = buttons[i];
 
-          if (o.equals(initialValue))
-            initialValueButton = jb;
-
           int buttonAction = buttonActions[i];
           Runnable action = callbacks.get(buttonAction);
           jb.setText((String) o);
@@ -871,6 +911,10 @@ public class JvOptionPane extends JOptionPane
             @Override
             public void actionPerformed(ActionEvent e)
             {
+              if (timeoutThreadF != null)
+              {
+                timeoutThreadF.interrupt();
+              }
 
               Object obj = e.getSource();
               if (obj == null || !(obj instanceof Component))
@@ -1290,6 +1334,7 @@ public class JvOptionPane extends JOptionPane
 
     // A better hack which works is to create a new JFrame parent with
     // setAlwaysOnTop(true)
+    boolean parentOnTop = dialogParent.isAlwaysOnTop();
     dialogParent.setAlwaysOnTop(true);
     parentComponent = dialogParent;
 
@@ -1297,6 +1342,8 @@ public class JvOptionPane extends JOptionPane
             JOPTIONPANE_MESSAGETYPE, icon, options, initialValue, modal,
             buttons);
 
+    dialogParent.setAlwaysOnTop(parentOnTop);
+
     if (dispose)
     {
       dialogParent.setAlwaysOnTop(false);
index ad7684e..6020135 100644 (file)
@@ -294,7 +294,7 @@ public class QuitHandler
       return QResponse.QUIT;
 
     int size = 0;
-    AlignFrame[] afArray = Desktop.getAlignFrames();
+    AlignFrame[] afArray = Desktop.getDesktopAlignFrames();
     if (!(afArray == null || afArray.length == 0))
     {
       for (int i = 0; i < afArray.length; i++)
index ff409e0..1060d8a 100755 (executable)
@@ -113,8 +113,11 @@ public class SplashScreen extends JPanel
    */
   public SplashScreen(boolean isTransient)
   {
-    Desktop.instance.acquireDialogQueue();
     this.transientDialog = isTransient;
+    if (this.transientDialog)
+    {
+      Desktop.instance.acquireDialogQueue();
+    }
 
     if (Platform.isJS()) // BH 2019
     {
@@ -228,7 +231,8 @@ public class SplashScreen extends JPanel
   protected boolean refreshText()
   {
     String newtext = Desktop.instance.getAboutMessage();
-    // jalview.bin.Console.errPrintln("Text found: \n"+newtext+"\nEnd of newtext.");
+    // jalview.bin.Console.errPrintln("Text found: \n"+newtext+"\nEnd of
+    // newtext.");
     if (oldTextLength != newtext.length())
     {
       iframe.setVisible(false);
@@ -324,7 +328,6 @@ public class SplashScreen extends JPanel
     }
 
     closeSplash();
-    Desktop.instance.releaseDialogQueue();
   }
 
   /**
@@ -332,10 +335,14 @@ public class SplashScreen extends JPanel
    */
   public void closeSplash()
   {
+    if (this.transientDialog)
+    {
+      Desktop.instance.releaseDialogQueue();
+    }
     try
     {
 
-      iframe.setClosed(true);
+      iframe.setClosed(true); // ##### implicated BLOCKED
     } catch (Exception ex)
     {
     }
index 6fbd422..2d4bdc8 100755 (executable)
@@ -406,9 +406,9 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       }
 
       int ystart = (node.left() == null ? 0
-              : (int) (((BinaryNode) node.left()).ycount * chunk)) + offy;
+              : (int) (node.left().ycount * chunk)) + offy;
       int yend = (node.right() == null ? 0
-              : (int) (((BinaryNode) node.right()).ycount * chunk)) + offy;
+              : (int) (node.right().ycount * chunk)) + offy;
 
       Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
       nodeHash.put(node, pos);
@@ -791,11 +791,11 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
 
     if (top.count == 0)
     {
-      top.count = ((BinaryNode) top.left()).count
-              + ((BinaryNode) top.right()).count;
+      top.count = top.left().count
+              + top.right().count;
     }
 
-    double chunk = (double) (height - (offy)) / (double)top.count;
+    float chunk = (float) (height - (offy)) / top.count;
 
     drawNode(g2, tree.getTopNode(), chunk, wscale, width, offx, offy);
 
index 196eb32..d8259f9 100644 (file)
@@ -1325,7 +1325,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
    */
   protected void updateWebServiceMenus()
   {
-    for (AlignFrame alignFrame : Desktop.getAlignFrames())
+    for (AlignFrame alignFrame : Desktop.getDesktopAlignFrames())
     {
       alignFrame.BuildWebServiceMenu();
     }
index 6d00a7d..c983dfe 100644 (file)
@@ -28,4 +28,9 @@ public enum DataSourceType
   {
     return this != FILE;
   }
+
+  public boolean isUrl()
+  {
+    return this == URL || this == RELATIVE_URL;
+  }
 }
index dc7adac..b16c37f 100755 (executable)
@@ -361,8 +361,9 @@ public class FileLoader implements Runnable
           // We read the data anyway - it might make sense.
         }
         // BH 2018 switch to File object here instead of filename
-        alignFrame = new Jalview2XML(raiseGUI && !Jalview.isBatchMode()).loadJalviewAlign(
-                selectedFile == null ? file : selectedFile);
+        alignFrame = new Jalview2XML(raiseGUI && !Jalview.isBatchMode())
+                .loadJalviewAlign(
+                        selectedFile == null ? file : selectedFile);
       }
       else
       {
@@ -563,7 +564,8 @@ public class FileLoader implements Runnable
 
     } catch (Exception er)
     {
-      jalview.bin.Console.errPrintln("Exception whilst opening file '" + file);
+      jalview.bin.Console
+              .errPrintln("Exception whilst opening file '" + file);
       er.printStackTrace();
       if (raiseGUI && !Jalview.isBatchMode())
       {
@@ -603,7 +605,8 @@ public class FileLoader implements Runnable
           }
         });
       }
-      jalview.bin.Console.errPrintln("Out of memory loading file " + file + "!!");
+      jalview.bin.Console
+              .errPrintln("Out of memory loading file " + file + "!!");
 
     }
     loadtime += System.currentTimeMillis();
@@ -684,10 +687,18 @@ public class FileLoader implements Runnable
     AlignViewport avp = af.getViewport();
     if (avp == null)
       return;
-    avp.setSavedUpToDate(!protocol.isDynamic(),
-            QuitHandler.Message.UNSAVED_ALIGNMENTS);
+    boolean upToDate = !protocol.isDynamic();
+    if (protocol.isUrl() && !Cache
+            .getDefault(PROMPT_SAVE_UNCHANGED_URL_ALIGNMENTS, true))
+    {
+      upToDate = true;
+    }
+    avp.setSavedUpToDate(upToDate,
+            upToDate ? null : QuitHandler.Message.UNSAVED_ALIGNMENTS);
   }
 
+  public static final String PROMPT_SAVE_UNCHANGED_URL_ALIGNMENTS = "PROMPT_SAVE_UNCHANGED_URL_ALIGNMENTS";
+
   public static boolean getUseDefaultFileFormat()
   {
     return useDefaultFileFormat;
index c3776d3..46b75c8 100644 (file)
@@ -151,7 +151,7 @@ public class VamsasAppDatastore
   private void buildSkipList()
   {
     skipList = new Hashtable();
-    AlignFrame[] al = Desktop.getAlignFrames();
+    AlignFrame[] al = Desktop.getDesktopAlignFrames();
     for (int f = 0; al != null && f < al.length; f++)
     {
       skipList.put(al[f].getViewport().getSequenceSetId(), al[f]);
index af3b2c8..cc20fce 100644 (file)
@@ -631,7 +631,7 @@ public class Jalview2XML
    */
   public void saveState(JarOutputStream jout)
   {
-    AlignFrame[] frames = Desktop.getAlignFrames();
+    AlignFrame[] frames = Desktop.getDesktopAlignFrames();
 
     setStateSavedUpToDate(true);
 
@@ -6919,7 +6919,7 @@ public class Jalview2XML
     if (stateSavedUpToDate()) // nothing happened since last project save
       return true;
 
-    AlignFrame[] frames = Desktop.getAlignFrames();
+    AlignFrame[] frames = Desktop.getDesktopAlignFrames();
     if (frames != null)
     {
       for (int i = 0; i < frames.length; i++)
index 9bd247a..2f1ddc0 100644 (file)
@@ -1050,7 +1050,7 @@ public class StructureSelectionManager
           int indexpos = sm.getSeqPos(atom.getPdbResNum());
           if (lastipos != indexpos || lastseq != sm.sequence)
           {
-            results.addResult(sm.sequence, indexpos, indexpos);
+            results.appendResult(sm.sequence, indexpos, indexpos);
             lastipos = indexpos;
             lastseq = sm.sequence;
             // construct highlighted sequence list
index 4b11494..dcedafa 100644 (file)
@@ -884,14 +884,7 @@ public abstract class AAStructureBindingModel
       {
         for (int s : cs.getSelected())
         {
-          if (hiddenCols == null)
-          {
             matched.set(s);
-          }
-          else
-          {
-            matched.set(hiddenCols.visibleToAbsoluteColumn(s));
-          }
         }
       }
       else
index c4e4b04..8b5240c 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.workers;
 
+import java.awt.Color;
+
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.Jalview;
@@ -27,8 +29,6 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.gui.AlignFrame;
 
-import java.awt.Color;
-
 /**
  * Factory class with methods which allow clients (including external scripts
  * such as Groovy) to 'register and forget' an alignment annotation calculator.
@@ -52,7 +52,7 @@ public class AlignmentAnnotationFactory
    */
   public static void newCalculator(FeatureSetCounterI counter)
   {
-    AlignmentViewPanel currentAlignFrame = Jalview
+    AlignmentViewPanel currentAlignFrame = Jalview.getInstance()
             .getCurrentAlignFrame().alignPanel;
     if (currentAlignFrame == null)
     {
@@ -74,7 +74,8 @@ public class AlignmentAnnotationFactory
   {
     // TODO need an interface for AlignFrame by which to access
     // its AlignViewportI and AlignmentViewPanel
-    AlignFrame currentAlignFrame = Jalview.getCurrentAlignFrame();
+    AlignFrame currentAlignFrame = Jalview.getInstance()
+            .getCurrentAlignFrame();
     if (currentAlignFrame != null)
     {
       new AnnotationWorker(currentAlignFrame.getViewport(),
index 8dae8f3..de6185c 100644 (file)
@@ -96,7 +96,7 @@ public class CommandsTest
   }
   */
 
-  @Test(groups = "Functional", dataProvider = "cmdLines")
+  @Test(groups = {"Functional","testTask3"}, dataProvider = "cmdLines")
   public void commandsOpenTest(String cmdLine, boolean cmdArgs,
           int numFrames, String[] sequences)
   {
@@ -111,13 +111,13 @@ public class CommandsTest
       Assert.assertEquals(cmds.argsWereParsed(), cmdArgs,
               "Overall command parse and operation is false");
 
-      Assert.assertEquals(Desktop.getAlignFrames().length, numFrames,
+      Assert.assertEquals(Desktop.getDesktopAlignFrames().length, numFrames,
               "Wrong number of AlignFrames");
 
       if (sequences != null)
       {
         Set<String> openedSequenceNames = new HashSet<>();
-        AlignFrame[] afs = Desktop.getAlignFrames();
+        AlignFrame[] afs = Desktop.getDesktopAlignFrames();
         for (AlignFrame af : afs)
         {
           openedSequenceNames.addAll(
@@ -147,7 +147,7 @@ public class CommandsTest
 
   @Test(
     groups =
-    { "Functional", "testTask1" },
+    { "Functional", "testTask3" },
     dataProvider = "structureImageOutputFiles")
   public void structureImageOutputTest(String cmdLine, String[] filenames)
           throws IOException
@@ -325,7 +325,7 @@ public class CommandsTest
 
   public static boolean lookForSequenceName(String sequenceName)
   {
-    AlignFrame[] afs = Desktop.getAlignFrames();
+    AlignFrame[] afs = Desktop.getDesktopAlignFrames();
     for (AlignFrame af : afs)
     {
       for (String name : af.getViewport().getAlignment().getSequenceNames())
index ae14c1a..a78ca5a 100644 (file)
@@ -79,7 +79,7 @@ public class CommandsTest2
     }
     ;
 
-    AlignFrame[] afs = Desktop.getAlignFrames();
+    AlignFrame[] afs = Desktop.getDesktopAlignFrames();
     Assert.assertNotNull(afs);
     Assert.assertTrue(afs.length > 0);
 
index b1bb43c..8059af9 100644 (file)
@@ -206,6 +206,32 @@ public class SearchResultsTest
     assertFalse(m.contains(null, 3, 3));
   }
 
+  @Test(groups = { "Functional" })
+  public void testMatchAdjacent()
+  {
+    SequenceI seq1 = new Sequence("", "abcdefghijklm");
+    SequenceI seq2 = new Sequence("", "abcdefghijklm");
+    SearchResultMatchI m = new SearchResults().new Match(seq1, 2, 5);
+
+    assertTrue(m.adjacent(seq1, 2, 5));
+    assertTrue(m.adjacent(seq1, 3, 5));
+    assertTrue(m.adjacent(seq1, 2, 4));
+    assertTrue(m.adjacent(seq1, 3, 3));
+
+    assertTrue(m.adjacent(seq1, 2, 6));
+    assertTrue(m.adjacent(seq1, 1, 5));
+    assertTrue(m.adjacent(seq1, 1, 8));
+    assertFalse(m.adjacent(seq1, 0, 0));
+    assertFalse(m.adjacent(seq1, 7, 8));
+    assertTrue(m.adjacent(seq1, 6, 8));
+    assertTrue(m.adjacent(seq1, 5, 8));
+    assertTrue(m.adjacent(seq1, 0, 1));
+    
+    
+    assertFalse(m.adjacent(seq2, 3, 3));
+    assertFalse(m.adjacent(null, 3, 3));
+  }
+
   /**
    * test markColumns for creating column selections
    */
@@ -308,6 +334,36 @@ public class SearchResultsTest
   }
 
   /**
+   * Test to verify appending creates a minimal set of results
+   */
+  @Test(groups = { "Functional" })
+  public void testAppendResult()
+  {
+    SequenceI seq1 = new Sequence("", "abcdefghijklm"),seq2=new Sequence("","defdefdefdef");
+    SearchResultsI sr = new SearchResults();
+    sr.appendResult(seq1, 3, 5);
+    assertEquals(1, sr.getCount());
+    sr.appendResult(seq1, 3, 6);
+    assertEquals(1, sr.getCount());
+    sr.appendResult(seq1, 8, 8);
+    assertEquals(2, sr.getCount());
+    sr.appendResult(seq1, 7, 7);
+    assertEquals(1, sr.getCount());
+    sr.appendResult(seq2, 7, 7);
+    assertEquals(2, sr.getCount());
+    sr.appendResult(seq2, 2, 7);
+    assertTrue(sr.appendResult(seq2, 7, 49));
+    assertTrue(sr.appendResult(seq2, 0, 30));
+    assertEquals(2, sr.getCount());
+    int c=0;
+    for (SearchResultMatchI sre: sr.getResults())
+    {
+      c++;
+    }
+    assertEquals(c,2);
+    
+  }
+  /**
    * Test for method that checks if search results matches a sequence region
    */
   @Test(groups = { "Functional" })
index 5bf3507..f8fdb63 100644 (file)
@@ -135,7 +135,7 @@ public class DesktopTests
     {
       Assert.fail("Unexpected exception " + x);
     }
-    AlignFrame[] alfs = Desktop.getAlignFrames();
+    AlignFrame[] alfs = Desktop.getDesktopAlignFrames();
     Assert.assertEquals("Expect just 2 alignment frames", 2, alfs.length);
     // internal paste should yield a new alignment window with shared dataset
     AlignmentI dataset = internalSource.getViewport().getAlignment()
index c46477a..34cc17f 100644 (file)
@@ -186,7 +186,7 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
         SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
                 forSource, forAccession);
         sf.run();
-        AlignFrame[] afs = Desktop.getAlignFrames();
+        AlignFrame[] afs = Desktop.getDesktopAlignFrames();
         if (afs.length == 0)
         {
           failedDBRetr.add("Didn't retrieve " + first);
index 5f9af25..ce34044 100644 (file)
@@ -84,24 +84,28 @@ public class JvCacheableInputBoxTest
     cacheBox.addItem(testInput);
     cacheBox.setSelectedItem(testInput);
     cacheBox.updateCache();
-
-    try
+    boolean done[]=new boolean[] { false };
+    // this event gets processed after updateCache's update event on the swing
+    // thread
+    SwingUtilities.invokeLater(() -> {
+        done[0]=true;
+    });
+    long t=0;
+    while (!done[0] && t<200)
     {
-      // fix for JAL-4153
-      // This delay is to let cacheBox.updateCache() finish updating the cache
-      SwingUtilities.invokeAndWait(() -> {
-        try
-        {
-          Thread.sleep(1);
+      try {
+        Thread.sleep(7);
+        t++;
         } catch (InterruptedException e)
         {
           e.printStackTrace();
         }
-      });
-    } catch (InvocationTargetException | InterruptedException e)
+    }
+    if (!done[0])
     {
-      e.printStackTrace();
+      Assert.fail("Giving up after 1.4s waiting for cache to be updated.");
     }
+    
     LinkedHashSet<String> foundCache = appCache
             .getAllCachedItemsFor(TEST_CACHE_KEY);
     Assert.assertTrue(foundCache.contains(testInput));
index c9532cc..aa4be3d 100644 (file)
@@ -287,12 +287,12 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   @Test(groups = { "Functional" })
   public void gatherViewsHere() throws Exception
   {
-    int origCount = Desktop.getAlignFrames() == null ? 0
-            : Desktop.getAlignFrames().length;
+    int origCount = Desktop.getDesktopAlignFrames() == null ? 0
+            : Desktop.getDesktopAlignFrames().length;
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
             "examples/exampleFile_2_7.jar", DataSourceType.FILE);
     assertNotNull(af, "Didn't read in the example file correctly.");
-    assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
+    assertTrue(Desktop.getDesktopAlignFrames().length == 1 + origCount,
             "Didn't gather the views in the example file.");
 
   }
@@ -430,7 +430,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
             "examples/exampleFile_2_7.jar", DataSourceType.FILE);
-    Assert.assertEquals(Desktop.getAlignFrames().length, 1);
+    Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 1);
     String afid = af.getViewport().getSequenceSetId();
 
     // check FileLoader returned a reference to the one alignFrame that is
@@ -440,8 +440,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
     Desktop.explodeViews(af);
 
-    int oldviews = Desktop.getAlignFrames().length;
-    Assert.assertEquals(Desktop.getAlignFrames().length,
+    int oldviews = Desktop.getDesktopAlignFrames().length;
+    Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
             Desktop.getAlignmentPanels(afid).length);
     File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
     try
@@ -455,14 +455,14 @@ public class Jalview2xmlTests extends Jalview2xmlBase
       Assert.fail("Didn't save the expanded view state", e);
     }
     Desktop.instance.closeAll_actionPerformed(null);
-    if (Desktop.getAlignFrames() != null)
+    if (Desktop.getDesktopAlignFrames() != null)
     {
-      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+      Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
     }
     af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
             DataSourceType.FILE);
     Assert.assertNotNull(af);
-    Assert.assertEquals(Desktop.getAlignFrames().length,
+    Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
             Desktop.getAlignmentPanels(
                     af.getViewport().getSequenceSetId()).length);
     Assert.assertEquals(Desktop
@@ -519,9 +519,9 @@ public class Jalview2xmlTests extends Jalview2xmlBase
       Assert.fail("Didn't save the expanded view state", e);
     }
     Desktop.instance.closeAll_actionPerformed(null);
-    if (Desktop.getAlignFrames() != null)
+    if (Desktop.getDesktopAlignFrames() != null)
     {
-      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+      Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
     }
 
     af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
@@ -698,9 +698,9 @@ public class Jalview2xmlTests extends Jalview2xmlBase
       Assert.fail("Didn't save the expanded view state", e);
     }
     Desktop.instance.closeAll_actionPerformed(null);
-    if (Desktop.getAlignFrames() != null)
+    if (Desktop.getDesktopAlignFrames() != null)
     {
-      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+      Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
     }
 
     af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
@@ -792,9 +792,9 @@ public class Jalview2xmlTests extends Jalview2xmlBase
       Assert.fail("Didn't save the state", e);
     }
     Desktop.instance.closeAll_actionPerformed(null);
-    if (Desktop.getAlignFrames() != null)
+    if (Desktop.getDesktopAlignFrames() != null)
     {
-      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+      Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
     }
 
     AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
@@ -1217,7 +1217,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     assertNotNull(af);
 
     AlignmentI ds = null;
-    for (AlignFrame alignFrame : Desktop.getAlignFrames())
+    for (AlignFrame alignFrame : Desktop.getDesktopAlignFrames())
     {
       if (ds == null)
       {
index 53f98c3..0472317 100644 (file)
@@ -638,7 +638,7 @@ public class FeatureRendererTest
     /*
      * find the complement frames (ugly)
      */
-    AlignFrame[] frames = Desktop.getAlignFrames();
+    AlignFrame[] frames = Desktop.getDesktopAlignFrames();
     assertEquals(frames.length, 2);
     AlignViewport av1 = frames[0].getViewport();
     AlignViewport av2 = frames[1].getViewport();