Merge branch 'features/JAL-2110_crossRefDuplications' into merge_JAL-2110
authorJim Procter <jprocter@issues.jalview.org>
Tue, 21 Jun 2016 15:13:05 +0000 (16:13 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Tue, 21 Jun 2016 15:13:05 +0000 (16:13 +0100)
100 files changed:
examples/appletDeployment.html
examples/appletParameters.html
examples/groovy/printtitle.groovy
examples/testdata/simpleGff3.gff
examples/testdata/test.html
help/html/calculations/consensus.html
help/html/calculations/conservation.html
help/html/features/annotation.html
help/html/features/bioJsonFormat.html
help/html/features/groovy.html
help/html/menus/desktopMenu.html
help/html/releases.html
help/html/whatsNew.html
resources/lang/Messages.properties
resources/lang/Messages_es.properties
schemas/jalview.xsd
src/jalview/api/FeatureColourI.java
src/jalview/api/FeatureRenderer.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/FeatureColourChooser.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/FeatureSettings.java
src/jalview/appletgui/SequenceRenderer.java
src/jalview/appletgui/UserDefinedColours.java
src/jalview/bin/ArgsParser.java [new file with mode: 0644]
src/jalview/bin/Jalview.java
src/jalview/datamodel/HiddenSequences.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/datamodel/xdb/embl/EmblEntry.java
src/jalview/ext/ensembl/EnsemblGene.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AnnotationExporter.java
src/jalview/gui/Desktop.java
src/jalview/gui/FeatureColourChooser.java
src/jalview/gui/FeatureRenderer.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/JDatabaseTree.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/SequenceFetcher.java
src/jalview/gui/SequenceRenderer.java
src/jalview/gui/StructureChooser.java
src/jalview/io/FeaturesFile.java
src/jalview/io/HtmlSvgOutput.java
src/jalview/io/PDBFeatureSettings.java
src/jalview/io/packed/JalviewDataset.java
src/jalview/io/packed/ParsePackedSet.java
src/jalview/jbgui/GStructureChooser.java
src/jalview/renderer/seqfeatures/FeatureRenderer.java
src/jalview/schemabinding/version2/.castor.cdr
src/jalview/schemabinding/version2/JSeq.java
src/jalview/schemabinding/version2/descriptors/AnnotationColoursDescriptor.java
src/jalview/schemabinding/version2/descriptors/FeaturesDescriptor.java
src/jalview/schemabinding/version2/descriptors/JSeqDescriptor.java
src/jalview/schemabinding/version2/descriptors/JalviewUserColoursDescriptor.java
src/jalview/schemabinding/version2/descriptors/UserColourSchemeDescriptor.java
src/jalview/schemabinding/version2/descriptors/VamsasModelDescriptor.java
src/jalview/schemes/FeatureColour.java [new file with mode: 0644]
src/jalview/schemes/FeatureColourAdapter.java [deleted file]
src/jalview/schemes/GraduatedColor.java [deleted file]
src/jalview/schemes/UserColourScheme.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/util/ImageMaker.java
src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
src/jalview/viewmodel/seqfeatures/FeatureRendererSettings.java
src/jalview/workers/AlignmentAnnotationFactory.java
src/jalview/ws/dbsources/Pdb.java
src/jalview/ws/jws1/SeqSearchWSThread.java
src/jalview/ws/jws2/AADisorderClient.java
test/jalview/bin/ArgsParserTest.java [new file with mode: 0644]
test/jalview/datamodel/PDBEntryTest.java
test/jalview/ext/ensembl/EnsemblCdnaTest.java
test/jalview/ext/ensembl/EnsemblCdsTest.java
test/jalview/ext/ensembl/EnsemblGeneTest.java
test/jalview/ext/ensembl/EnsemblGenomeTest.java
test/jalview/ext/ensembl/EnsemblSeqProxyTest.java
test/jalview/ext/jmol/JmolViewerTest.java
test/jalview/ext/rbvi/chimera/JalviewChimeraView.java
test/jalview/ext/so/SequenceOntologyTest.java
test/jalview/fts/service/pdb/PDBFTSPanelTest.java
test/jalview/fts/service/pdb/PDBFTSRestClientTest.java
test/jalview/gui/JAL1353bugdemo.java
test/jalview/gui/PaintRefresherTest.java
test/jalview/gui/StructureChooserTest.java
test/jalview/io/AnnotatedPDBFileInputTest.java
test/jalview/io/FeaturesFileTest.java
test/jalview/io/FileIOTester.java
test/jalview/io/JSONFileTest.java
test/jalview/io/Jalview2xmlTests.java
test/jalview/io/JalviewExportPropertiesTests.java
test/jalview/io/NewickFileTests.java
test/jalview/io/RNAMLfileTest.java
test/jalview/schemes/FeatureColourTest.java [new file with mode: 0644]
test/jalview/schemes/UserColourSchemeTest.java [new file with mode: 0644]
test/jalview/ws/PDBSequenceFetcherTest.java
test/jalview/ws/jabaws/JalviewJabawsTestUtils.java
test/jalview/ws/jabaws/JpredJabaStructExportImport.java
test/jalview/ws/jabaws/RNAStructExportImport.java
test/jalview/ws/seqfetcher/DbRefFetcherTest.java

index a7653ed..87953df 100644 (file)
 <div id="view_decorated" name="view_decorated"  style="margin:8px; padding:10px; border: 2px solid red; text-align:center; display:none;"><b>Click <a href="index.html#appletDeployment"> here</a> to view decorated page</b></div>
 
 <!-- content start -->
-<h2><a name="appletdeploymentnotes"/>Notes on applet deployment</h2>
+<h2><a name="appletDeployment"/>Notes on applet deployment</h2>
+<table width=80% border="1">
+  <tr><th colspan="2" align="center">Required Dependency Downloads</th></tr>
+  <tr>
+    <th>Dependency</th>
+    <th>Description</th>
+  </tr>
+  <tr>
+    <td><a href="http://www.jalview.org/builds/develop/examples/jalviewApplet.jar">JalviewApplet.jar</a> </td>
+    <td>Main Jalview Applet Jar</td>
+  </tr>
+  <tr>
+    <td><a href="http://www.jalview.org/builds/develop/examples/JmolApplet-14.2.14_2015.06.11.jar">JmolApplet-14.2.14_2015.06.11.jar</a> </td>
+    <td>Jmol Applet Jar</td>
+  </tr>
+  <tr>
+    <td><a href="http://www.jalview.org/builds/develop/examples/java-json.jar">java-json.jar</a></td>
+    <td>Required for BioJSON Generation</td>
+  </tr>
+  <tr>
+    <td><a href="http://www.jalview.org/builds/develop/examples/json_simple-1.1.jar">json_simple-1.1.jar</a></td>
+    <td>Required for BioJSON Generation</td>
+  </tr>
+</table>
+
         <ul>
           <li>Package all your data files into a single (or multiple) zip / jar 
             files. This is very useful to reduce download time of large data files. 
index 433f5a9..cc95ecb 100644 (file)
@@ -28,7 +28,7 @@ which are described <a href="#parameters"> below</a>. Once initialised,
 the applet can be interacted with <em>via</em> its 
 <a href="javascript:doSubmit('jalviewLiteJs')">Javascript API</a>. 
 </p><p><strong>Issues arising from tightening of Java Security default settings</strong><br/>JalviewLite is provided as a signed applet with 'sandbox' permissions and wildcards that allow it to be run from any website. Unfortunately, earlier versions of Java may not be compatible with these settings. </p>
-    <p>For additional deployment notes, <a href="#appletdeploymentnotes">see below</a>.</p>
+    <p>For additional deployment notes, <a href="javascript:doSubmit('appletDeployment')">see Applet Deployment</a>.</p>
            <p><h2>Applet Parameters</h2><br/>The applet takes the following initialisation parameters.</p>
         <a name="parameters"></a>        <table width="97%" class="borderTable" align="center" >
           <tr> 
index 813df63..b3387ea 100644 (file)
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 // do something groovy in jalview
-print "Hello World.\n";
-def alf = Jalview.getAlignFrames();
+println "Hello World.\n"
+println "First sequence is " + currentAlFrame.viewport.alignment.getSequenceAt(0).getDisplayId(true)
+
+def alf = Jalview.getAlignFrames()
 for (ala in alf)
 {
        // ala is an jalview.gui.AlignFrame object 
-       print ala.getTitle()+"\n";
+       println ala.getTitle()
        // get the parent jalview.datamodel.Alignment from the alignment viewport
-       def alignment = ala.viewport.alignment;
+       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 34b64ee..614b440 100644 (file)
@@ -24,4 +24,3 @@ seq1  exonerate:protein2genome:local  similarity      9       11      3652    -       .       alignment_id 0 ; Qu
 ACTACGACACGACGACGACGACG
 >seq2
 CDEQEATGTQDAQEQAQC
-
index 229596c..1e41232 100644 (file)
@@ -26,4 +26,4 @@ subCatContainer.scroll(
 function() {
 subCatContainer.scrollTop($(this).scrollTop());
 });
-</script></hmtl>
\ No newline at end of file
+</script></html>
index 0a0214e..c870887 100644 (file)
   <strong>Normalise Consensus Logo</strong> to scale all columns of the
   logo to the same height.
 
+    <p>
+    <strong>Group Consensus</strong><br>
+    If sequence groups have been defined, then selecting option 'Group Consensus' in the <a href="../menus/alwannotation.html">Annotations menu</a> will 
+    result in Consensus being calculated for each group, as well as the alignment as a whole.
+  </p>
   <p>
     <strong>cDNA Consensus</strong>
   </p>
index df8b5ff..9cb8ce1 100755 (executable)
     (e.g. !proline).
   </p>
   <p>
-    <em>Colouring an alignment by conservation</em><br>
+    <strong>Colouring an alignment by conservation</strong><br>
     Conservation scores can be used to colour an alignment. This is
     explained further in the help page for <a
       href="../colourSchemes/conservation.html"
     >conservation colouring</a>.
   </p>
+  <p>
+    <strong>Group conservation</strong><br>
+    If sequence groups have been defined, then selecting option 'Group Conservation' in the <a href="../menus/alwannotation.html">Annotations menu</a> will 
+    result in Conservation being calculated for each group, as well as the alignment as a whole.
+  </p>
 </body>
 </html>
index a645630..7e52c46 100755 (executable)
@@ -48,6 +48,25 @@ alignment window or loaded from the alignment's file menu.
                        href="../webServices/proteinDisorder.html">disordered region</a>
                prediction methods. 
 </p>
+<p><strong>Sequence Group Annotation</strong>
+</p>
+<p>
+       If sequence groups are defined, <a href="../calculations/conservation.html">Conservation</a>
+        and <a href="../calculations/consensus.html">Consensus</a> annotation can be enabled
+       for each group from the <a href="../menus/alwannotation.html">Annotations menu</a>, or can
+       be imported from a Jalview <a href="annotationsFormat.html">Annotations file</a>.
+</p>
+<p><strong>Sequence Selection from Annotation</strong>
+</p>
+<p>
+    Sequences associated with sequence (or sequence group) annotations can be selected by
+    double-clicking the annotation label with these key combinations:
+    <ul>
+    <li>double-click - Select associated sequences (replaces current selection)</li>
+    <li>shift double-click - add  sequences to selection</li>
+    <li>Ctrl (Mac CMD) double-click - toggles inclusion of associated sequences in the current selection</li>
+    </ul>
+    Note this also works in combination with manual sequence selection in the alignment.
 <p><strong>Interactive Alignment Annotation</strong></p>
 <p>
 Annotation rows are added using the <strong>Annotation Label</strong>
index f8f87dc..cb7ccc0 100644 (file)
@@ -20,7 +20,7 @@
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
 <head>
-<title>BioJSON in Jalviwe</title>
+<title>BioJSON in Jalview</title>
 </head>
 <body>
   <p>
index 9aa341b..a2bc627 100644 (file)
@@ -56,6 +56,9 @@
     </em>
   </p>
   <p>
+    <strong>Executing a groovy script on a particular alignment</strong><br/>
+    
+  <p>
     <strong>Access to Jalview's functions from Groovy Scripts</strong><br>
     There is as yet no properly defined scripting interface to Jalview,
     but all the public methods of the jalview class hierarchy can be
index 15c94ce..edbd1e9 100755 (executable)
@@ -82,8 +82,7 @@
             <a href="../webServices/newsreader.html">Jalview News</a>
             dialog box.
         </em></li>
-        <li><strong>Groovy Console...<em> (only
-              available if groovy is on the classpath)</em><br></strong> <em>Opens
+        <li><strong>Groovy Console...<br></strong> <em>Opens
             the <a href="../features/groovy.html">Groovy Console</a> for
             interactive scripting.
         </em><strong><br></strong></li>
index 2b2184b..0e7d02d 100755 (executable)
       <td><em>General</em>
         <ul>
             <li><!-- JAL---></li>
+            <li><!-- JAL-192 --->Alignment ruler shows positions relative to reference sequence</li>
         </ul> <em>Application</em>
         <ul>
             <li><!-- JAL---></li>
             <li><!-- JAL-2027-->Support for reverse-complement coding regions in ENA and EMBL</li>
             <li><!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2 for ENA record retrieval</li>
+            <li><!--  JAL 1812 -->New 'execute Groovy script' option in an alignment window's Calculate menu</li>
+            <li><!--  JAL 1812 -->Allow groovy scripts that call Jalview.getAlignFrames() to run in headless mode</li>
+            <li><!-- JAL-1369 --->Store/restore reference sequence in Jalview projects</li>
+             
         </ul> <em>Applet</em>
         <ul>
             <li><!-- JAL---></li>
@@ -73,6 +78,8 @@
             <li><!-- JAL-2067, JAL-  -->Tidied up links in help file table of contents</li>
             <li><!-- JAL-2072  -->Feature based tree calculation not shown for DNA alignments</li>
             <li><!-- JAL-2075  -->Hidden columns ignored during feature based tree calculation</li>
+            <li><!-- JAL-2065  -->Alignment view stops updating when show unconserved enabled for group on alignment</li>
+            <li><!--  JAL-2086  -->Cannot insert gaps into sequence when set as reference</li>
             
           </ul>
           <em>Application</em>
@@ -82,6 +89,9 @@
             <li><!-- JAL-1552-->URLs and links can imported by drag'n'drop on OSX webstart</li>
             <li><!-- JAL-2030-->InstallAnywhere distribution fails when launching Chimera</li>
             <li><!-- JAL-2080-->Jalview very slow to launch via webstart (also hotfix for 2.9.0b2)</li>
+            <li><!--  JAL-2085  -->Cannot save project when view has a reference sequence defined</li>
+            <li><!--  JAL-1011  -->Columns are suddenly selected in other alignments and views when revealing hidden columns</li>
+            <li><!--  JAL-1989  -->Hide columns not mirrored in complement view in a cDNA/Protein splitframe</li>
             <!--  may exclude, this is an external service stability issue  JAL-1941 /> RNA 3D structure not added via DSSR service</li> -->
           </ul>
           <em>Applet</em>
index 19be76f..d7a93c6 100755 (executable)
     <strong>What's new ?</strong>
   </p>
   <p>
-    Jalview 2.9.0b2 is a bug fix release for Jalview 2.9.
-    The release of Jalview 2.9 in September 2015 included
-    a multitude of bug fixes and minor improvements (both small, and
-    rather big!), it also brings major new capabilities for codon-level
-    analysis of protein alignments and the retrieval and manipulation of
-    structural data.</p><p>For the patches since version 2.9 was released, see the
-    <a href="releases.html#Jalview.2.9.0b2">Jalview 2.9.0b2 Release Notes</a>.
+    Jalview 2.9.1 is the next major release in the Jalview 2.9 series. Full details are in the
+    <a href="releases.html#Jalview.2.9.1">Jalview 2.9.1 Release Notes</a>.
   </p>
   <p>
-    <strong>Highlights in Jalview 2.9</strong>
+    <strong>Highlights in Jalview 2.9.1</strong>
   <ul>
-    <li><strong>Visualisation, editing and analysis of
-        cDNA and Protein alignments</strong><br />A new <a
-      href="features/splitView.html">Split View</a> window allows linked
-      protein and nucleotide sequence alignments to be viewed, edited,
-      and analysed as one. <br />cDNA alignments can also be
-      reconstructed from protein alignments calculated by Jalview's web
-      services, and update in response to edits in the amino acid view.<br />To
-      start experimenting with cDNA/Protein analysis, jut drop a file
-      containing cDNA sequences which code for proteins in an existing
-      alignment, and Jalview will do the rest.</li>
-    <li><strong>Enhanced Integration of UCSF Chimera</strong> <br>Jalview
-      2.9 provides full support for the use of Chimera to view 3D
-      structures linked to alignment views in the Jalview Desktop. We've
-      also included support for saving Chimera sessions in Jalview
-      project files.<br />Jalview and Chimera communicate using local
-      web server connections, which may cause firewall alerts on some
-      systems, but has the advantage of allowing bidirectional
-      communication. Communication between Jalview and Chimera is now
-      much more responsive, and selected regions in Chimera are now
-      shown as highlighted regions in the Jalview desktop.</li>
-    <li><strong>Interactive querying of the PDBe</strong><br />Jalview
-      users can now <a href="features/pdbsequencefetcher.html">browse</a> and <a href="features/viewingpdbs.html">retrieve 3D structure</a> data from the PDB
-      via the <a href="http://www.ebi.ac.uk/pdbe/api/doc/search.html">PDBe
-        Search API</a> (<a href="http://dx.doi.org/10.1093%2Fnar%2Fgkt1180">Gutmanas
-        et al 2014</a>). Developed in collaboration with the PDBe group at
-      EMBL-EBI, the interface allows both structured and free-text
-      queries to be performed, and allows automatic selection of the
-      most relevant structures for an alignment acording to a variety of
-      criteria.</li>
-    <li><strong>Improved support for RNA visualisation</strong><br />Jalview
-      2.9 integrates the latest version of the <a
-      href="features/varna.html">VARNA RNA Viewer</a>, and VARNA views
-      can also now be stored in Jalview projects. We've also dealt with
-      a number of lingering bugs in the VARNA/Jalview interface,
-      including the loss of pseudoknots when RNA secondary structure is
-      shown VARNA.</li>
-    <li><strong>Protein Secondary Structure predictions
-        with JPred4</strong><br />Jalview includes a number of new features for
-      working with secondary structure predictions from the JPred4
-      server. These include new <a href="menus/popupMenu.html#hideinserts">popup menu actions</a> to automatically hide insertions and highlight
-      mutations in an alignment with respect to a <a href="calculations/referenceseq.html">Reference
-        Sequence</a>. Jalview 2.9's new <a href="io/export.html#htmlexport">scrollable
-        SVG HTML export</a> was also developed specifically for the JPred4
-      server.</li>
   </ul>
 
 </body>
index cb9aa77..40c311f 100644 (file)
@@ -675,7 +675,7 @@ label.view_all_representative_structures = View all {0} representative structure
 label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Opens a new structure viewer with all representative structures\nassociated with the current selection\nsuperimposed with the current alignment.
 label.associate_structure_with_sequence = Associate Structure with Sequence
 label.from_file = From File
-label.enter_pdb_id = Enter PDB Id
+label.enter_pdb_id = Enter PDB Id (or pdbid:chaincode)
 label.discover_pdb_ids = Discover PDB IDs
 label.text_colour = Text Colour
 action.set_text_colour = Text Colour...
@@ -972,7 +972,6 @@ error.eps_generation_not_implemented = EPS Generation not yet implemented
 error.png_generation_not_implemented = PNG Generation not yet implemented
 error.try_join_vamsas_session_another = Trying to join a vamsas session when another is already connected
 error.invalid_vamsas_session_id = Invalid vamsas session id
-error.implementation_error_cannot_create_groovyshell = Implementation Error. Cannot create groovyShell without Groovy on the classpath!
 label.groovy_support_failed = Jalview Groovy Support Failed
 label.couldnt_create_groovy_shell = Couldn't create the groovy Shell. Check the error log for the details of what went wrong.
 error.unsupported_version_calcIdparam = Unsupported Version for calcIdparam {0}
@@ -1302,3 +1301,10 @@ label.next_page_tooltip=Next Page
 label.prev_page_tooltip=Previous Page
 exception.bad_request=Bad request. There is a problem with your input.
 exception.service_not_available=Service not available. The server is being updated, try again later.
+status.launching_3d_structure_viewer = Launching 3D Structure viewer...
+status.fetching_3d_structures_for_selected_entries = Fetching 3D Structures for selected entries...
+status.fetching_dbrefs_for_sequences_without_valid_refs = Fetching db refs for {0} sequence(s) without valid db ref required for SIFTS mapping
+status.fetching_3d_structures_for = Fetching 3D Structure for {0}
+status.obtaining_mapping_with_sifts = Obtaining mapping with SIFTS
+status.obtaining_mapping_with_nw_alignment = Obtaining mapping with NW alignment
+status.exporting_alignment_as_x_file = Exporting alignment as {0} file
index 49056ef..f814c97 100644 (file)
@@ -905,7 +905,6 @@ error.eps_generation_not_implemented = La generaci
 error.png_generation_not_implemented = La generación de PNG no se ha implementado todavía
 error.try_join_vamsas_session_another = Tratando de establecer una sesión VAMSAS cuando ya había otra conectada
 error.invalid_vamsas_session_id = Identificador de sesión VAMSAS no válido
-error.implementation_error_cannot_create_groovyshell = Error de implementación:no se puede crear groovyShell sin Groovy en el classpath
 label.groovy_support_failed = El soporte Groovy de Jalview ha fallado
 label.couldnt_create_groovy_shell = No es posible crear el shell de Groovy. Compruebe el fichero de log para conocer los detalles.
 error.unsupported_version_calcIdparam = Versión no soportada de {0}
@@ -1308,3 +1307,9 @@ label.sifts_mapping=Mapeado SIFTs
 label.mapping_method=Método de mapeo de secuencia \u27F7 estructura
 info.error_creating_file=Error al crear fichero {0}
 exception.fts_rest_service_no_longer_available= Servicios Rest {0} ya no están disponibles! 
+status.launching_3d_structure_viewer=Lanzando visualizador de estructura 3D...
+status.obtaining_mapping_with_sifts=Obteniendo mapeo por SIFTS
+status.fetching_3d_structures_for=Buscando la estructura 3D para {0}
+status.fetching_3d_structures_for_selected_entries=Buscando las estructuras 3D para entradas seleccionadas...
+status.fetching_dbrefs_for_sequences_without_valid_refs=Buscando referencias para {0} secuencia(s) sin referencia válida necesaria para mapeado SIFTS
+status.obtaining_mapping_with_nw_alignment=Obteniendo mapeo por alineamiento Needleman y Wunsch
\ No newline at end of file
index 850b223..f0bd638 100755 (executable)
                                                <xs:attribute name="end" type="xs:int" use="required" />
                                                <xs:attribute name="id" type="xs:string" use="required" />
                                                <xs:attribute name="hidden" type="xs:boolean" />
+                                               <xs:attribute name="viewreference" type="xs:boolean" use="optional"/>
                                        </xs:complexType>
                                </xs:element>
                                <xs:element name="JGroup" minOccurs="0" maxOccurs="unbounded">
index d8363f4..1fcbfd0 100644 (file)
@@ -1,13 +1,14 @@
 package jalview.api;
 
+import jalview.datamodel.SequenceFeature;
+
 import java.awt.Color;
 
 public interface FeatureColourI
 {
 
   /**
-   * Answers true when either isColourByLabel, isAboveThreshold or
-   * isBelowThreshold answers true
+   * Answers true when the feature colour varies across the score range
    * 
    * @return
    */
@@ -35,13 +36,22 @@ public interface FeatureColourI
   Color getMaxColour();
 
   /**
-   * Answers true if the feature is coloured by label (description); only
-   * applicable when isGraduatedColour answers true
+   * Answers true if the feature has a single colour, i.e. if isColourByLabel()
+   * and isGraduatedColour() both answer false
+   * 
+   * @return
+   */
+  boolean isSimpleColour();
+
+  /**
+   * Answers true if the feature is coloured by label (description)
    * 
    * @return
    */
   boolean isColourByLabel();
 
+  void setColourByLabel(boolean b);
+
   /**
    * Answers true if the feature is coloured below a threshold value; only
    * applicable when isGraduatedColour answers true
@@ -50,6 +60,8 @@ public interface FeatureColourI
    */
   boolean isBelowThreshold();
 
+  void setBelowThreshold(boolean b);
+
   /**
    * Answers true if the feature is coloured above a threshold value; only
    * applicable when isGraduatedColour answers true
@@ -58,14 +70,20 @@ public interface FeatureColourI
    */
   boolean isAboveThreshold();
 
+  void setAboveThreshold(boolean b);
+
   /**
-   * Answers true if the threshold is the min (or max) of the colour range; only
-   * applicable when isGraduatedColour answers true
+   * Answers true if the threshold is the minimum value (when
+   * isAboveThreshold()) or maximum value (when isBelowThreshold()) of the
+   * colour range; only applicable when isGraduatedColour and either
+   * isAboveThreshold() or isBelowThreshold() answers true
    * 
    * @return
    */
   boolean isThresholdMinMax();
 
+  void setThresholdMinMax(boolean b);
+
   /**
    * Returns the threshold value (if any), else zero
    * 
@@ -73,10 +91,71 @@ public interface FeatureColourI
    */
   float getThreshold();
 
+  void setThreshold(float f);
+
+  /**
+   * Answers true if the colour varies between the actual minimum and maximum
+   * score values of the feature, or false if between absolute minimum and
+   * maximum values (or if not a graduated colour).
+   * 
+   * @return
+   */
+  boolean isAutoScaled();
+
+  void setAutoScaled(boolean b);
+
+  /**
+   * Returns the maximum score of the graduated colour range
+   * 
+   * @return
+   */
+  float getMax();
+
+  /**
+   * Returns the minimum score of the graduated colour range
+   * 
+   * @return
+   */
+  float getMin();
+
+  /**
+   * Answers true if either isAboveThreshold or isBelowThreshold answers true
+   * 
+   * @return
+   */
+  boolean hasThreshold();
+
+  /**
+   * Returns the computed colour for the given sequence feature
+   * 
+   * @param feature
+   * @return
+   */
+  Color getColor(SequenceFeature feature);
+
+  /**
+   * Answers true if the feature has a simple colour, or is coloured by label,
+   * or has a graduated colour and the score of this feature instance is within
+   * the range to render (if any), i.e. does not lie below or above any
+   * threshold set.
+   * 
+   * @param feature
+   * @return
+   */
+  boolean isColored(SequenceFeature feature);
+
+  /**
+   * Update the min-max range for a graduated colour scheme
+   * 
+   * @param min
+   * @param max
+   */
+  void updateBounds(float min, float max);
+
   /**
-   * Answers true if ?
+   * Returns the colour in Jalview features file format
    * 
    * @return
    */
-  boolean isLowToHigh();
+  String toJalviewFormat(String featureType);
 }
index d9795a6..dbc9880 100644 (file)
@@ -60,17 +60,15 @@ public interface FeatureRenderer
    * @param ft
    * @return display style for a feature
    */
-  Object getFeatureStyle(String ft);
+  FeatureColourI getFeatureStyle(String ft);
 
   /**
    * update the feature style for a particular feature
    * 
    * @param ft
    * @param ggc
-   *          - currently allows java.awt.Color and
-   *          jalview.schemes.GraduatedColor
    */
-  void setColour(String ft, Object ggc);
+  void setColour(String ft, FeatureColourI ggc);
 
   AlignViewportI getViewport();
 
@@ -85,7 +83,7 @@ public interface FeatureRenderer
    * 
    * @return
    */
-  Map<String, Object> getFeatureColours();
+  Map<String, FeatureColourI> getFeatureColours();
 
   /**
    * query the alignment view to find all features
@@ -100,7 +98,7 @@ public interface FeatureRenderer
    * 
    * @return
    */
-  Map<String, Object> getDisplayedFeatureCols();
+  Map<String, FeatureColourI> getDisplayedFeatureCols();
 
   /**
    * get all registered groups
index e5f0053..8f1f2fd 100644 (file)
@@ -25,6 +25,7 @@ import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.AlignViewportI;
+import jalview.api.FeatureColourI;
 import jalview.api.FeatureRenderer;
 import jalview.api.FeatureSettingsControllerI;
 import jalview.api.SequenceStructureBinding;
@@ -367,7 +368,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     boolean featuresFile = false;
     try
     {
-      Map<String, Object> colours = alignPanel.seqPanel.seqCanvas
+      Map<String, FeatureColourI> colours = alignPanel.seqPanel.seqCanvas
               .getFeatureRenderer().getFeatureColours();
       boolean relaxedIdMatching = viewport.applet.getDefaultParameter(
               "relaxedidmatch", false);
@@ -1399,7 +1400,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     return annotation;
   }
 
-  private Map<String, Object> getDisplayedFeatureCols()
+  private Map<String, FeatureColourI> getDisplayedFeatureCols()
   {
     if (alignPanel.getFeatureRenderer() != null
             && viewport.getFeaturesDisplayed() != null)
index 46a67c4..3c04ccd 100644 (file)
  */
 package jalview.appletgui;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.GraphLine;
 import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
 import jalview.util.MessageManager;
 
 import java.awt.Checkbox;
@@ -60,9 +61,9 @@ public class FeatureColourChooser extends Panel implements ActionListener,
 
   // AlignmentPanel ap;
 
-  GraduatedColor cs;
+  FeatureColourI cs;
 
-  Object oldcs;
+  FeatureColourI oldcs;
 
   Hashtable oldgroupColours;
 
@@ -91,29 +92,29 @@ public class FeatureColourChooser extends Panel implements ActionListener,
   {
     this.type = type;
     fr = frenderer;
-    float mm[] = ((float[][]) fr.getMinMax().get(type))[0];
+    float mm[] = fr.getMinMax().get(type)[0];
     min = mm[0];
     max = mm[1];
     oldcs = fr.getFeatureColours().get(type);
-    if (oldcs instanceof GraduatedColor)
+    if (oldcs.isGraduatedColour())
     {
-      cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
+      cs = new FeatureColour((FeatureColour) oldcs, min, max);
     }
     else
     {
       // promote original color to a graduated color
       Color bl = Color.black;
-      if (oldcs instanceof Color)
+      if (oldcs.isSimpleColour())
       {
-        bl = (Color) oldcs;
+        bl = oldcs.getColour();
       }
       // original colour becomes the maximum colour
-      cs = new GraduatedColor(Color.white, bl, mm[0], mm[1]);
+      cs = new FeatureColour(Color.white, bl, mm[0], mm[1]);
     }
-    minColour.setBackground(cs.getMinColor());
-    maxColour.setBackground(cs.getMaxColor());
-    minColour.setForeground(cs.getMinColor());
-    maxColour.setForeground(cs.getMaxColor());
+    minColour.setBackground(cs.getMinColour());
+    maxColour.setBackground(cs.getMaxColour());
+    minColour.setForeground(cs.getMinColour());
+    maxColour.setForeground(cs.getMaxColour());
     colourFromLabel.setState(cs.isColourByLabel());
     adjusting = true;
 
@@ -123,10 +124,8 @@ public class FeatureColourChooser extends Panel implements ActionListener,
     } catch (Exception ex)
     {
     }
-    threshold
-            .select(cs.getThreshType() == AnnotationColourGradient.NO_THRESHOLD ? 0
-                    : cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1
-                            : 2);
+    threshold.select(cs.isAboveThreshold() ? 1 : (cs.isBelowThreshold() ? 2
+            : 0));
 
     adjusting = false;
     changeColour();
@@ -259,6 +258,7 @@ public class FeatureColourChooser extends Panel implements ActionListener,
 
   private GraphLine threshline;
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == thresholdValue)
@@ -286,6 +286,7 @@ public class FeatureColourChooser extends Panel implements ActionListener,
     }
   }
 
+  @Override
   public void itemStateChanged(ItemEvent evt)
   {
     maxColour.setEnabled(!colourFromLabel.getState());
@@ -293,19 +294,20 @@ public class FeatureColourChooser extends Panel implements ActionListener,
     changeColour();
   }
 
+  @Override
   public void adjustmentValueChanged(AdjustmentEvent evt)
   {
     if (!adjusting)
     {
-      thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
+      thresholdValue.setText((slider.getValue() / 1000f) + "");
       valueChanged();
     }
   }
 
   protected void valueChanged()
   {
-    threshline.value = (float) slider.getValue() / 1000f;
-    cs.setThresh(threshline.value);
+    threshline.value = slider.getValue() / 1000f;
+    cs.setThreshold(threshline.value);
     changeColour();
     PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
     // ap.paintAlignment(false);
@@ -369,7 +371,7 @@ public class FeatureColourChooser extends Panel implements ActionListener,
 
     slider.setEnabled(true);
     thresholdValue.setEnabled(true);
-    GraduatedColor acg = new GraduatedColor(minColour.getBackground(),
+    FeatureColour acg = new FeatureColour(minColour.getBackground(),
             maxColour.getBackground(), min, max);
 
     acg.setColourByLabel(colourFromLabel.getState());
@@ -393,7 +395,7 @@ public class FeatureColourChooser extends Panel implements ActionListener,
     if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
     {
       adjusting = true;
-      acg.setThresh(threshline.value);
+      acg.setThreshold(threshline.value);
 
       float range = max * 1000f - min * 1000f;
 
@@ -406,17 +408,17 @@ public class FeatureColourChooser extends Panel implements ActionListener,
       adjusting = false;
     }
 
-    acg.setThreshType(aboveThreshold);
+    acg.setAboveThreshold(true);
     if (thresholdIsMin.getState()
             && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
     {
       if (aboveThreshold == AnnotationColourGradient.ABOVE_THRESHOLD)
       {
-        acg = new GraduatedColor(acg, threshline.value, max);
+        acg = new FeatureColour(acg, threshline.value, max);
       }
       else
       {
-        acg = new GraduatedColor(acg, min, threshline.value);
+        acg = new FeatureColour(acg, min, threshline.value);
       }
     }
 
@@ -434,14 +436,17 @@ public class FeatureColourChooser extends Panel implements ActionListener,
 
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
   }
 
+  @Override
   public void mousePressed(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     if (evt.getSource() == minColour || evt.getSource() == maxColour)
@@ -456,10 +461,12 @@ public class FeatureColourChooser extends Panel implements ActionListener,
     // ap.paintAlignment(true);
   }
 
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseExited(MouseEvent evt)
   {
   }
index a93cdcb..3f87549 100644 (file)
  */
 package jalview.appletgui;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.io.FeaturesFile;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.UserColourScheme;
 import jalview.util.MessageManager;
 import jalview.viewmodel.AlignmentViewport;
 
@@ -43,6 +45,9 @@ import java.awt.TextArea;
 import java.awt.TextField;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Hashtable;
 
 /**
  * DOCUMENT ME!
@@ -53,11 +58,15 @@ import java.awt.event.ActionListener;
 public class FeatureRenderer extends
         jalview.renderer.seqfeatures.FeatureRenderer
 {
+
+  // Holds web links for feature groups and feature types
+  // in the form label|link
+  Hashtable featureLinks = null;
+
   /**
    * Creates a new FeatureRenderer object.
    * 
    * @param av
-   *          DOCUMENT ME!
    */
   public FeatureRenderer(AlignmentViewport av)
   {
@@ -88,51 +97,35 @@ public class FeatureRenderer extends
     /**
      * render a feature style in the amend feature dialog box
      */
-    public void updateColor(Object newcol)
+    public void updateColor(FeatureColourI newcol)
     {
-
-      Color bg, col = null;
-      GraduatedColor gcol = null;
+      Color bg = null;
       String vlabel = "";
-      if (newcol instanceof Color)
+      if (newcol.isSimpleColour())
       {
-        isGcol = false;
-        col = (Color) newcol;
-        gcol = null;
-      }
-      else if (newcol instanceof GraduatedColor)
-      {
-        isGcol = true;
-        gcol = (GraduatedColor) newcol;
-        col = null;
+        bg = newcol.getColour();
+        setBackground(bg);
       }
       else
       {
-        throw new Error(
-                MessageManager
-                        .getString("error.invalid_colour_for_mycheckbox"));
-      }
-      if (col != null)
-      {
-        setBackground(bg = col);
-      }
-      else
-      {
-        if (gcol.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
+        if (newcol.isAboveThreshold())
         {
-          vlabel += " "
-                  + ((gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)"
-                          : "(<)");
+          vlabel += " (>)";
         }
-        if (isColourByLabel = gcol.isColourByLabel())
+        else if (newcol.isBelowThreshold())
+        {
+          vlabel += " (<)";
+        }
+
+        if (isColourByLabel = newcol.isColourByLabel())
         {
           setBackground(bg = Color.white);
           vlabel += " (by Label)";
         }
         else
         {
-          setBackground(bg = gcol.getMinColor());
-          maxCol = gcol.getMaxColor();
+          setBackground(bg = newcol.getMinColour());
+          maxCol = newcol.getMaxColour();
         }
       }
       label = vlabel;
@@ -239,11 +232,12 @@ public class FeatureRenderer extends
             ap.seqPanel.seqCanvas.highlightSearchResults(highlight);
 
           }
-          Object col = getFeatureStyle(name.getText());
+          FeatureColourI col = getFeatureStyle(name.getText());
           if (col == null)
           {
-            col = new jalview.schemes.UserColourScheme()
+            Color generatedColour = UserColourScheme
                     .createColourFromName(name.getText());
+            col = new FeatureColour(generatedColour);
           }
 
           colourPanel.updateColor(col);
@@ -351,15 +345,16 @@ public class FeatureRenderer extends
     start.setText(features[0].getBegin() + "");
     end.setText(features[0].getEnd() + "");
     description.setText(features[0].getDescription());
-    Object fcol = getFeatureStyle(name.getText());
+    // lookup (or generate) the feature colour
+    FeatureColourI fcol = getFeatureStyle(name.getText());
     // simply display the feature color in a box
     colourPanel.updateColor(fcol);
     dialog.setResizable(true);
     // TODO: render the graduated color in the box.
-    colourPanel.addMouseListener(new java.awt.event.MouseAdapter()
+    colourPanel.addMouseListener(new MouseAdapter()
     {
       @Override
-      public void mousePressed(java.awt.event.MouseEvent evt)
+      public void mousePressed(MouseEvent evt)
       {
         if (!colourPanel.isGcol)
         {
@@ -367,15 +362,14 @@ public class FeatureRenderer extends
         }
         else
         {
-          FeatureColourChooser fcc = new FeatureColourChooser(
-                  ap.alignFrame, name.getText());
+          new FeatureColourChooser(ap.alignFrame, name.getText());
           dialog.transferFocus();
         }
       }
     });
     dialog.setVisible(true);
 
-    jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();
+    FeaturesFile ffile = new FeaturesFile();
 
     if (dialog.accept)
     {
@@ -404,7 +398,7 @@ public class FeatureRenderer extends
         if (!colourPanel.isGcol)
         {
           // update colour - otherwise its already done.
-          setColour(sf.type, colourPanel.getBackground());
+          setColour(sf.type, new FeatureColour(colourPanel.getBackground()));
         }
         try
         {
@@ -444,7 +438,7 @@ public class FeatureRenderer extends
         {
           setGroupVisibility(lastFeatureGroupAdded, true);
         }
-        setColour(lastFeatureAdded, newColour); // was fcol
+        setColour(lastFeatureAdded, new FeatureColour(newColour)); // was fcol
         setVisible(lastFeatureAdded);
         findAllFeatures(false); // different to original applet behaviour ?
         // findAllFeatures();
index 7ae318c..bfac241 100755 (executable)
  */
 package jalview.appletgui;
 
+import jalview.api.FeatureColourI;
 import jalview.api.FeatureSettingsControllerI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceFeature;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -190,8 +189,8 @@ public class FeatureSettings extends Panel implements ItemListener,
           int x, int y)
   {
     final String type = check.type;
-    final Object typeCol = fr.getFeatureStyle(type);
-    java.awt.PopupMenu men = new PopupMenu(MessageManager.formatMessage(
+    final FeatureColourI typeCol = fr.getFeatureStyle(type);
+    PopupMenu men = new PopupMenu(MessageManager.formatMessage(
             "label.settings_for_type", new String[] { type }));
     java.awt.MenuItem scr = new MenuItem(
             MessageManager.getString("label.sort_by_score"));
@@ -243,7 +242,7 @@ public class FeatureSettings extends Panel implements ItemListener,
         // graduated colourschemes for those where minmax exists for the
         // positional features
         MenuItem mxcol = new MenuItem(
-                (typeCol instanceof Color) ? "Graduated Colour"
+                (typeCol.isSimpleColour()) ? "Graduated Colour"
                         : "Single Colour");
         men.add(mxcol);
         mxcol.addActionListener(new ActionListener()
@@ -252,7 +251,7 @@ public class FeatureSettings extends Panel implements ItemListener,
           @Override
           public void actionPerformed(ActionEvent e)
           {
-            if (typeCol instanceof Color)
+            if (typeCol.isSimpleColour())
             {
               new FeatureColourChooser(me, type);
               // write back the current colour object to update the table
@@ -260,8 +259,7 @@ public class FeatureSettings extends Panel implements ItemListener,
             }
             else
             {
-              new UserDefinedColours(me, check.type,
-                      ((GraduatedColor) typeCol));
+              new UserDefinedColours(me, check.type, typeCol);
             }
           }
 
@@ -637,19 +635,9 @@ public class FeatureSettings extends Panel implements ItemListener,
     }
   }
 
-  public void setUserColour(String feature, Object originalColour)
+  public void setUserColour(String feature, FeatureColourI originalColour)
   {
-    if (originalColour instanceof Color
-            || originalColour instanceof GraduatedColor)
-    {
-      fr.setColour(feature, originalColour);
-    }
-    else
-    {
-      throw new Error(
-              MessageManager
-                      .getString("error.implementation_error_unsupported_feature_colour_object"));
-    }
+    fr.setColour(feature, originalColour);
     refreshTable();
   }
 
@@ -686,10 +674,10 @@ public class FeatureSettings extends Panel implements ItemListener,
 
     if (evt.getClickCount() > 1)
     {
-      Object fcol = fr.getFeatureStyle(check.type);
-      if (fcol instanceof Color)
+      FeatureColourI fcol = fr.getFeatureStyle(check.type);
+      if (fcol.isSimpleColour())
       {
-        new UserDefinedColours(this, check.type, (Color) fcol);
+        new UserDefinedColours(this, check.type, fcol.getColour());
       }
       else
       {
@@ -721,49 +709,34 @@ public class FeatureSettings extends Panel implements ItemListener,
 
     boolean hasLink;
 
-    GraduatedColor gcol;
+    FeatureColourI col;
 
-    Color col;
-
-    public void updateColor(Object newcol)
+    public void updateColor(FeatureColourI newcol)
     {
-      if (newcol instanceof Color)
-      {
-        col = (Color) newcol;
-        gcol = null;
-      }
-      else if (newcol instanceof GraduatedColor)
+      col = newcol;
+      if (col.isSimpleColour())
       {
-        gcol = (GraduatedColor) newcol;
-        col = null;
-      }
-      else
-      {
-        throw new Error(
-                MessageManager
-                        .getString("error.invalid_colour_for_mycheckbox"));
-      }
-      if (col != null)
-      {
-        setBackground(col);
+        setBackground(col.getColour());
       }
       else
       {
         String vlabel = type;
-        if (gcol.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
+        if (col.isAboveThreshold())
         {
-          vlabel += " "
-                  + ((gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)"
-                          : "(<)");
+          vlabel += " (>)";
         }
-        if (gcol.isColourByLabel())
+        else if (col.isBelowThreshold())
+        {
+          vlabel += " (<)";
+        }
+        if (col.isColourByLabel())
         {
           setBackground(Color.white);
           vlabel += " (by Label)";
         }
         else
         {
-          setBackground(gcol.getMinColor());
+          setBackground(col.getMinColour());
         }
         this.setLabel(vlabel);
       }
@@ -780,7 +753,7 @@ public class FeatureSettings extends Panel implements ItemListener,
     }
 
     public MyCheckbox(String type, boolean selected, boolean b,
-            Object featureStyle)
+            FeatureColourI featureStyle)
     {
       this(type, selected, b);
       updateColor(featureStyle);
@@ -790,31 +763,28 @@ public class FeatureSettings extends Panel implements ItemListener,
     public void paint(Graphics g)
     {
       Dimension d = getSize();
-      if (gcol != null)
+      if (col.isColourByLabel())
       {
-        if (gcol.isColourByLabel())
-        {
-          g.setColor(Color.white);
-          g.fillRect(d.width / 2, 0, d.width / 2, d.height);
-          /*
-           * g.setColor(Color.black); Font f=g.getFont().deriveFont(9);
-           * g.setFont(f);
-           * 
-           * // g.setFont(g.getFont().deriveFont( //
-           * AffineTransform.getScaleInstance( //
-           * width/g.getFontMetrics().stringWidth("Label"), //
-           * height/g.getFontMetrics().getHeight()))); g.drawString("Label",
-           * width/2, 0);
-           */
+        g.setColor(Color.white);
+        g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+        /*
+         * g.setColor(Color.black); Font f=g.getFont().deriveFont(9);
+         * g.setFont(f);
+         * 
+         * // g.setFont(g.getFont().deriveFont( //
+         * AffineTransform.getScaleInstance( //
+         * width/g.getFontMetrics().stringWidth("Label"), //
+         * height/g.getFontMetrics().getHeight()))); g.drawString("Label",
+         * width/2, 0);
+         */
 
-        }
-        else
-        {
-          Color maxCol = gcol.getMaxColor();
-          g.setColor(maxCol);
-          g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+      }
+      else if (col.isGraduatedColour())
+      {
+        Color maxCol = col.getMaxColour();
+        g.setColor(maxCol);
+        g.fillRect(d.width / 2, 0, d.width / 2, d.height);
 
-        }
       }
 
       if (hasLink)
@@ -825,11 +795,6 @@ public class FeatureSettings extends Panel implements ItemListener,
     }
   }
 
-  @Override
-  public void mousePressed(MouseEvent e)
-  {
-  }
-
   /**
    * Hide columns containing (or not containing) a given feature type
    * 
@@ -850,4 +815,11 @@ public class FeatureSettings extends Panel implements ItemListener,
     }
   }
 
+  @Override
+  public void mousePressed(MouseEvent e)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
 }
index 09b50c4..970d20e 100755 (executable)
@@ -32,6 +32,8 @@ import java.awt.Graphics;
 
 public class SequenceRenderer implements jalview.api.SequenceRenderer
 {
+  final static int CHAR_TO_UPPER = 'A' - 'a';
+
   AlignViewport av;
 
   FontMetrics fm;
@@ -67,6 +69,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
     this.renderGaps = renderGaps;
   }
 
+  @Override
   public Color getResidueBoxColour(SequenceI seq, int i)
   {
     allGroups = av.getAlignment().findAllGroups(seq);
@@ -256,7 +259,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
         }
         if (currentSequenceGroup.getShowNonconserved())
         {
-          s = getDisplayChar(srep, i, s, '.');
+          s = getDisplayChar(srep, i, s, '.', currentSequenceGroup);
         }
       }
       else
@@ -280,7 +283,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
         }
         if (av.getShowUnconserved())
         {
-          s = getDisplayChar(srep, i, s, '.');
+          s = getDisplayChar(srep, i, s, '.', null);
 
         }
       }
@@ -312,20 +315,43 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
 
   }
 
-  private char getDisplayChar(final boolean usesrep, int position, char s,
-          char c)
+  /**
+   * Returns 'conservedChar' to represent the given position if the sequence
+   * character at that position is equal to the consensus (ignoring case), else
+   * returns the sequence character
+   * 
+   * @param usesrep
+   * @param position
+   * @param sequenceChar
+   * @param conservedChar
+   * @return
+   */
+  private char getDisplayChar(final boolean usesrep, int position,
+          char sequenceChar, char conservedChar, SequenceGroup currentGroup)
   {
     // TODO - use currentSequenceGroup rather than alignment
     // currentSequenceGroup.getConsensus()
-    char conschar = (usesrep) ? av.getAlignment().getSeqrep()
-            .getCharAt(position)
-            : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
-                    .charAt(0);
-    if (!jalview.util.Comparison.isGap(conschar) && s == conschar)
+    char conschar = (usesrep) ? (currentGroup == null
+            || position < currentGroup.getStartRes()
+            || position > currentGroup.getEndRes() ? av.getAlignment()
+            .getSeqrep().getCharAt(position)
+            : (currentGroup.getSeqrep() != null ? currentGroup.getSeqrep()
+                    .getCharAt(position) : av.getAlignment().getSeqrep()
+                    .getCharAt(position)))
+            : (currentGroup != null && currentGroup.getConsensus() != null
+                    && position >= currentGroup.getStartRes()
+                    && position <= currentGroup.getEndRes() && currentGroup
+                    .getConsensus().annotations.length > position) ? currentGroup
+                    .getConsensus().annotations[position].displayCharacter
+                    .charAt(0)
+                    : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
+                            .charAt(0);
+    if (!jalview.util.Comparison.isGap(conschar)
+            && (sequenceChar == conschar || sequenceChar + CHAR_TO_UPPER == conschar))
     {
-      s = c;
+      sequenceChar = conservedChar;
     }
-    return s;
+    return sequenceChar;
   }
 
   boolean inCurrentSequenceGroup(int res)
index 57cf669..88098a9 100644 (file)
  */
 package jalview.appletgui;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.SequenceGroup;
 import jalview.schemes.ColourSchemeI;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
 import jalview.schemes.ResidueProperties;
 import jalview.schemes.UserColourScheme;
 import jalview.util.MessageManager;
@@ -59,7 +60,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
 
   Button selectedButton;
 
-  Vector oldColours = new Vector();
+  Vector<Color> oldColours = new Vector<Color>();
 
   ColourSchemeI oldColourScheme;
 
@@ -75,7 +76,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
 
   String originalLabel;
 
-  Object originalColour;
+  FeatureColourI originalColour;
 
   int R = 0, G = 0, B = 0;
 
@@ -117,7 +118,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
   public UserDefinedColours(FeatureRenderer fr, Frame alignframe)
   {
     caller = fr;
-    originalColour = fr.colourPanel.getBackground();
+    originalColour = new FeatureColour(fr.colourPanel.getBackground());
     originalLabel = "Feature Colour";
     setForDialog("Select Feature Colour", alignframe);
     setTargetColour(fr.colourPanel.getBackground());
@@ -134,21 +135,21 @@ public class UserDefinedColours extends Panel implements ActionListener,
    * 
    * @param caller
    *          - handles events
-   * @param col1
+   * @param col
    *          - original colour
    * @param alignframe
    *          - the parent Frame for the dialog
    * @param title
    *          - window title
    */
-  public UserDefinedColours(Component caller, Color col1, Frame alignframe,
+  public UserDefinedColours(Component caller, Color col, Frame alignframe,
           String title)
   {
     this.caller = caller;
-    originalColour = col1;
+    originalColour = new FeatureColour(col);
     originalLabel = title;
     setForDialog(title, alignframe);
-    setTargetColour(col1);
+    setTargetColour(col);
     dialog.setVisible(true);
   }
 
@@ -161,7 +162,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
    */
   public UserDefinedColours(Object caller, String label, Color colour)
   {
-    this(caller, label, colour, colour);
+    this(caller, label, new FeatureColour(colour), colour);
   }
 
   /**
@@ -172,13 +173,13 @@ public class UserDefinedColours extends Panel implements ActionListener,
    * @param graduatedColor
    */
   public UserDefinedColours(FeatureSettings me, String type,
-          GraduatedColor graduatedColor)
+          FeatureColourI graduatedColor)
   {
-    this(me, type, graduatedColor, graduatedColor.getMaxColor());
+    this(me, type, graduatedColor, graduatedColor.getMaxColour());
   }
 
-  private UserDefinedColours(Object caller, String label, Object ocolour,
-          Color colour)
+  private UserDefinedColours(Object caller, String label,
+          FeatureColourI ocolour, Color colour)
   {
     this.caller = caller;
     originalColour = ocolour;
@@ -228,6 +229,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
 
   }
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     final Object source = evt.getSource();
@@ -257,6 +259,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
     }
   }
 
+  @Override
   public void adjustmentValueChanged(AdjustmentEvent evt)
   {
     if (evt.getSource() == rScroller)
@@ -420,6 +423,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
     button.setFont(new java.awt.Font("Verdana", 1, 10));
     button.addMouseListener(new java.awt.event.MouseAdapter()
     {
+      @Override
       public void mousePressed(MouseEvent e)
       {
         colourButtonPressed(e);
@@ -451,7 +455,8 @@ public class UserDefinedColours extends Panel implements ActionListener,
     {
       if (caller instanceof FeatureSettings)
       {
-        ((FeatureSettings) caller).setUserColour(originalLabel, getColor());
+        ((FeatureSettings) caller).setUserColour(originalLabel,
+                new FeatureColour(getColor()));
       }
       else if (caller instanceof AnnotationColourChooser)
       {
@@ -468,7 +473,8 @@ public class UserDefinedColours extends Panel implements ActionListener,
       }
       else if (caller instanceof FeatureRenderer)
       {
-        ((FeatureRenderer) caller).colourPanel.updateColor(getColor());
+        ((FeatureRenderer) caller).colourPanel
+                .updateColor(new FeatureColour(getColor()));
       }
       else if (caller instanceof FeatureColourChooser)
       {
@@ -537,12 +543,12 @@ public class UserDefinedColours extends Panel implements ActionListener,
         if (originalLabel.equals("Min Colour"))
         {
           ((AnnotationColourChooser) caller)
-                  .minColour_actionPerformed((Color) originalColour);
+                  .minColour_actionPerformed(originalColour.getColour());
         }
         else
         {
           ((AnnotationColourChooser) caller)
-                  .maxColour_actionPerformed((Color) originalColour);
+                  .maxColour_actionPerformed(originalColour.getColour());
         }
       }
       else if (caller instanceof FeatureRenderer)
@@ -556,12 +562,12 @@ public class UserDefinedColours extends Panel implements ActionListener,
         if (originalLabel.indexOf("inimum") > -1)
         {
           ((FeatureColourChooser) caller)
-                  .minColour_actionPerformed((Color) originalColour);
+                  .minColour_actionPerformed(originalColour.getColour());
         }
         else
         {
           ((FeatureColourChooser) caller)
-                  .maxColour_actionPerformed((Color) originalColour);
+                  .maxColour_actionPerformed(originalColour.getColour());
         }
       }
       if (dialog != null)
@@ -576,7 +582,7 @@ public class UserDefinedColours extends Panel implements ActionListener,
     Color[] newColours = new Color[24];
     for (int i = 0; i < 24; i++)
     {
-      newColours[i] = (Color) oldColours.elementAt(i);
+      newColours[i] = oldColours.elementAt(i);
       buttonPanel.getComponent(i).setBackground(newColours[i]);
     }
 
diff --git a/src/jalview/bin/ArgsParser.java b/src/jalview/bin/ArgsParser.java
new file mode 100644 (file)
index 0000000..9c8d0df
--- /dev/null
@@ -0,0 +1,97 @@
+package jalview.bin;
+
+import java.net.URLDecoder;
+import java.util.Vector;
+
+/**
+ * Notes: this argParser does not distinguish between parameter switches,
+ * parameter values and argument text. If an argument happens to be identical to
+ * a parameter, it will be taken as such (even though it didn't have a '-'
+ * prefixing it).
+ * 
+ * @author Andrew Waterhouse and JBP documented.
+ * 
+ */
+public class ArgsParser
+{
+  Vector<String> vargs = null;
+
+  public ArgsParser(String[] args)
+  {
+    vargs = new Vector<String>();
+    for (int i = 0; i < args.length; i++)
+    {
+      String arg = args[i].trim();
+      if (arg.charAt(0) == '-')
+      {
+        arg = arg.substring(1);
+      }
+      vargs.addElement(arg);
+    }
+  }
+
+  /**
+   * check for and remove first occurence of arg+parameter in arglist.
+   * 
+   * @param arg
+   * @return return the argument following the given arg if arg was in list.
+   */
+  public String getValue(String arg)
+  {
+    return getValue(arg, false);
+  }
+
+  public String getValue(String arg, boolean utf8decode)
+  {
+    int index = vargs.indexOf(arg);
+    String dc = null, ret = null;
+    if (index != -1)
+    {
+      ret = vargs.elementAt(index + 1).toString();
+      vargs.removeElementAt(index);
+      vargs.removeElementAt(index);
+      if (utf8decode && ret != null)
+      {
+        try
+        {
+          dc = URLDecoder.decode(ret, "UTF-8");
+          ret = dc;
+        } catch (Exception e)
+        {
+          // TODO: log failure to decode
+        }
+      }
+    }
+    return ret;
+  }
+
+  /**
+   * check for and remove first occurence of arg in arglist.
+   * 
+   * @param arg
+   * @return true if arg was present in argslist.
+   */
+  public boolean contains(String arg)
+  {
+    if (vargs.contains(arg))
+    {
+      vargs.removeElement(arg);
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+  public String nextValue()
+  {
+    return vargs.remove(0);
+  }
+
+  public int getSize()
+  {
+    return vargs.size();
+  }
+
+}
\ No newline at end of file
index d0b3232..76ae3ff 100755 (executable)
  */
 package jalview.bin;
 
+import groovy.lang.Binding;
+import groovy.util.GroovyScriptEngine;
+
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
+import jalview.gui.PromptUserConfig;
+import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
 import jalview.io.HtmlSvgOutput;
+import jalview.io.IdentifyFile;
+import jalview.io.NewickFile;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.UserColourScheme;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
 import jalview.ws.jws2.Jws2Discoverer;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URL;
-import java.net.URLDecoder;
 import java.security.AllPermission;
 import java.security.CodeSource;
 import java.security.PermissionCollection;
@@ -62,6 +71,15 @@ import javax.swing.UIManager;
  */
 public class Jalview
 {
+  /*
+   * singleton instance of this class
+   */
+  private static Jalview instance;
+
+  private Desktop desktop;
+
+  public static AlignFrame currentAlignFrame;
+
   static
   {
     // grab all the rights we can the JVM
@@ -83,6 +101,71 @@ public class Jalview
   }
 
   /**
+   * keep track of feature fetching tasks.
+   * 
+   * @author JimP
+   * 
+   */
+  class FeatureFetcher
+  {
+    /*
+     * TODO: generalise to track all jalview events to orchestrate batch
+     * processing events.
+     */
+
+    private int queued = 0;
+
+    private int running = 0;
+
+    public FeatureFetcher()
+    {
+
+    }
+
+    public void addFetcher(final AlignFrame af,
+            final Vector<String> dasSources)
+    {
+      final long id = System.currentTimeMillis();
+      queued++;
+      final FeatureFetcher us = this;
+      new Thread(new Runnable()
+      {
+
+        @Override
+        public void run()
+        {
+          synchronized (us)
+          {
+            queued--;
+            running++;
+          }
+
+          af.setProgressBar(MessageManager
+                  .getString("status.das_features_being_retrived"), id);
+          af.featureSettings_actionPerformed(null);
+          af.featureSettings.fetchDasFeatures(dasSources, true);
+          af.setProgressBar(null, id);
+          synchronized (us)
+          {
+            running--;
+          }
+        }
+      }).start();
+    }
+
+    public synchronized boolean allFinished()
+    {
+      return queued == 0 && running == 0;
+    }
+
+  }
+
+  public static Jalview getInstance()
+  {
+    return instance;
+  }
+
+  /**
    * main class for Jalview application
    * 
    * @param args
@@ -90,6 +173,15 @@ public class Jalview
    */
   public static void main(String[] args)
   {
+    instance = new Jalview();
+    instance.doMain(args);
+  }
+
+  /**
+   * @param args
+   */
+  void doMain(String[] args)
+  {
     System.setSecurityManager(null);
     System.out.println("Java version: "
             + System.getProperty("java.version"));
@@ -163,7 +255,7 @@ public class Jalview
     try
     {
       Cache.initLogger();
-    } catch (java.lang.NoClassDefFoundError error)
+    } catch (NoClassDefFoundError error)
     {
       error.printStackTrace();
       System.out
@@ -172,7 +264,7 @@ public class Jalview
       System.exit(0);
     }
 
-    Desktop desktop = null;
+    desktop = null;
 
     try
     {
@@ -253,8 +345,9 @@ public class Jalview
     }
 
     String file = null, protocol = null, format = null, data = null;
-    jalview.io.FileLoader fileLoader = new jalview.io.FileLoader(!headless);
-    Vector getFeatures = null; // vector of das source nicknames to fetch
+    FileLoader fileLoader = new FileLoader(!headless);
+    Vector<String> getFeatures = null; // vector of das source nicknames to
+                                       // fetch
     // features from
     // loading is done.
     String groovyscript = null; // script to execute after all loading is
@@ -268,8 +361,8 @@ public class Jalview
       System.out.println("No files to open!");
       System.exit(1);
     }
-    String vamsasImport = aparser.getValue("vdoc"), vamsasSession = aparser
-            .getValue("vsess");
+    String vamsasImport = aparser.getValue("vdoc");
+    String vamsasSession = aparser.getValue("vsess");
     if (vamsasImport != null || vamsasSession != null)
     {
       if (desktop == null || headless)
@@ -284,13 +377,13 @@ public class Jalview
       {
         try
         {
-          String viprotocol = jalview.io.AppletFormatAdapter
+          String viprotocol = AppletFormatAdapter
                   .checkProtocol(vamsasImport);
           if (viprotocol == jalview.io.FormatAdapter.FILE)
           {
             inSession = desktop.vamsasImport(new File(vamsasImport));
           }
-          else if (viprotocol == jalview.io.FormatAdapter.URL)
+          else if (viprotocol == FormatAdapter.URL)
           {
             inSession = desktop.vamsasImport(new URL(vamsasImport));
           }
@@ -367,7 +460,7 @@ public class Jalview
 
       if (!file.startsWith("http://"))
       {
-        if (!(new java.io.File(file)).exists())
+        if (!(new File(file)).exists())
         {
           System.out.println("Can't find " + file);
           if (headless)
@@ -377,9 +470,9 @@ public class Jalview
         }
       }
 
-      protocol = jalview.io.AppletFormatAdapter.checkProtocol(file);
+      protocol = AppletFormatAdapter.checkProtocol(file);
 
-      format = new jalview.io.IdentifyFile().identify(file, protocol);
+      format = new IdentifyFile().identify(file, protocol);
 
       AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
               format);
@@ -389,19 +482,18 @@ public class Jalview
       }
       else
       {
-        Desktop.setCurrentAlignFrame(af);
+        setCurrentAlignFrame(af);
         data = aparser.getValue("colour", true);
         if (data != null)
         {
           data.replaceAll("%20", " ");
 
-          jalview.schemes.ColourSchemeI cs = jalview.schemes.ColourSchemeProperty
-                  .getColour(af.getViewport().getAlignment(), data);
+          ColourSchemeI cs = ColourSchemeProperty.getColour(af
+                  .getViewport().getAlignment(), data);
 
           if (cs == null)
           {
-            jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
-                    "white");
+            UserColourScheme ucs = new UserColourScheme("white");
             ucs.parseAppletParameter(data);
             cs = ucs;
           }
@@ -418,7 +510,7 @@ public class Jalview
         if (data != null)
         {
           af.parseFeaturesFile(data,
-                  jalview.io.AppletFormatAdapter.checkProtocol(data));
+                  AppletFormatAdapter.checkProtocol(data));
           // System.out.println("Added " + data);
           System.out.println("CMD groups[-" + data
                   + "]  executed successfully!");
@@ -427,7 +519,7 @@ public class Jalview
         if (data != null)
         {
           af.parseFeaturesFile(data,
-                  jalview.io.AppletFormatAdapter.checkProtocol(data));
+                  AppletFormatAdapter.checkProtocol(data));
           // System.out.println("Added " + data);
           System.out.println("CMD [-features " + data
                   + "]  executed successfully!");
@@ -475,8 +567,8 @@ public class Jalview
           {
             System.out.println("CMD [-tree " + data
                     + "] executed successfully!");
-            fin = new jalview.io.NewickFile(data,
-                    jalview.io.AppletFormatAdapter.checkProtocol(data));
+            fin = new NewickFile(data,
+                    AppletFormatAdapter.checkProtocol(data));
             if (fin != null)
             {
               af.getViewport().setCurrentTree(
@@ -517,7 +609,7 @@ public class Jalview
           // Execute the groovy script after we've done all the rendering stuff
           // and before any images or figures are generated.
           System.out.println("Executing script " + groovyscript);
-          executeGroovyScript(groovyscript, new Object[] { desktop, af });
+          executeGroovyScript(groovyscript, af);
           System.out.println("CMD groovy[" + groovyscript
                   + "] executed successfully!");
           groovyscript = null;
@@ -530,14 +622,14 @@ public class Jalview
 
           if (format.equalsIgnoreCase("png"))
           {
-            af.createPNG(new java.io.File(file));
-            imageName = (new java.io.File(file)).getName();
+            af.createPNG(new File(file));
+            imageName = (new File(file)).getName();
             System.out.println("Creating PNG image: " + file);
             continue;
           }
           else if (format.equalsIgnoreCase("svg"))
           {
-            File imageFile = new java.io.File(file);
+            File imageFile = new File(file);
             imageName = imageFile.getName();
             af.createSVG(imageFile);
             System.out.println("Creating SVG image: " + file);
@@ -545,21 +637,21 @@ public class Jalview
           }
           else if (format.equalsIgnoreCase("html"))
           {
-            File imageFile = new java.io.File(file);
+            File imageFile = new File(file);
             imageName = imageFile.getName();
-            new HtmlSvgOutput(new java.io.File(file), af.alignPanel);
+            new HtmlSvgOutput(new File(file), af.alignPanel);
             System.out.println("Creating HTML image: " + file);
             continue;
           }
           else if (format.equalsIgnoreCase("imgMap"))
           {
-            af.createImageMap(new java.io.File(file), imageName);
+            af.createImageMap(new File(file), imageName);
             System.out.println("Creating image map: " + file);
             continue;
           }
           else if (format.equalsIgnoreCase("eps"))
           {
-            File outputFile = new java.io.File(file);
+            File outputFile = new File(file);
             System.out.println("Creating EPS file: "
                     + outputFile.getAbsolutePath());
             af.createEPS(outputFile);
@@ -619,7 +711,7 @@ public class Jalview
       }
       else
       {
-        format = new jalview.io.IdentifyFile().identify(file, protocol);
+        format = new IdentifyFile().identify(file, protocol);
       }
 
       startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
@@ -641,11 +733,10 @@ public class Jalview
     // Once all other stuff is done, execute any groovy scripts (in order)
     if (groovyscript != null)
     {
-      if (jalview.bin.Cache.groovyJarsPresent())
+      if (Cache.groovyJarsPresent())
       {
         System.out.println("Executing script " + groovyscript);
-        executeGroovyScript(groovyscript, new Object[] { desktop,
-            startUpAlframe });
+        executeGroovyScript(groovyscript, startUpAlframe);
       }
       else
       {
@@ -712,8 +803,8 @@ public class Jalview
     /**
      * start a User Config prompt asking if we can log usage statistics.
      */
-    jalview.gui.PromptUserConfig prompter = new jalview.gui.PromptUserConfig(
-            desktop.desktop,
+    PromptUserConfig prompter = new PromptUserConfig(
+            Desktop.desktop,
             "USAGESTATS",
             "Jalview Usage Statistics",
             "Do you want to help make Jalview better by enabling "
@@ -749,14 +840,8 @@ public class Jalview
    *          the Jalview Desktop object passed in to the groovy binding as the
    *          'Jalview' object.
    */
-  private static void executeGroovyScript(String groovyscript,
-          Object[] jalviewContext)
+  private void executeGroovyScript(String groovyscript, AlignFrame af)
   {
-    if (jalviewContext == null)
-    {
-      System.err
-              .println("Sorry. Groovy support is currently only available when running with the Jalview GUI enabled.");
-    }
     /**
      * for scripts contained in files
      */
@@ -773,8 +858,8 @@ public class Jalview
         tfile = File.createTempFile("jalview", "groovy");
         PrintWriter outfile = new PrintWriter(new OutputStreamWriter(
                 new FileOutputStream(tfile)));
-        BufferedReader br = new BufferedReader(
-                new java.io.InputStreamReader(System.in));
+        BufferedReader br = new BufferedReader(new InputStreamReader(
+                System.in));
         String line = null;
         while ((line = br.readLine()) != null)
         {
@@ -838,75 +923,23 @@ public class Jalview
         }
       }
     }
-    boolean success = false;
     try
     {
-      /*
-       * The following code performs the GroovyScriptEngine invocation using
-       * reflection, and is equivalent to this fragment from the embedding
-       * groovy documentation on the groovy site: <code> import
-       * groovy.lang.Binding; import groovy.util.GroovyScriptEngine;
-       * 
-       * String[] roots = new String[] { "/my/groovy/script/path" };
-       * GroovyScriptEngine gse = new GroovyScriptEngine(roots); Binding binding
-       * = new Binding(); binding.setVariable("input", "world");
-       * gse.run("hello.groovy", binding); </code>
-       */
-      Class<?>[] bspec;
-      Object[] binding;
-      int blen = ((jalviewContext[0] == null) ? 0 : 1)
-              + ((jalviewContext[1] == null) ? 0 : 1);
-      String cnames[] = new String[] { "Jalview", "currentAlFrame" };
-      bspec = new Class[blen * 2];
-      binding = new Object[blen * 2];
-      blen = 0;
-      ClassLoader cl = null;
       Map<String, Object> vbinding = new HashMap<String, Object>();
-      for (int jc = 0; jc < jalviewContext.length; jc++)
+      vbinding.put("Jalview", this);
+      if (af != null)
       {
-        if (jalviewContext[jc] != null)
-        {
-          if (cl == null)
-          {
-            cl = jalviewContext[jc].getClass().getClassLoader();
-          }
-          bspec[blen * 2] = String.class;
-          bspec[blen * 2 + 1] = Object.class;
-          binding[blen * 2] = cnames[jc];
-          binding[blen * 2 + 1] = jalviewContext[jc];
-          vbinding.put(cnames[jc], jalviewContext[jc]);
-          blen++;
-        }
+        vbinding.put("currentAlFrame", af);
       }
-      Class<?> gbindingc = cl.loadClass("groovy.lang.Binding");
-      Constructor<?> gbcons;
-      Object gbinding;
-      try
-      {
-        gbcons = gbindingc.getConstructor(Map.class);
-        gbinding = gbcons.newInstance(vbinding);
-      } catch (NoSuchMethodException x)
+      Binding gbinding = new Binding(vbinding);
+      GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
+      gse.run(sfile.toString(), gbinding);
+      if ("STDIN".equals(groovyscript))
       {
-        // old style binding config - using series of string/object values to
-        // setVariable.
-        gbcons = gbindingc.getConstructor();
-        gbinding = gbcons.newInstance();
-        java.lang.reflect.Method setvar = gbindingc.getMethod(
-                "setVariable", bspec);
-        setvar.invoke(gbinding, binding);
+        // delete temp file that we made -
+        // only if it was successfully executed
+        tfile.delete();
       }
-
-      Class<?> gsec = cl.loadClass("groovy.util.GroovyScriptEngine");
-      Constructor<?> gseccons = gsec
-              .getConstructor(new Class[] { URL[].class }); // String[].class
-                                                            // });
-      Object gse = gseccons
-              .newInstance(new Object[] { new URL[] { sfile } }); // .toString()
-                                                                  // } });
-      java.lang.reflect.Method run = gsec.getMethod("run", new Class[] {
-          String.class, gbindingc });
-      run.invoke(gse, new Object[] { sfile.toString(), gbinding });
-      success = true;
     } catch (Exception e)
     {
       System.err.println("Exception Whilst trying to execute file " + sfile
@@ -914,12 +947,6 @@ public class Jalview
       e.printStackTrace(System.err);
 
     }
-    if (success && groovyscript.equals("STDIN"))
-    {
-      // delete temp file that we made - but only if it was successfully
-      // executed
-      tfile.delete();
-    }
   }
 
   /**
@@ -927,16 +954,15 @@ public class Jalview
    * 
    * @return vector of DAS source nicknames to retrieve from
    */
-  private static Vector checkDasArguments(ArgsParser aparser)
+  private static Vector<String> checkDasArguments(ArgsParser aparser)
   {
-    Vector source = null;
+    Vector<String> source = null;
     String data;
     String locsources = Cache.getProperty(Cache.DAS_LOCAL_SOURCE);
     while ((data = aparser.getValue("dasserver", true)) != null)
     {
       String nickname = null;
       String url = null;
-      boolean seq = false, feat = true;
       int pos = data.indexOf('=');
       // determine capabilities
       if (pos > 0)
@@ -966,7 +992,7 @@ public class Jalview
                         + nickname + "|" + url);
         if (source == null)
         {
-          source = new Vector();
+          source = new Vector<String>();
         }
         source.addElement(nickname);
       }
@@ -984,7 +1010,7 @@ public class Jalview
       System.out.println("adding source '" + data + "'");
       if (source == null)
       {
-        source = new Vector();
+        source = new Vector<String>();
       }
       source.addElement(data);
     }
@@ -996,7 +1022,8 @@ public class Jalview
    * 
    * @param dasSources
    */
-  private static FeatureFetcher startFeatureFetching(final Vector dasSources)
+  private FeatureFetcher startFeatureFetching(
+          final Vector<String> dasSources)
   {
     FeatureFetcher ff = new FeatureFetcher();
     AlignFrame afs[] = Desktop.getAlignFrames();
@@ -1020,176 +1047,37 @@ public class Jalview
     }
     return false;
   }
-}
-
-/**
- * Notes: this argParser does not distinguish between parameter switches,
- * parameter values and argument text. If an argument happens to be identical to
- * a parameter, it will be taken as such (even though it didn't have a '-'
- * prefixing it).
- * 
- * @author Andrew Waterhouse and JBP documented.
- * 
- */
-
-class rnabuttonlistener implements ActionListener
-{
-  @Override
-  public void actionPerformed(ActionEvent arg0)
-  {
-    System.out.println("Good idea ! ");
-
-  }
-}
-
-class pbuttonlistener implements ActionListener
-{
-  @Override
-  public void actionPerformed(ActionEvent arg0)
-  {
-
-  }
-}
-
-class ArgsParser
-{
-  Vector vargs = null;
 
-  public ArgsParser(String[] args)
-  {
-    vargs = new Vector();
-    for (int i = 0; i < args.length; i++)
-    {
-      String arg = args[i].trim();
-      if (arg.charAt(0) == '-')
-      {
-        arg = arg.substring(1);
-      }
-      vargs.addElement(arg);
-    }
-  }
-
-  /**
-   * check for and remove first occurence of arg+parameter in arglist.
-   * 
-   * @param arg
-   * @return return the argument following the given arg if arg was in list.
-   */
-  public String getValue(String arg)
+  public AlignFrame[] getAlignFrames()
   {
-    return getValue(arg, false);
-  }
+    return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
+            : Desktop.getAlignFrames();
 
-  public String getValue(String arg, boolean utf8decode)
-  {
-    int index = vargs.indexOf(arg);
-    String dc = null, ret = null;
-    if (index != -1)
-    {
-      ret = vargs.elementAt(index + 1).toString();
-      vargs.removeElementAt(index);
-      vargs.removeElementAt(index);
-      if (utf8decode && ret != null)
-      {
-        try
-        {
-          dc = URLDecoder.decode(ret, "UTF-8");
-          ret = dc;
-        } catch (Exception e)
-        {
-          // TODO: log failure to decode
-        }
-      }
-    }
-    return ret;
   }
 
   /**
-   * check for and remove first occurence of arg in arglist.
-   * 
-   * @param arg
-   * @return true if arg was present in argslist.
+   * Quit method delegates to Desktop.quit - unless running in headless mode
+   * when it just ends the JVM
    */
-  public boolean contains(String arg)
+  public void quit()
   {
-    if (vargs.contains(arg))
+    if (desktop != null)
     {
-      vargs.removeElement(arg);
-      return true;
+      desktop.quit();
     }
     else
     {
-      return false;
+      System.exit(0);
     }
   }
 
-  public String nextValue()
+  public static AlignFrame getCurrentAlignFrame()
   {
-    return vargs.remove(0).toString();
+    return Jalview.currentAlignFrame;
   }
 
-  public int getSize()
+  public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
   {
-    return vargs.size();
+    Jalview.currentAlignFrame = currentAlignFrame;
   }
-
-}
-
-/**
- * keep track of feature fetching tasks.
- * 
- * @author JimP
- * 
- */
-class FeatureFetcher
-{
-  /*
-   * TODO: generalise to track all jalview events to orchestrate batch
-   * processing events.
-   */
-
-  private int queued = 0;
-
-  private int running = 0;
-
-  public FeatureFetcher()
-  {
-
-  }
-
-  public void addFetcher(final AlignFrame af, final Vector dasSources)
-  {
-    final long id = System.currentTimeMillis();
-    queued++;
-    final FeatureFetcher us = this;
-    new Thread(new Runnable()
-    {
-
-      @Override
-      public void run()
-      {
-        synchronized (us)
-        {
-          queued--;
-          running++;
-        }
-
-        af.setProgressBar(MessageManager
-                .getString("status.das_features_being_retrived"), id);
-        af.featureSettings_actionPerformed(null);
-        af.featureSettings.fetchDasFeatures(dasSources, true);
-        af.setProgressBar(null, id);
-        synchronized (us)
-        {
-          running--;
-        }
-      }
-    }).start();
-  }
-
-  public synchronized boolean allFinished()
-  {
-    return queued == 0 && running == 0;
-  }
-
 }
index dcc5f26..db4c858 100755 (executable)
@@ -254,6 +254,12 @@ public class HiddenSequences
     return alignmentIndex;
   }
 
+  /**
+   * makes a copy of the alignment with hidden sequences included. Using the
+   * copy for anything other than simple output is not recommended. Note - this
+   * method DOES NOT USE THE AlignmentI COPY CONSTRUCTOR!
+   * @return
+   */
   public AlignmentI getFullAlignment()
   {
     int isize = hiddenSequences.length;
@@ -277,6 +283,7 @@ public class HiddenSequences
     fAlignmt.alignmentProperties = alignment.getProperties();
     fAlignmt.groups = alignment.getGroups();
     fAlignmt.hasRNAStructure = alignment.hasRNAStructure();
+    fAlignmt.setSeqrep(alignment.getSeqrep());
 
     return fAlignmt;
   }
index 0e8fa17..d403d6e 100755 (executable)
@@ -894,6 +894,7 @@ public class SequenceGroup implements AnnotatedCollectionI
   /**
    * @return the representative sequence for this group
    */
+  @Override
   public SequenceI getSeqrep()
   {
     return seqrep;
@@ -906,6 +907,7 @@ public class SequenceGroup implements AnnotatedCollectionI
    * @param seqrep
    *          the seqrep to set (null means no sequence representative)
    */
+  @Override
   public void setSeqrep(SequenceI seqrep)
   {
     this.seqrep = seqrep;
@@ -915,6 +917,7 @@ public class SequenceGroup implements AnnotatedCollectionI
    * 
    * @return true if group has a sequence representative
    */
+  @Override
   public boolean hasSeqrep()
   {
     return seqrep != null;
@@ -1036,7 +1039,8 @@ public class SequenceGroup implements AnnotatedCollectionI
 
   /**
    * 
-   * @return automatically calculated consensus row
+   * @return automatically calculated consensus row note: the row is a stub if a
+   *         consensus calculation has not yet been performed on the group
    */
   public AlignmentAnnotation getConsensus()
   {
index 43581da..5409d5b 100644 (file)
@@ -198,6 +198,7 @@ public class EmblEntry
     retrievedref.setMap(new Mapping(null, new int[] { 1, dna.getLength() },
             new int[] { 1, dna.getLength() }, 1, 1));
 
+
     /*
      * transform EMBL Database refs to canonical form
      */
@@ -282,13 +283,13 @@ public class EmblEntry
         }
         else if (qname.equals("protein_id"))
         {
-          prid = q.getValues()[0];
+          prid = q.getValues()[0].trim();
         }
         else if (qname.equals("codon_start"))
         {
           try
           {
-            codonStart = Integer.parseInt(q.getValues()[0]);
+            codonStart = Integer.parseInt(q.getValues()[0].trim());
           } catch (NumberFormatException e)
           {
             System.err.println("Invalid codon_start in XML for "
@@ -298,7 +299,7 @@ public class EmblEntry
         else if (qname.equals("product"))
         {
           // sometimes name is returned e.g. for V00488
-          prname = q.getValues()[0];
+          prname = q.getValues()[0].trim();
         }
         else
         {
index 4dd1bba..b4d2783 100644 (file)
@@ -8,7 +8,7 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyI;
-import jalview.schemes.FeatureColourAdapter;
+import jalview.schemes.FeatureColour;
 import jalview.schemes.FeatureSettingsAdapter;
 import jalview.util.MapList;
 
@@ -536,7 +536,7 @@ public class EnsemblGene extends EnsemblSeqProxy
       {
         if (so.isA(type, SequenceOntologyI.EXON))
         {
-          return new FeatureColourAdapter()
+          return new FeatureColour()
           {
             @Override
             public boolean isColourByLabel()
@@ -547,7 +547,7 @@ public class EnsemblGene extends EnsemblSeqProxy
         }
         if (so.isA(type, SequenceOntologyI.SEQUENCE_VARIANT))
         {
-          return new FeatureColourAdapter()
+          return new FeatureColour()
           {
 
             @Override
index 3f0847b..2133f2b 100644 (file)
@@ -176,6 +176,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     // and shut down jmol
     viewer.evalStringQuiet("zap");
     viewer.setJmolStatusListener(null);
+    viewer.dispose();
     lastCommand = null;
     viewer = null;
     releaseUIResources();
index 5dba850..18ee912 100644 (file)
@@ -473,7 +473,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       @Override
       public void focusGained(FocusEvent e)
       {
-        Desktop.setCurrentAlignFrame(AlignFrame.this);
+        Jalview.setCurrentAlignFrame(AlignFrame.this);
       }
     });
 
@@ -6078,7 +6078,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void runGroovy_actionPerformed()
   {
-    Desktop.setCurrentAlignFrame(this);
+    Jalview.setCurrentAlignFrame(this);
     groovy.ui.Console console = Desktop.getGroovyConsole();
     if (console != null)
     {
index d688ddd..469e495 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.gui;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.SequenceI;
 import jalview.io.AnnotationFile;
@@ -155,18 +156,25 @@ public class AnnotationExporter extends JPanel
             .getString("label.no_features_on_alignment");
     if (features)
     {
+      Map<String, FeatureColourI> displayedFeatureColours = ap
+              .getFeatureRenderer().getDisplayedFeatureCols();
       FeaturesFile formatter = new FeaturesFile();
       SequenceI[] sequences = ap.av.getAlignment().getSequencesArray();
-      Map<String, Object> featureColours = ap.getFeatureRenderer()
+      Map<String, FeatureColourI> featureColours = ap.getFeatureRenderer()
               .getDisplayedFeatureCols();
       boolean includeNonPositional = ap.av.isShowNPFeats();
       if (GFFFormat.isSelected())
       {
+        text = new FeaturesFile().printGffFormat(ap.av.getAlignment()
+                .getDataset().getSequencesArray(), displayedFeatureColours,
+                true, ap.av.isShowNPFeats());
         text = formatter.printGffFormat(sequences, featureColours, true,
                 includeNonPositional);
       }
       else
       {
+        text = new FeaturesFile().printJalviewFormat(ap.av.getAlignment()
+                .getDataset().getSequencesArray(), displayedFeatureColours, true, ap.av.isShowNPFeats()); // ap.av.featuresDisplayed);
         text = formatter.printJalviewFormat(sequences, featureColours,
                 true, includeNonPositional);
       }
index 698b164..d54e553 100644 (file)
@@ -61,6 +61,7 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
+import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
@@ -82,6 +83,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Semaphore;
 
+import javax.swing.AbstractAction;
 import javax.swing.DefaultDesktopManager;
 import javax.swing.DesktopManager;
 import javax.swing.JButton;
@@ -96,6 +98,7 @@ import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
 import javax.swing.JProgressBar;
+import javax.swing.KeyStroke;
 import javax.swing.SwingUtilities;
 import javax.swing.event.HyperlinkEvent;
 import javax.swing.event.HyperlinkEvent.EventType;
@@ -169,8 +172,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
   static final int yOffset = 30;
 
-  private static AlignFrame currentAlignFrame;
-
   public static jalview.ws.jws1.Discoverer discoverer;
 
   public static Object[] jalviewClipboard;
@@ -1180,6 +1181,13 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       dialogExecutor.shutdownNow();
     }
     closeAll_actionPerformed(null);
+
+    if (groovyConsole != null)
+    {
+      // suppress a possible repeat prompt to save script
+      groovyConsole.setDirty(false);
+      groovyConsole.exit();
+    }
     System.exit(0);
   }
 
@@ -2371,7 +2379,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     if (Jalview.isHeadlessMode())
     {
       // Desktop.desktop is null in headless mode
-      return new AlignFrame[] { currentAlignFrame };
+      return new AlignFrame[] { Jalview.currentAlignFrame };
     }
 
     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
@@ -2467,50 +2475,79 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    */
   void openGroovyConsole()
   {
-    groovyConsole = new groovy.ui.Console();
+    if (groovyConsole == null)
+    {
+      groovyConsole = new groovy.ui.Console();
+      groovyConsole.setVariable("Jalview", this);
+      groovyConsole.run();
 
-    /*
-     * bind groovy variable 'Jalview' to the Desktop object
-     */
-    groovyConsole.setVariable("Jalview", this);
+      /*
+       * We allow only one console at a time, so that AlignFrame menu option
+       * 'Calculate | Run Groovy script' is unambiguous.
+       * Disable 'Groovy Console', and enable 'Run script', when the console is 
+       * opened, and the reverse when it is closed
+       */
+      Window window = (Window) groovyConsole.getFrame();
+      window.addWindowListener(new WindowAdapter()
+      {
+        @Override
+        public void windowClosed(WindowEvent e)
+        {
+          /*
+           * rebind CMD-Q from Groovy Console to Jalview Quit
+           */
+          addQuitHandler();
+          enableExecuteGroovy(false);
+        }
+      });
+    }
 
     /*
-     * start the console
+     * show Groovy console window (after close and reopen)
      */
-    groovyConsole.run();
+    ((Window) groovyConsole.getFrame()).setVisible(true);
 
     /*
-     * Allow only one console at a time, so that the AlignFrame menu option
-     * 'Calculate | Run Groovy script' is unambiguous.
-     * Disable 'new console', and enable 'Run script', when the console is 
-     * opened, and the reverse when it is closed
+     * if we got this far, enable 'Run Groovy' in AlignFrame menus
+     * and disable opening a second console
      */
-    Window window = (Window) groovyConsole.getFrame();
-    window.addWindowListener(new WindowAdapter()
+    enableExecuteGroovy(true);
+  }
+
+  /**
+   * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
+   * binding when opened
+   */
+  protected void addQuitHandler()
+  {
+    getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+            KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
+                    .getDefaultToolkit().getMenuShortcutKeyMask()),
+            "Quit");
+    getRootPane().getActionMap().put("Quit", new AbstractAction()
     {
       @Override
-      public void windowClosed(WindowEvent e)
+      public void actionPerformed(ActionEvent e)
       {
-        groovyShell.setEnabled(true);
-        enableExecuteGroovy(false);
+        quit();
       }
     });
-
-    /*
-     * if we got this far, enable 'Run Groovy' in AlignFrame menus
-     * and disable opening a second console
-     */
-    groovyShell.setEnabled(false);
-    enableExecuteGroovy(true);
   }
 
   /**
    * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
    * 
    * @param enabled
+   *          true if Groovy console is open
    */
   public void enableExecuteGroovy(boolean enabled)
   {
+    /*
+     * disable opening a second Groovy console
+     * (or re-enable when the console is closed)
+     */
+    groovyShell.setEnabled(!enabled);
+
     AlignFrame[] alignFrames = getAlignFrames();
     if (alignFrames != null)
     {
@@ -3134,17 +3171,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
      * The dust settles...give focus to the tab we did this from.
      */
     myTopFrame.setDisplayedView(myTopFrame.alignPanel);
-
-  }
-
-  public static AlignFrame getCurrentAlignFrame()
-  {
-    return currentAlignFrame;
-  }
-
-  public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
-  {
-    Desktop.currentAlignFrame = currentAlignFrame;
   }
 
   public static groovy.ui.Console getGroovyConsole()
index 064d58b..79217ea 100644 (file)
@@ -20,9 +20,9 @@
  */
 package jalview.gui;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.GraphLine;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -33,7 +33,6 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.util.Hashtable;
 
 import javax.swing.BorderFactory;
 import javax.swing.JCheckBox;
@@ -52,16 +51,16 @@ public class FeatureColourChooser extends JalviewDialog
   // FeatureSettings fs;
   FeatureRenderer fr;
 
-  private GraduatedColor cs;
+  private FeatureColourI cs;
 
-  private Object oldcs;
+  private FeatureColourI oldcs;
 
   /**
    * 
    * @return the last colour setting selected by user - either oldcs (which may
    *         be a java.awt.Color) or the new GraduatedColor
    */
-  public Object getLastColour()
+  public FeatureColourI getLastColour()
   {
     if (cs == null)
     {
@@ -70,8 +69,6 @@ public class FeatureColourChooser extends JalviewDialog
     return cs;
   }
 
-  Hashtable oldgroupColours;
-
   AlignmentPanel ap;
 
   boolean adjusting = false;
@@ -127,7 +124,7 @@ public class FeatureColourChooser extends JalviewDialog
       }
     });
 
-    float mm[] = ((float[][]) fr.getMinMax().get(type))[0];
+    float mm[] = fr.getMinMax().get(type)[0];
     min = mm[0];
     max = mm[1];
 
@@ -139,32 +136,32 @@ public class FeatureColourChooser extends JalviewDialog
     scaleFactor = (max == min) ? 1f : 100f / (max - min);
 
     oldcs = fr.getFeatureColours().get(type);
-    if (oldcs instanceof GraduatedColor)
+    if (!oldcs.isSimpleColour())
     {
-      if (((GraduatedColor) oldcs).isAutoScale())
+      if (oldcs.isAutoScaled())
       {
         // update the scale
-        cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
+        cs = new FeatureColour((FeatureColour) oldcs, min, max);
       }
       else
       {
-        cs = new GraduatedColor((GraduatedColor) oldcs);
+        cs = new FeatureColour((FeatureColour) oldcs);
       }
     }
     else
     {
       // promote original color to a graduated color
-      Color bl = Color.black;
-      if (oldcs instanceof Color)
+      Color bl = oldcs.getColour();
+      if (bl == null)
       {
-        bl = (Color) oldcs;
+        bl = Color.BLACK;
       }
       // original colour becomes the maximum colour
-      cs = new GraduatedColor(Color.white, bl, mm[0], mm[1]);
+      cs = new FeatureColour(Color.white, bl, mm[0], mm[1]);
       cs.setColourByLabel(false);
     }
-    minColour.setBackground(oldminColour = cs.getMinColor());
-    maxColour.setBackground(oldmaxColour = cs.getMaxColor());
+    minColour.setBackground(oldminColour = cs.getMinColour());
+    maxColour.setBackground(oldmaxColour = cs.getMaxColour());
     adjusting = true;
 
     try
@@ -174,18 +171,15 @@ public class FeatureColourChooser extends JalviewDialog
     {
     }
     // update the gui from threshold state
-    thresholdIsMin.setSelected(!cs.isAutoScale());
+    thresholdIsMin.setSelected(!cs.isAutoScaled());
     colourByLabel.setSelected(cs.isColourByLabel());
-    if (cs.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
+    if (cs.hasThreshold())
     {
       // initialise threshold slider and selector
-      threshold
-              .setSelectedIndex(cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1
-                      : 2);
+      threshold.setSelectedIndex(cs.isAboveThreshold() ? 1 : 2);
       slider.setEnabled(true);
       thresholdValue.setEnabled(true);
-      threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
-              "Threshold", Color.black);
+      threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
 
     }
 
@@ -395,50 +389,50 @@ public class FeatureColourChooser extends JalviewDialog
       return;
     }
 
-    int aboveThreshold = AnnotationColourGradient.NO_THRESHOLD;
+    boolean aboveThreshold = false;
+    boolean belowThreshold = false;
     if (threshold.getSelectedIndex() == 1)
     {
-      aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
+      aboveThreshold = true;
     }
     else if (threshold.getSelectedIndex() == 2)
     {
-      aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
+      belowThreshold = true;
     }
+    boolean hasThreshold = aboveThreshold || belowThreshold;
 
     slider.setEnabled(true);
     thresholdValue.setEnabled(true);
 
-    GraduatedColor acg;
+    FeatureColourI acg;
     if (cs.isColourByLabel())
     {
-      acg = new GraduatedColor(oldminColour, oldmaxColour, min, max);
+      acg = new FeatureColour(oldminColour, oldmaxColour, min, max);
     }
     else
     {
-      acg = new GraduatedColor(oldminColour = minColour.getBackground(),
+      acg = new FeatureColour(oldminColour = minColour.getBackground(),
               oldmaxColour = maxColour.getBackground(), min, max);
 
     }
 
-    if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
+    if (!hasThreshold)
     {
       slider.setEnabled(false);
       thresholdValue.setEnabled(false);
       thresholdValue.setText("");
       thresholdIsMin.setEnabled(false);
     }
-    else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
-            && threshline == null)
+    else if (threshline == null)
     {
       // todo visual indication of feature threshold
-      threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
-              "Threshold", Color.black);
+      threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
     }
 
-    if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+    if (hasThreshold)
     {
       adjusting = true;
-      acg.setThresh(threshline.value);
+      acg.setThreshold(threshline.value);
 
       float range = (max - min) * scaleFactor;
 
@@ -453,18 +447,18 @@ public class FeatureColourChooser extends JalviewDialog
       adjusting = false;
     }
 
-    acg.setThreshType(aboveThreshold);
-    if (thresholdIsMin.isSelected()
-            && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+    acg.setAboveThreshold(aboveThreshold);
+    acg.setBelowThreshold(belowThreshold);
+    if (thresholdIsMin.isSelected() && hasThreshold)
     {
       acg.setAutoScaled(false);
-      if (aboveThreshold == AnnotationColourGradient.ABOVE_THRESHOLD)
+      if (aboveThreshold)
       {
-        acg = new GraduatedColor(acg, threshline.value, max);
+        acg = new FeatureColour((FeatureColour) acg, threshline.value, max);
       }
       else
       {
-        acg = new GraduatedColor(acg, min, threshline.value);
+        acg = new FeatureColour((FeatureColour) acg, min, threshline.value);
       }
     }
     else
@@ -554,7 +548,7 @@ public class FeatureColourChooser extends JalviewDialog
   public void valueChanged()
   {
     threshline.value = slider.getValue() / scaleFactor;
-    cs.setThresh(threshline.value);
+    cs.setThreshold(threshline.value);
     changeColour();
     ap.paintAlignment(false);
   }
index 1cf15ac..1bf7453 100644 (file)
  */
 package jalview.gui;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.UserColourScheme;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -94,7 +96,7 @@ public class FeatureRenderer extends
 
   static String lastDescriptionAdded;
 
-  Object oldcol, fcol;
+  FeatureColourI oldcol, fcol;
 
   int featureIndex = 0;
 
@@ -126,20 +128,19 @@ public class FeatureRenderer extends
       @Override
       public void mousePressed(MouseEvent evt)
       {
-        if (fcol instanceof Color)
+        if (fcol.isSimpleColour())
         {
           Color col = JColorChooser.showDialog(Desktop.desktop,
                   MessageManager.getString("label.select_feature_colour"),
-                  ((Color) fcol));
+                  fcol.getColour());
           if (col != null)
           {
-            fcol = col;
-            updateColourButton(bigPanel, colour, col);
+            fcol = new FeatureColour(col);
+            updateColourButton(bigPanel, colour, new FeatureColour(col));
           }
         }
         else
         {
-
           if (fcc == null)
           {
             final String type = features[featureIndex].getType();
@@ -206,11 +207,11 @@ public class FeatureRenderer extends
             ap.getSeqPanel().seqCanvas.highlightSearchResults(highlight);
 
           }
-          Object col = getFeatureStyle(name.getText());
+          FeatureColourI col = getFeatureStyle(name.getText());
           if (col == null)
           {
-            col = new jalview.schemes.UserColourScheme()
-                    .createColourFromName(name.getText());
+            col = new FeatureColour(UserColourScheme
+                    .createColourFromName(name.getText()));
           }
           oldcol = fcol = col;
           updateColourButton(bigPanel, colour, col);
@@ -421,26 +422,25 @@ public class FeatureRenderer extends
    * 
    * @param bigPanel
    * @param col
-   * @param col2
+   * @param col
    */
   protected void updateColourButton(JPanel bigPanel, JLabel colour,
-          Object col2)
+          FeatureColourI col)
   {
     colour.removeAll();
     colour.setIcon(null);
     colour.setToolTipText(null);
     colour.setText("");
 
-    if (col2 instanceof Color)
+    if (col.isSimpleColour())
     {
-      colour.setBackground((Color) col2);
+      colour.setBackground(col.getColour());
     }
     else
     {
       colour.setBackground(bigPanel.getBackground());
       colour.setForeground(Color.black);
-      FeatureSettings.renderGraduatedColor(colour, (GraduatedColor) col2);
-      // colour.setForeground(colour.getBackground());
+      FeatureSettings.renderGraduatedColor(colour, col);
     }
   }
 
index 09204d1..bfc14b5 100644 (file)
  */
 package jalview.gui;
 
+import jalview.api.FeatureColourI;
 import jalview.api.FeatureSettingsControllerI;
 import jalview.bin.Cache;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.Help.HelpId;
 import jalview.io.JalviewFileChooser;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemabinding.version2.JalviewUserColours;
+import jalview.schemes.FeatureColour;
 import jalview.util.Format;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.util.QuickSort;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.ws.dbsources.das.api.jalviewSourceI;
@@ -162,8 +164,8 @@ public class FeatureSettings extends JPanel implements
 
     table.setDefaultEditor(Color.class, new ColorEditor(this));
 
-    table.setDefaultEditor(GraduatedColor.class, new ColorEditor(this));
-    table.setDefaultRenderer(GraduatedColor.class, new ColorRenderer());
+    table.setDefaultEditor(FeatureColour.class, new ColorEditor(this));
+    table.setDefaultRenderer(FeatureColour.class, new ColorRenderer());
     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 
     table.addMouseListener(new MouseAdapter()
@@ -172,7 +174,7 @@ public class FeatureSettings extends JPanel implements
       public void mousePressed(MouseEvent evt)
       {
         selectedRow = table.rowAtPoint(evt.getPoint());
-        if (evt.isPopupTrigger())
+        if (SwingUtilities.isRightMouseButton(evt))
         {
           popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
                   table.getValueAt(selectedRow, 1), fr.getMinMax(),
@@ -253,7 +255,7 @@ public class FeatureSettings extends JPanel implements
 
     frame = new JInternalFrame();
     frame.setContentPane(this);
-    if (new jalview.util.Platform().isAMac())
+    if (Platform.isAMac())
     {
       Desktop.addInternalFrame(frame,
               MessageManager.getString("label.sequence_feature_settings"),
@@ -283,6 +285,8 @@ public class FeatureSettings extends JPanel implements
           final Object typeCol, final Map<String, float[][]> minmax, int x,
           int y)
   {
+    final FeatureColourI featureColour = (FeatureColourI) typeCol;
+
     JPopupMenu men = new JPopupMenu(MessageManager.formatMessage(
             "label.settings_for_param", new String[] { type }));
     JMenuItem scr = new JMenuItem(
@@ -338,7 +342,7 @@ public class FeatureSettings extends JPanel implements
         // positional features
         final JCheckBoxMenuItem mxcol = new JCheckBoxMenuItem(
                 "Graduated Colour");
-        mxcol.setSelected(!(typeCol instanceof Color));
+        mxcol.setSelected(!featureColour.isSimpleColour());
         men.add(mxcol);
         mxcol.addActionListener(new ActionListener()
         {
@@ -349,7 +353,7 @@ public class FeatureSettings extends JPanel implements
           {
             if (e.getSource() == mxcol)
             {
-              if (typeCol instanceof Color)
+              if (featureColour.isSimpleColour())
               {
                 FeatureColourChooser fc = new FeatureColourChooser(me.fr,
                         type);
@@ -363,8 +367,7 @@ public class FeatureSettings extends JPanel implements
                         "Select new Colour", true, // modal
                         colorChooser, this, // OK button handler
                         null); // no CANCEL button handler
-                colorChooser.setColor(((GraduatedColor) typeCol)
-                        .getMaxColor());
+                colorChooser.setColor(featureColour.getMaxColour());
                 dialog.setVisible(true);
               }
             }
@@ -449,13 +452,13 @@ public class FeatureSettings extends JPanel implements
   /**
    * contains a float[3] for each feature type string. created by setTableData
    */
-  Hashtable typeWidth = null;
+  Map<String, float[]> typeWidth = null;
 
   @Override
   synchronized public void discoverAllFeatureData()
   {
-    Vector allFeatures = new Vector();
-    Vector allGroups = new Vector();
+    Vector<String> allFeatures = new Vector<String>();
+    Vector<String> allGroups = new Vector<String>();
     SequenceFeature[] tmpfeatures;
     String group;
     for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++)
@@ -561,13 +564,13 @@ public class FeatureSettings extends JPanel implements
       return;
     }
     resettingTable = true;
-    typeWidth = new Hashtable();
+    typeWidth = new Hashtable<String, float[]>();
     // TODO: change avWidth calculation to 'per-sequence' average and use long
     // rather than float
     float[] avWidth = null;
     SequenceFeature[] tmpfeatures;
     String group = null, type;
-    Vector visibleChecks = new Vector();
+    Vector<String> visibleChecks = new Vector<String>();
 
     // Find out which features should be visible depending on which groups
     // are selected / deselected
@@ -608,7 +611,7 @@ public class FeatureSettings extends JPanel implements
         }
         else
         {
-          avWidth = (float[]) typeWidth.get(tmpfeatures[index].getType());
+          avWidth = typeWidth.get(tmpfeatures[index].getType());
         }
         avWidth[0]++;
         if (tmpfeatures[index].getBegin() > tmpfeatures[index].getEnd())
@@ -753,8 +756,7 @@ public class FeatureSettings extends JPanel implements
         InputStreamReader in = new InputStreamReader(new FileInputStream(
                 file), "UTF-8");
 
-        jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
-        jucs = jucs.unmarshal(in);
+        JalviewUserColours jucs = JalviewUserColours.unmarshal(in);
 
         for (int i = jucs.getColourCount() - 1; i >= 0; i--)
         {
@@ -773,7 +775,7 @@ public class FeatureSettings extends JPanel implements
               Cache.log.warn("Couldn't parse out graduated feature color.",
                       e);
             }
-            GraduatedColor gcol = new GraduatedColor(mincol, maxcol,
+            FeatureColourI gcol = new FeatureColour(mincol, maxcol,
                     newcol.getMin(), newcol.getMax());
             if (newcol.hasAutoScale())
             {
@@ -785,31 +787,28 @@ public class FeatureSettings extends JPanel implements
             }
             if (newcol.hasThreshold())
             {
-              gcol.setThresh(newcol.getThreshold());
-              gcol.setThreshType(AnnotationColourGradient.NO_THRESHOLD); // default
+              gcol.setThreshold(newcol.getThreshold());
             }
             if (newcol.getThreshType().length() > 0)
             {
               String ttyp = newcol.getThreshType();
-              if (ttyp.equalsIgnoreCase("NONE"))
-              {
-                gcol.setThreshType(AnnotationColourGradient.NO_THRESHOLD);
-              }
               if (ttyp.equalsIgnoreCase("ABOVE"))
               {
-                gcol.setThreshType(AnnotationColourGradient.ABOVE_THRESHOLD);
+                gcol.setAboveThreshold(true);
               }
               if (ttyp.equalsIgnoreCase("BELOW"))
               {
-                gcol.setThreshType(AnnotationColourGradient.BELOW_THRESHOLD);
+                gcol.setBelowThreshold(true);
               }
             }
             fr.setColour(name = newcol.getName(), gcol);
           }
           else
           {
-            fr.setColour(name = jucs.getColour(i).getName(), new Color(
-                    Integer.parseInt(jucs.getColour(i).getRGB(), 16)));
+            Color color = new Color(
+                    Integer.parseInt(jucs.getColour(i).getRGB(), 16));
+            fr.setColour(name = jucs.getColour(i).getName(),
+                    new FeatureColour(color));
           }
           fr.setOrder(name, (i == 0) ? 0 : i / jucs.getColourCount());
         }
@@ -866,38 +865,27 @@ public class FeatureSettings extends JPanel implements
         }
         QuickSort.sort(sortOrder, sortTypes);
         sortOrder = null;
-        Object fcol;
-        GraduatedColor gcol;
-        for (String featureType : sortTypes)
+        for (i = 0; i < sortTypes.length; i++)
         {
           jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
-          col.setName(featureType);
-          fcol = fr.getFeatureStyle(featureType);
-          Color colour = fcol instanceof Color ? (Color) fcol
-                  : ((GraduatedColor) fcol).getMaxColor();
-          col.setRGB(Format.getHexString(colour));
-          if (fcol instanceof GraduatedColor)
+          col.setName(sortTypes[i]);
+          FeatureColourI fcol = fr.getFeatureStyle(sortTypes[i]);
+          if (fcol.isSimpleColour())
           {
-            gcol = (GraduatedColor) fcol;
-            col.setMin(gcol.getMin());
-            col.setMax(gcol.getMax());
-            col.setMinRGB(Format.getHexString(gcol
-                    .getMinColor()));
-            col.setAutoScale(gcol.isAutoScale());
-            col.setThreshold(gcol.getThresh());
-            col.setColourByLabel(gcol.isColourByLabel());
-            switch (gcol.getThreshType())
-            {
-            case AnnotationColourGradient.NO_THRESHOLD:
-              col.setThreshType("NONE");
-              break;
-            case AnnotationColourGradient.ABOVE_THRESHOLD:
-              col.setThreshType("ABOVE");
-              break;
-            case AnnotationColourGradient.BELOW_THRESHOLD:
-              col.setThreshType("BELOW");
-              break;
-            }
+            col.setRGB(Format.getHexString(fcol.getColour()));
+          }
+          else
+          {
+            col.setRGB(Format.getHexString(fcol.getMaxColour()));
+            col.setMin(fcol.getMin());
+            col.setMax(fcol.getMax());
+            col.setMinRGB(jalview.util.Format.getHexString(fcol
+                    .getMinColour()));
+            col.setAutoScale(fcol.isAutoScaled());
+            col.setThreshold(fcol.getThreshold());
+            col.setColourByLabel(fcol.isColourByLabel());
+            col.setThreshType(fcol.isAboveThreshold() ? "ABOVE" : (fcol
+                    .isBelowThreshold() ? "BELOW" : "NONE"));
           }
           ucs.addColour(col);
         }
@@ -933,7 +921,7 @@ public class FeatureSettings extends JPanel implements
     int num = 0;
     for (int i = 0; i < data.length; i++)
     {
-      awidth = (float[]) typeWidth.get(data[i][0]);
+      awidth = typeWidth.get(data[i][0]);
       if (awidth[0] > 0)
       {
         width[i] = awidth[1] / awidth[0];// *awidth[0]*awidth[2]; - better
@@ -1256,7 +1244,8 @@ public class FeatureSettings extends JPanel implements
     fetchDAS.setEnabled(false);
     cancelDAS.setEnabled(true);
     dassourceBrowser.setGuiEnabled(false);
-    Vector selectedSources = dassourceBrowser.getSelectedSources();
+    Vector<jalviewSourceI> selectedSources = dassourceBrowser
+            .getSelectedSources();
     doDasFeatureFetch(selectedSources, true, true);
   }
 
@@ -1315,7 +1304,7 @@ public class FeatureSettings extends JPanel implements
    *          Vector of Strings to resolve to DAS source nicknames.
    * @return sources that are present in source list.
    */
-  public List<jalviewSourceI> resolveSourceNicknames(Vector sources)
+  public List<jalviewSourceI> resolveSourceNicknames(Vector<String> sources)
   {
     return dassourceBrowser.sourceRegistry.resolveSourceNicknames(sources);
   }
@@ -1340,7 +1329,7 @@ public class FeatureSettings extends JPanel implements
    *          if true then runs in same thread, otherwise passes to the Swing
    *          executor
    */
-  public void fetchDasFeatures(Vector sources, boolean block)
+  public void fetchDasFeatures(Vector<String> sources, boolean block)
   {
     initDasSources();
     List<jalviewSourceI> resolved = dassourceBrowser.sourceRegistry
@@ -1506,10 +1495,11 @@ public class FeatureSettings extends JPanel implements
     }
 
     @Override
-    public Component getTableCellRendererComponent(JTable table,
+    public Component getTableCellRendererComponent(JTable tbl,
             Object color, boolean isSelected, boolean hasFocus, int row,
             int column)
     {
+      FeatureColourI cellColour = (FeatureColourI) color;
       // JLabel comp = new JLabel();
       // comp.
       setOpaque(true);
@@ -1517,11 +1507,11 @@ public class FeatureSettings extends JPanel implements
       // setBounds(getBounds());
       Color newColor;
       setToolTipText(baseTT);
-      setBackground(table.getBackground());
-      if (color instanceof GraduatedColor)
+      setBackground(tbl.getBackground());
+      if (!cellColour.isSimpleColour())
       {
-        Rectangle cr = table.getCellRect(row, column, false);
-        FeatureSettings.renderGraduatedColor(this, (GraduatedColor) color,
+        Rectangle cr = tbl.getCellRect(row, column, false);
+        FeatureSettings.renderGraduatedColor(this, cellColour,
                 (int) cr.getWidth(), (int) cr.getHeight());
 
       }
@@ -1529,20 +1519,16 @@ public class FeatureSettings extends JPanel implements
       {
         this.setText("");
         this.setIcon(null);
-        newColor = (Color) color;
-        // comp.
+        newColor = cellColour.getColour();
         setBackground(newColor);
-        // comp.setToolTipText("RGB value: " + newColor.getRed() + ", "
-        // + newColor.getGreen() + ", " + newColor.getBlue());
       }
       if (isSelected)
       {
         if (selectedBorder == null)
         {
           selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
-                  table.getSelectionBackground());
+                  tbl.getSelectionBackground());
         }
-        // comp.
         setBorder(selectedBorder);
       }
       else
@@ -1550,9 +1536,8 @@ public class FeatureSettings extends JPanel implements
         if (unselectedBorder == null)
         {
           unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
-                  table.getBackground());
+                  tbl.getBackground());
         }
-        // comp.
         setBorder(unselectedBorder);
       }
 
@@ -1566,7 +1551,7 @@ public class FeatureSettings extends JPanel implements
    * @param comp
    * @param gcol
    */
-  public static void renderGraduatedColor(JLabel comp, GraduatedColor gcol)
+  public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol)
   {
     int w = comp.getWidth(), h = comp.getHeight();
     if (w < 20)
@@ -1582,23 +1567,23 @@ public class FeatureSettings extends JPanel implements
     renderGraduatedColor(comp, gcol, w, h);
   }
 
-  public static void renderGraduatedColor(JLabel comp, GraduatedColor gcol,
+  public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol,
           int w, int h)
   {
     boolean thr = false;
     String tt = "";
     String tx = "";
-    if (gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD)
+    if (gcol.isAboveThreshold())
     {
       thr = true;
       tx += ">";
-      tt += "Thresholded (Above " + gcol.getThresh() + ") ";
+      tt += "Thresholded (Above " + gcol.getThreshold() + ") ";
     }
-    if (gcol.getThreshType() == AnnotationColourGradient.BELOW_THRESHOLD)
+    if (gcol.isBelowThreshold())
     {
       thr = true;
       tx += "<";
-      tt += "Thresholded (Below " + gcol.getThresh() + ") ";
+      tt += "Thresholded (Below " + gcol.getThreshold() + ") ";
     }
     if (gcol.isColourByLabel())
     {
@@ -1612,7 +1597,7 @@ public class FeatureSettings extends JPanel implements
     }
     else
     {
-      Color newColor = gcol.getMaxColor();
+      Color newColor = gcol.getMaxColour();
       comp.setBackground(newColor);
       // System.err.println("Width is " + w / 2);
       Icon ficon = new FeatureIcon(gcol, comp.getBackground(), w, h, thr);
@@ -1640,7 +1625,7 @@ public class FeatureSettings extends JPanel implements
 
 class FeatureIcon implements Icon
 {
-  GraduatedColor gcol;
+  FeatureColourI gcol;
 
   Color backg;
 
@@ -1652,7 +1637,7 @@ class FeatureIcon implements Icon
 
   Color mpcolour = Color.white;
 
-  FeatureIcon(GraduatedColor gfc, Color bg, int w, int h, boolean mspace)
+  FeatureIcon(FeatureColourI gfc, Color bg, int w, int h, boolean mspace)
   {
     gcol = gfc;
     backg = bg;
@@ -1692,7 +1677,7 @@ class FeatureIcon implements Icon
       g.setColor(backg);
       g.fillRect(0, 0, width, height);
       // need an icon here.
-      g.setColor(gcol.getMaxColor());
+      g.setColor(gcol.getMaxColour());
 
       g.setFont(new Font("Verdana", Font.PLAIN, 9));
 
@@ -1706,7 +1691,7 @@ class FeatureIcon implements Icon
     }
     else
     {
-      Color minCol = gcol.getMinColor();
+      Color minCol = gcol.getMinColour();
       g.setColor(minCol);
       g.fillRect(0, 0, s1, height);
       if (midspace)
@@ -1714,7 +1699,7 @@ class FeatureIcon implements Icon
         g.setColor(Color.white);
         g.fillRect(s1, 0, e1 - s1, height);
       }
-      g.setColor(gcol.getMaxColor());
+      g.setColor(gcol.getMaxColour());
       g.fillRect(0, e1, width - e1, height);
     }
   }
@@ -1725,14 +1710,12 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor,
 {
   FeatureSettings me;
 
-  GraduatedColor currentGColor;
+  FeatureColourI currentColor;
 
   FeatureColourChooser chooser;
 
   String type;
 
-  Color currentColor;
-
   JButton button;
 
   JColorChooser colorChooser;
@@ -1772,11 +1755,11 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor,
     {
       // The user has clicked the cell, so
       // bring up the dialog.
-      if (currentColor != null)
+      if (currentColor.isSimpleColour())
       {
         // bring up simple color chooser
-        button.setBackground(currentColor);
-        colorChooser.setColor(currentColor);
+        button.setBackground(currentColor.getColour());
+        colorChooser.setColor(currentColor.getColour());
         dialog.setVisible(true);
       }
       else
@@ -1793,15 +1776,13 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor,
     }
     else
     { // User pressed dialog's "OK" button.
-      if (currentColor != null)
+      if (currentColor.isSimpleColour())
       {
-        currentColor = colorChooser.getColor();
+        currentColor = new FeatureColour(colorChooser.getColor());
       }
       else
       {
-        // class cast exceptions may be raised if the chooser created on a
-        // non-graduated color
-        currentGColor = (GraduatedColor) chooser.getLastColour();
+        currentColor = chooser.getLastColour();
       }
       me.table.setValueAt(getCellEditorValue(), selectedRow, 1);
       fireEditingStopped();
@@ -1813,10 +1794,6 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor,
   @Override
   public Object getCellEditorValue()
   {
-    if (currentColor == null)
-    {
-      return currentGColor;
-    }
     return currentColor;
   }
 
@@ -1825,18 +1802,16 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor,
   public Component getTableCellEditorComponent(JTable table, Object value,
           boolean isSelected, int row, int column)
   {
-    currentGColor = null;
-    currentColor = null;
+    currentColor = (FeatureColourI) value;
     this.selectedRow = row;
     type = me.table.getValueAt(row, 0).toString();
     button.setOpaque(true);
     button.setBackground(me.getBackground());
-    if (value instanceof GraduatedColor)
+    if (!currentColor.isSimpleColour())
     {
-      currentGColor = (GraduatedColor) value;
       JLabel btn = new JLabel();
       btn.setSize(button.getSize());
-      FeatureSettings.renderGraduatedColor(btn, currentGColor);
+      FeatureSettings.renderGraduatedColor(btn, currentColor);
       button.setBackground(btn.getBackground());
       button.setIcon(btn.getIcon());
       button.setText(btn.getText());
@@ -1845,8 +1820,7 @@ class ColorEditor extends AbstractCellEditor implements TableCellEditor,
     {
       button.setText("");
       button.setIcon(null);
-      currentColor = (Color) value;
-      button.setBackground(currentColor);
+      button.setBackground(currentColor.getColour());
     }
     return button;
   }
index 6f602ad..8294d2b 100644 (file)
@@ -26,7 +26,6 @@ import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.awt.BorderLayout;
 import java.awt.Component;
-import java.awt.Container;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
 import java.awt.GridLayout;
@@ -73,7 +72,7 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
       @Override
       public void actionPerformed(ActionEvent arg0)
       {
-        showDialog(null);
+        showDialog();
       }
     });
     return viewdbs;
@@ -188,6 +187,7 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
     jc.validate();
     // j.setPreferredSize(new Dimension(300,50));
     add(jc, BorderLayout.CENTER);
+    ok.setEnabled(false);
     j.add(ok);
     j.add(cancel);
     add(j, BorderLayout.SOUTH);
@@ -320,7 +320,7 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
     closeDialog();
   }
 
-  private void showDialog(Container parent)
+  void showDialog()
   {
     oldselection = selection;
     oldtsel = tsel;
@@ -349,10 +349,12 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
     {
       return;
     }
+    ok.setEnabled(false);
     if (dbviews.getSelectionCount() == 0)
     {
       selection = null;
     }
+
     tsel = dbviews.getSelectionPaths();
     boolean forcedFirstChild = false;
     List<DbSourceProxy> srcs = new ArrayList<DbSourceProxy>();
@@ -364,6 +366,10 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
                 .getLastPathComponent();
         if (dmt.getUserObject() != null)
         {
+          /*
+           * enable OK button once a selection has been made
+           */
+          ok.setEnabled(true);
           if (dmt.getUserObject() instanceof DbSourceProxy)
           {
             srcs.add((DbSourceProxy) dmt.getUserObject());
@@ -419,6 +425,7 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
       }
     }
 
+    dbstatex.setText(" ");
     if (allowMultiSelections)
     {
       dbstatus.setText(MessageManager.formatMessage(
@@ -427,7 +434,6 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
                   (srcs.size() == 1 ? "" : "s"),
                   (srcs.size() > 0 ? " with " + x + " test quer"
                           + (x == 1 ? "y" : "ies") : ".") }));
-      dbstatex.setText(" ");
     }
     else
     {
@@ -440,10 +446,6 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
           dbstatex.setText(MessageManager.formatMessage(
                   "label.example_param", new String[] { qr }));
         }
-        else
-        {
-          dbstatex.setText(" ");
-        }
       }
       else
       {
index dfd2119..df076d9 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.gui;
 
+import jalview.api.FeatureColourI;
 import jalview.api.ViewStyleI;
 import jalview.api.structures.JalviewStructureDisplayI;
 import jalview.bin.Cache;
@@ -71,7 +72,7 @@ import jalview.schemabinding.version2.Viewport;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
 import jalview.schemes.ResidueColourScheme;
 import jalview.schemes.ResidueProperties;
 import jalview.schemes.UserColourScheme;
@@ -634,11 +635,15 @@ public class Jalview2XML
     object.setVersion(jalview.bin.Cache.getDefault("VERSION",
             "Development Build"));
 
-    jalview.datamodel.AlignmentI jal = av.getAlignment();
+    /**
+     * rjal is full height alignment, jal is actual alignment with full metadata
+     * but excludes hidden sequences.
+     */
+    jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
 
     if (av.hasHiddenRows())
     {
-      jal = jal.getHiddenSequences().getFullAlignment();
+      rjal = jal.getHiddenSequences().getFullAlignment();
     }
 
     SequenceSet vamsasSet = new SequenceSet();
@@ -655,6 +660,7 @@ public class Jalview2XML
       {
         // switch jal and the dataset
         jal = jal.getDataset();
+        rjal = jal;
       }
     }
     if (jal.getProperties() != null)
@@ -674,9 +680,9 @@ public class Jalview2XML
     Set<String> calcIdSet = new HashSet<String>();
 
     // SAVE SEQUENCES
-    for (int i = 0; i < jal.getHeight(); i++)
+    for (int i = 0; i < rjal.getHeight(); i++)
     {
-      final SequenceI jds = jal.getSequenceAt(i);
+      final SequenceI jds = rjal.getSequenceAt(i);
       final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
               : jds.getDatasetSequence();
       String id = seqHash(jds);
@@ -715,26 +721,34 @@ public class Jalview2XML
         // Store any sequences this sequence represents
         if (av.hasHiddenRows())
         {
+          // use rjal, contains the full height alignment
           jseq.setHidden(av.getAlignment().getHiddenSequences()
                   .isHidden(jds));
 
-          if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
+          if (av.isHiddenRepSequence(rjal.getSequenceAt(i)))
           {
             jalview.datamodel.SequenceI[] reps = av
-                    .getRepresentedSequences(jal.getSequenceAt(i))
-                    .getSequencesInOrder(jal);
+                    .getRepresentedSequences(rjal.getSequenceAt(i))
+                    .getSequencesInOrder(rjal);
 
             for (int h = 0; h < reps.length; h++)
             {
-              if (reps[h] != jal.getSequenceAt(i))
+              if (reps[h] != rjal.getSequenceAt(i))
               {
-                jseq.addHiddenSequences(jal.findIndex(reps[h]));
+                jseq.addHiddenSequences(rjal.findIndex(reps[h]));
               }
             }
           }
         }
+        // mark sequence as reference - if it is the reference for this view
+        if (jal.hasSeqrep())
+        {
+          jseq.setViewreference(rjal.getSequenceAt(i) == jal.getSeqrep());
+        }
       }
 
+      // TODO: omit sequence features from each alignment view's XML dump if we
+      // are storing dataset
       if (jds.getSequenceFeatures() != null)
       {
         jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
@@ -900,7 +914,7 @@ public class Jalview2XML
             alc.addAlcodMap(alcmap);
           }
         }
-
+        // TODO: delete this ? dead code from 2.8.3->2.9 ?
         // {
         // AlcodonFrame alc = new AlcodonFrame();
         // vamsasSet.addAlcodonFrame(alc);
@@ -1196,31 +1210,31 @@ public class Jalview2XML
                 .toArray(new String[0]);
 
         Vector<String> settingsAdded = new Vector<String>();
-        Object gstyle = null;
-        GraduatedColor gcol = null;
         if (renderOrder != null)
         {
           for (String featureType : renderOrder)
           {
-            gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
+            FeatureColourI fcol = ap.getSeqPanel().seqCanvas
+                    .getFeatureRenderer()
                     .getFeatureStyle(featureType);
             Setting setting = new Setting();
             setting.setType(featureType);
-            if (gstyle instanceof GraduatedColor)
+            if (!fcol.isSimpleColour())
             {
-              gcol = (GraduatedColor) gstyle;
-              setting.setColour(gcol.getMaxColor().getRGB());
-              setting.setMincolour(gcol.getMinColor().getRGB());
-              setting.setMin(gcol.getMin());
-              setting.setMax(gcol.getMax());
-              setting.setColourByLabel(gcol.isColourByLabel());
-              setting.setAutoScale(gcol.isAutoScale());
-              setting.setThreshold(gcol.getThresh());
-              setting.setThreshstate(gcol.getThreshType());
+              setting.setColour(fcol.getMaxColour().getRGB());
+              setting.setMincolour(fcol.getMinColour().getRGB());
+              setting.setMin(fcol.getMin());
+              setting.setMax(fcol.getMax());
+              setting.setColourByLabel(fcol.isColourByLabel());
+              setting.setAutoScale(fcol.isAutoScaled());
+              setting.setThreshold(fcol.getThreshold());
+              // -1 = No threshold, 0 = Below, 1 = Above
+              setting.setThreshstate(fcol.isAboveThreshold() ? 1
+                      : (fcol.isBelowThreshold() ? 0 : -1));
             }
             else
             {
-              setting.setColour(((Color) gstyle).getRGB());
+              setting.setColour(fcol.getColour().getRGB());
             }
 
             setting.setDisplay(av.getFeaturesDisplayed().isVisible(
@@ -1257,7 +1271,6 @@ public class Jalview2XML
           groupsAdded.addElement(grp);
         }
         jms.setFeatureSettings(fs);
-
       }
 
       if (av.hasHiddenColumns())
@@ -2654,7 +2667,7 @@ public class Jalview2XML
     List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
 
     boolean multipleView = false;
-
+    SequenceI referenceseqForView = null;
     JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
     int vi = 0; // counter in vamsasSeq array
     for (int i = 0; i < jseqs.length; i++)
@@ -2679,6 +2692,11 @@ public class Jalview2XML
         vi++;
       }
 
+      if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
+      {
+        referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
+      }
+
       if (jseqs[i].getHidden())
       {
         if (hiddenSeqs == null)
@@ -2688,7 +2706,6 @@ public class Jalview2XML
 
         hiddenSeqs.add(seqRefIds.get(seqId));
       }
-
     }
 
     // /
@@ -2699,6 +2716,10 @@ public class Jalview2XML
 
     AlignmentI al = new Alignment(orderedSeqs);
 
+    if (referenceseqForView != null)
+    {
+      al.setSeqrep(referenceseqForView);
+    }
     // / Add the alignment properties
     for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
     {
@@ -4092,6 +4113,12 @@ public class Jalview2XML
               .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
     }
 
+    if (al.hasSeqrep())
+    {
+      af.getViewport().setColourByReferenceSeq(true);
+      af.getViewport().setDisplayReferenceSeq(true);
+    }
+
     af.viewport.setGatherViewsHere(view.getGatheredViews());
 
     if (view.getSequenceSetId() != null)
@@ -4295,25 +4322,33 @@ public class Jalview2XML
       af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
       String[] renderOrder = new String[jms.getFeatureSettings()
               .getSettingCount()];
-      Hashtable featureGroups = new Hashtable();
-      Hashtable featureColours = new Hashtable();
-      Hashtable featureOrder = new Hashtable();
+      Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
+      Map<String, Float> featureOrder = new Hashtable<String, Float>();
 
       for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
       {
         Setting setting = jms.getFeatureSettings().getSetting(fs);
         if (setting.hasMincolour())
         {
-          GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
-                  new java.awt.Color(setting.getMincolour()),
-                  new java.awt.Color(setting.getColour()),
-                  setting.getMin(), setting.getMax()) : new GraduatedColor(
-                  new java.awt.Color(setting.getMincolour()),
-                  new java.awt.Color(setting.getColour()), 0, 1);
+          FeatureColourI gc = setting.hasMin() ? new FeatureColour(
+                  new Color(setting.getMincolour()), new Color(
+                          setting.getColour()), setting.getMin(),
+                  setting.getMax()) : new FeatureColour(new Color(
+                  setting.getMincolour()), new Color(setting.getColour()),
+                  0, 1);
           if (setting.hasThreshold())
           {
-            gc.setThresh(setting.getThreshold());
-            gc.setThreshType(setting.getThreshstate());
+            gc.setThreshold(setting.getThreshold());
+            int threshstate = setting.getThreshstate();
+            // -1 = None, 0 = Below, 1 = Above threshold
+            if (threshstate == 0)
+            {
+              gc.setBelowThreshold(true);
+            }
+            else if (threshstate == 1)
+            {
+              gc.setAboveThreshold(true);
+            }
           }
           gc.setAutoScaled(true); // default
           if (setting.hasAutoScale())
@@ -4329,8 +4364,8 @@ public class Jalview2XML
         }
         else
         {
-          featureColours.put(setting.getType(),
-                  new java.awt.Color(setting.getColour()));
+          featureColours.put(setting.getType(), new FeatureColour(
+                  new Color(setting.getColour())));
         }
         renderOrder[fs] = setting.getType();
         if (setting.hasOrder())
@@ -4347,7 +4382,7 @@ public class Jalview2XML
           fdi.setVisible(setting.getType());
         }
       }
-      Hashtable fgtable = new Hashtable();
+      Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
       for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
       {
         Group grp = jms.getFeatureSettings().getGroup(gs);
index 4b0ffad..e64d43f 100644 (file)
@@ -60,7 +60,6 @@ import jalview.util.GroupUrlLink;
 import jalview.util.GroupUrlLink.UrlStringTooLongException;
 import jalview.util.MessageManager;
 import jalview.util.UrlLink;
-import jalview.ws.DBRefFetcher;
 
 import java.awt.Color;
 import java.awt.event.ActionEvent;
@@ -2364,45 +2363,6 @@ public class PopupMenu extends JPopupMenu
             ap, true));
   }
 
-  public void enterPDB_actionPerformed()
-  {
-    String id = JOptionPane.showInternalInputDialog(Desktop.desktop,
-            MessageManager.getString("label.enter_pdb_id"),
-            MessageManager.getString("label.enter_pdb_id"),
-            JOptionPane.QUESTION_MESSAGE);
-
-    if (id != null && id.length() > 0)
-    {
-      PDBEntry entry = new PDBEntry();
-      entry.setId(id.toUpperCase());
-      sequence.getDatasetSequence().addPDBId(entry);
-    }
-  }
-
-  public void discoverPDB_actionPerformed()
-  {
-
-    final SequenceI[] sequences = ((ap.av.getSelectionGroup() == null) ? new SequenceI[]
-    { sequence }
-            : ap.av.getSequenceSelection());
-    Thread discpdb = new Thread(new Runnable()
-    {
-      @Override
-      public void run()
-      {
-        boolean isNucleotide = ap.alignFrame.getViewport().getAlignment()
-                .isNucleotide();
-
-        new DBRefFetcher(sequences, ap.alignFrame, null,
-                ap.alignFrame.featureSettings, isNucleotide)
-                .fetchDBRefs(false);
-
-      }
-
-    });
-    discpdb.start();
-  }
-
   public void sequenceFeature_actionPerformed()
   {
     SequenceGroup sg = ap.av.getSelectionGroup();
index 85ea20b..828a2aa 100755 (executable)
@@ -31,6 +31,7 @@ import jalview.fts.service.uniprot.UniprotFTSPanel;
 import jalview.io.gff.SequenceOntologyI;
 import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.ws.dbsources.das.api.DasSourceRegistryI;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
@@ -274,13 +275,13 @@ public class SequenceFetcher extends JPanel implements Runnable
 
     frame = new JInternalFrame();
     frame.setContentPane(this);
-    if (new jalview.util.Platform().isAMac())
+    if (Platform.isAMac())
     {
-      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 240);
+      Desktop.addInternalFrame(frame, getFrameTitle(), false, 400, 240);
     }
     else
     {
-      Desktop.addInternalFrame(frame, getFrameTitle(), 400, 180);
+      Desktop.addInternalFrame(frame, getFrameTitle(), false, 400, 180);
     }
   }
 
@@ -365,7 +366,19 @@ public class SequenceFetcher extends JPanel implements Runnable
     jPanel1.add(close);
     jPanel3.add(jPanel2, java.awt.BorderLayout.CENTER);
     jPanel2.setLayout(borderLayout3);
-    databaseButt = database.getDatabaseSelectorButton();
+    databaseButt = /*database.getDatabaseSelectorButton();
+                   final JButton viewdbs =*/new JButton(
+            MessageManager.getString("action.select_ddbb"));
+    databaseButt.addActionListener(new ActionListener()
+    {
+
+      @Override
+      public void actionPerformed(ActionEvent arg0)
+      {
+        hidePanel();
+        database.showDialog();
+      }
+    });
     databaseButt.setFont(JvSwingUtils.getLabelFont());
     database.addActionListener(new ActionListener()
     {
@@ -374,6 +387,12 @@ public class SequenceFetcher extends JPanel implements Runnable
       {
         debounceTrap++;
         String currentSelection = database.getSelectedItem();
+        if (currentSelection == null)
+        {
+          close_actionPerformed(null);
+        }
+
+        showPanel();
 
         if (currentSelection.equalsIgnoreCase("pdb")
                 && (database.action == KeyEvent.VK_ENTER || ((debounceTrap % 2) == 0)))
@@ -970,4 +989,22 @@ public class SequenceFetcher extends JPanel implements Runnable
   {
     this.progressIndicator = progressIndicator;
   }
+
+  /**
+   * Make this panel visible (after a selection has been made in the database
+   * chooser)
+   */
+  void showPanel()
+  {
+    frame.setVisible(true);
+  }
+
+  /**
+   * Hide this panel (on clicking the database button to open the database
+   * chooser)
+   */
+  void hidePanel()
+  {
+    frame.setVisible(false);
+  }
 }
index 258a229..427eb08 100755 (executable)
@@ -29,12 +29,6 @@ import java.awt.Color;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 
-/**
- * DOCUMENT ME!
- * 
- * @author $author$
- * @version $Revision$
- */
 public class SequenceRenderer implements jalview.api.SequenceRenderer
 {
   final static int CHAR_TO_UPPER = 'A' - 'a';
@@ -417,7 +411,7 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
           }
           if (!isarep && av.getShowUnconserved())
           {
-            s = getDisplayChar(srep, i, s, '.', currentSequenceGroup);
+            s = getDisplayChar(srep, i, s, '.', null);
 
           }
 
@@ -447,12 +441,17 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer
   {
     // TODO - use currentSequenceGroup rather than alignment
     // currentSequenceGroup.getConsensus()
-    char conschar = (usesrep) ? (currentGroup == null ? av.getAlignment()
+    char conschar = (usesrep) ? (currentGroup == null
+            || position < currentGroup.getStartRes()
+            || position > currentGroup.getEndRes() ? av.getAlignment()
             .getSeqrep().getCharAt(position)
             : (currentGroup.getSeqrep() != null ? currentGroup.getSeqrep()
                     .getCharAt(position) : av.getAlignment().getSeqrep()
                     .getCharAt(position)))
-            : (currentGroup != null && currentGroup.getConsensus() != null) ? currentGroup
+            : (currentGroup != null && currentGroup.getConsensus() != null
+                    && position >= currentGroup.getStartRes()
+                    && position <= currentGroup.getEndRes() && currentGroup
+                    .getConsensus().annotations.length > position) ? currentGroup
                     .getConsensus().annotations[position].displayCharacter
                     .charAt(0)
                     : av.getAlignmentConsensusAnnotation().annotations[position].displayCharacter
index 9464f66..c83f264 100644 (file)
@@ -533,8 +533,6 @@ public class StructureChooser extends GStructureChooser implements
     {
       cmb_filterOption.addItem(new FilterOption("Best Quality",
               "overall_quality", VIEWS_FILTER));
-      cmb_filterOption.addItem(new FilterOption("Most UniProt Coverage",
-              "uniprot_coverage", VIEWS_FILTER));
       cmb_filterOption.addItem(new FilterOption("Best Resolution",
               "resolution", VIEWS_FILTER));
       cmb_filterOption.addItem(new FilterOption("Most Protein Chain",
@@ -808,9 +806,13 @@ public class StructureChooser extends GStructureChooser implements
         pdbEntry = new PDBEntry();
             if (pdbIdStr.split(":").length > 1)
             {
-              pdbEntry.setChainCode(pdbIdStr.split(":")[1]);
+              pdbEntry.setId(pdbIdStr.split(":")[0]);
+              pdbEntry.setChainCode(pdbIdStr.split(":")[1].toUpperCase());
+            }
+            else
+            {
+              pdbEntry.setId(pdbIdStr);
             }
-        pdbEntry.setId(pdbIdStr);
         pdbEntry.setType(PDBEntry.Type.PDB);
         selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
       }
@@ -859,7 +861,8 @@ public class StructureChooser extends GStructureChooser implements
           final PDBEntry[] pdbEntriesToView,
           final AlignmentPanel alignPanel, SequenceI[] sequences)
   {
-    ssm.setProgressBar("Launching PDB structure viewer..");
+    ssm.setProgressBar(MessageManager
+            .getString("status.launching_3d_structure_viewer"));
     final StructureViewer sViewer = new StructureViewer(ssm);
 
     if (SiftsSettings.isMapWithSifts())
@@ -877,9 +880,9 @@ public class StructureChooser extends GStructureChooser implements
       {
         int y = seqsWithoutSourceDBRef.size();
         ssm.setProgressBar(null);
-        ssm.setProgressBar("Fetching db refs for " + y
-                + " sequence" + (y > 1 ? "s" : "")
-                + " without valid db ref required for SIFTS mapping");
+        ssm.setProgressBar(MessageManager.formatMessage(
+                "status.fetching_dbrefs_for_sequences_without_valid_refs",
+                y));
         SequenceI[] seqWithoutSrcDBRef = new SequenceI[y];
         int x = 0;
         for (SequenceI fSeq : seqsWithoutSourceDBRef)
@@ -898,14 +901,16 @@ public class StructureChooser extends GStructureChooser implements
       }
       SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]);
       ssm.setProgressBar(null);
-      ssm.setProgressBar("Fetching PDB Structures for selected entries..");
+      ssm.setProgressBar(MessageManager
+              .getString("status.fetching_3d_structures_for_selected_entries"));
       sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel);
     }
     else
     {
       ssm.setProgressBar(null);
-      ssm.setProgressBar("Fetching PDB Structure for "
-              + pdbEntriesToView[0].getId());
+      ssm.setProgressBar(MessageManager.formatMessage(
+              "status.fetching_3d_structures_for",
+              pdbEntriesToView[0].getId()));
       sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
     }
   }
index 372d905..aa38540 100755 (executable)
@@ -23,6 +23,7 @@ package jalview.io;
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.SequenceIdMatcher;
 import jalview.api.AlignViewportI;
+import jalview.api.FeatureColourI;
 import jalview.api.FeaturesSourceI;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
@@ -33,15 +34,12 @@ import jalview.datamodel.SequenceI;
 import jalview.io.gff.GffHelperBase;
 import jalview.io.gff.GffHelperFactory;
 import jalview.io.gff.GffHelperI;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
 import jalview.schemes.UserColourScheme;
-import jalview.util.Format;
 import jalview.util.MapList;
 import jalview.util.ParseHtmlBodyAndLinks;
 import jalview.util.StringUtils;
 
-import java.awt.Color;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -50,7 +48,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.StringTokenizer;
 
 /**
  * Parses and writes features files, which may be in Jalview, GFF2 or GFF3
@@ -140,7 +137,8 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    *          - process html strings into plain text
    * @return true if features were added
    */
-  public boolean parse(AlignmentI align, Map<String, Object> colours,
+  public boolean parse(AlignmentI align,
+          Map<String, FeatureColourI> colours,
           boolean removeHTML)
   {
     return parse(align, colours, removeHTML, false);
@@ -177,7 +175,8 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    *          - when true, ID matches to compound sequence IDs are allowed
    * @return true if features were added
    */
-  public boolean parse(AlignmentI align, Map<String, Object> colours,
+  public boolean parse(AlignmentI align,
+          Map<String, FeatureColourI> colours,
           boolean removeHTML, boolean relaxedIdmatching)
   {
     Map<String, String> gffProps = new HashMap<String, String>();
@@ -232,12 +231,18 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
           else if (ft.equalsIgnoreCase("endgroup"))
           {
             // We should check whether this is the current group,
-            // but at present theres no way of showing more than 1 group
+            // but at present there's no way of showing more than 1 group
             featureGroup = null;
           }
           else
           {
-            parseFeatureColour(line, ft, gffColumns, colours);
+            String colscheme = gffColumns[1];
+            FeatureColourI colour = FeatureColour
+                    .parseJalviewFeatureColour(colscheme);
+            if (colour != null)
+            {
+              colours.put(ft, colour);
+            }
           }
           continue;
         }
@@ -297,7 +302,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @param featureGroup
    */
   protected boolean parseJalviewFeature(String line, String[] gffColumns,
-          AlignmentI alignment, Map<String, Object> featureColours,
+          AlignmentI alignment, Map<String, FeatureColourI> featureColours,
           boolean removeHTML, boolean relaxedIdMatching, String featureGroup)
   {
     /*
@@ -350,7 +355,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
        * synthesize a colour from the feature type
        */
       UserColourScheme ucs = new UserColourScheme(ft);
-      featureColours.put(ft, ucs.findColour('A'));
+      featureColours.put(ft, new FeatureColour(ucs.findColour('A')));
     }
     SequenceFeature sf = new SequenceFeature(ft, desc, "", startPos,
             endPos, featureGroup);
@@ -381,225 +386,6 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
   }
 
   /**
-   * Process a feature type colour specification
-   * 
-   * @param line
-   *          the current input line (for error messages only)
-   * @param featureType
-   *          the first token on the line
-   * @param gffColumns
-   *          holds tokens on the line
-   * @param colours
-   *          map to which to add derived colour specification
-   */
-  protected void parseFeatureColour(String line, String featureType,
-          String[] gffColumns, Map<String, Object> colours)
-  {
-    Object colour = null;
-    String colscheme = gffColumns[1];
-    if (colscheme.indexOf("|") > -1
-            || colscheme.trim().equalsIgnoreCase("label"))
-    {
-      colour = parseGraduatedColourScheme(line, colscheme);
-    }
-    else
-    {
-      UserColourScheme ucs = new UserColourScheme(colscheme);
-      colour = ucs.findColour('A');
-    }
-    if (colour != null)
-    {
-      colours.put(featureType, colour);
-    }
-  }
-
-  /**
-   * Parse a Jalview graduated colour descriptor
-   * 
-   * @param line
-   * @param colourDescriptor
-   * @return
-   */
-  protected GraduatedColor parseGraduatedColourScheme(String line,
-          String colourDescriptor)
-  {
-    // Parse '|' separated graduated colourscheme fields:
-    // [label|][mincolour|maxcolour|[absolute|]minvalue|maxvalue|thresholdtype|thresholdvalue]
-    // can either provide 'label' only, first is optional, next two
-    // colors are required (but may be
-    // left blank), next is optional, nxt two min/max are required.
-    // first is either 'label'
-    // first/second and third are both hexadecimal or word equivalent
-    // colour.
-    // next two are values parsed as floats.
-    // fifth is either 'above','below', or 'none'.
-    // sixth is a float value and only required when fifth is either
-    // 'above' or 'below'.
-    StringTokenizer gcol = new StringTokenizer(colourDescriptor, "|", true);
-    // set defaults
-    float min = Float.MIN_VALUE, max = Float.MAX_VALUE;
-    boolean labelCol = false;
-    // Parse spec line
-    String mincol = gcol.nextToken();
-    if (mincol == "|")
-    {
-      System.err
-              .println("Expected either 'label' or a colour specification in the line: "
-                      + line);
-      return null;
-    }
-    String maxcol = null;
-    if (mincol.toLowerCase().indexOf("label") == 0)
-    {
-      labelCol = true;
-      mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null); // skip '|'
-      mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null);
-    }
-    String abso = null, minval, maxval;
-    if (mincol != null)
-    {
-      // at least four more tokens
-      if (mincol.equals("|"))
-      {
-        mincol = "";
-      }
-      else
-      {
-        gcol.nextToken(); // skip next '|'
-      }
-      // continue parsing rest of line
-      maxcol = gcol.nextToken();
-      if (maxcol.equals("|"))
-      {
-        maxcol = "";
-      }
-      else
-      {
-        gcol.nextToken(); // skip next '|'
-      }
-      abso = gcol.nextToken();
-      gcol.nextToken(); // skip next '|'
-      if (abso.toLowerCase().indexOf("abso") != 0)
-      {
-        minval = abso;
-        abso = null;
-      }
-      else
-      {
-        minval = gcol.nextToken();
-        gcol.nextToken(); // skip next '|'
-      }
-      maxval = gcol.nextToken();
-      if (gcol.hasMoreTokens())
-      {
-        gcol.nextToken(); // skip next '|'
-      }
-      try
-      {
-        if (minval.length() > 0)
-        {
-          min = Float.valueOf(minval);
-        }
-      } catch (Exception e)
-      {
-        System.err
-                .println("Couldn't parse the minimum value for graduated colour for type ("
-                        + colourDescriptor
-                        + ") - did you misspell 'auto' for the optional automatic colour switch ?");
-        e.printStackTrace();
-      }
-      try
-      {
-        if (maxval.length() > 0)
-        {
-          max = Float.valueOf(maxval);
-        }
-      } catch (Exception e)
-      {
-        System.err
-                .println("Couldn't parse the maximum value for graduated colour for type ("
-                        + colourDescriptor + ")");
-        e.printStackTrace();
-      }
-    }
-    else
-    {
-      // add in some dummy min/max colours for the label-only
-      // colourscheme.
-      mincol = "FFFFFF";
-      maxcol = "000000";
-    }
-
-    GraduatedColor colour = null;
-    try
-    {
-      colour = new GraduatedColor(
-              new UserColourScheme(mincol).findColour('A'),
-              new UserColourScheme(maxcol).findColour('A'), min, max);
-    } catch (Exception e)
-    {
-      System.err.println("Couldn't parse the graduated colour scheme ("
-              + colourDescriptor + ")");
-      e.printStackTrace();
-    }
-    if (colour != null)
-    {
-      colour.setColourByLabel(labelCol);
-      colour.setAutoScaled(abso == null);
-      // add in any additional parameters
-      String ttype = null, tval = null;
-      if (gcol.hasMoreTokens())
-      {
-        // threshold type and possibly a threshold value
-        ttype = gcol.nextToken();
-        if (ttype.toLowerCase().startsWith("below"))
-        {
-          colour.setThreshType(AnnotationColourGradient.BELOW_THRESHOLD);
-        }
-        else if (ttype.toLowerCase().startsWith("above"))
-        {
-          colour.setThreshType(AnnotationColourGradient.ABOVE_THRESHOLD);
-        }
-        else
-        {
-          colour.setThreshType(AnnotationColourGradient.NO_THRESHOLD);
-          if (!ttype.toLowerCase().startsWith("no"))
-          {
-            System.err.println("Ignoring unrecognised threshold type : "
-                    + ttype);
-          }
-        }
-      }
-      if (colour.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
-      {
-        try
-        {
-          gcol.nextToken();
-          tval = gcol.nextToken();
-          colour.setThresh(new Float(tval).floatValue());
-        } catch (Exception e)
-        {
-          System.err.println("Couldn't parse threshold value as a float: ("
-                  + tval + ")");
-          e.printStackTrace();
-        }
-      }
-      // parse the thresh-is-min token ?
-      if (gcol.hasMoreTokens())
-      {
-        System.err
-                .println("Ignoring additional tokens in parameters in graduated colour specification\n");
-        while (gcol.hasMoreTokens())
-        {
-          System.err.println("|" + gcol.nextToken());
-        }
-        System.err.println("\n");
-      }
-    }
-    return colour;
-  }
-
-  /**
    * clear any temporary handles used to speed up ID matching
    */
   protected void resetMatcher()
@@ -703,7 +489,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @return features file contents
    */
   public String printJalviewFormat(SequenceI[] sequences,
-          Map<String, Object> visible)
+          Map<String, FeatureColourI> visible)
   {
     return printJalviewFormat(sequences, visible, true, true);
   }
@@ -723,7 +509,8 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @return features file contents
    */
   public String printJalviewFormat(SequenceI[] sequences,
-          Map<String, Object> visible, boolean visOnly, boolean nonpos)
+          Map<String, FeatureColourI> visible, boolean visOnly,
+          boolean nonpos)
   {
     StringBuilder out = new StringBuilder(256);
     boolean featuresGen = false;
@@ -739,58 +526,14 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
       // viewed features
       // TODO: decide if feature links should also be written here ?
       Iterator<String> en = visible.keySet().iterator();
-      String featureType, color;
       while (en.hasNext())
       {
-        featureType = en.next().toString();
-
-        if (visible.get(featureType) instanceof GraduatedColor)
-        {
-          GraduatedColor gc = (GraduatedColor) visible.get(featureType);
-          color = (gc.isColourByLabel() ? "label|" : "")
-                  + Format.getHexString(gc.getMinColor()) + "|"
-                  + Format.getHexString(gc.getMaxColor())
-                  + (gc.isAutoScale() ? "|" : "|abso|") + gc.getMin() + "|"
-                  + gc.getMax() + "|";
-          if (gc.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
-          {
-            if (gc.getThreshType() == AnnotationColourGradient.BELOW_THRESHOLD)
-            {
-              color += "below";
-            }
-            else
-            {
-              if (gc.getThreshType() != AnnotationColourGradient.ABOVE_THRESHOLD)
-              {
-                System.err.println("WARNING: Unsupported threshold type ("
-                        + gc.getThreshType() + ") : Assuming 'above'");
-              }
-              color += "above";
-            }
-            // add the value
-            color += "|" + gc.getThresh();
-          }
-          else
-          {
-            color += "none";
-          }
-        }
-        else if (visible.get(featureType) instanceof Color)
-        {
-          color = Format.getHexString((Color) visible.get(featureType));
-        }
-        else
-        {
-          // legacy support for integer objects containing colour triplet values
-          color = Format.getHexString(new Color(Integer.parseInt(visible
-                  .get(featureType).toString())));
-        }
-        out.append(featureType);
-        out.append(TAB);
-        out.append(color);
-        out.append(newline);
+        String featureType = en.next().toString();
+        FeatureColourI colour = visible.get(featureType);
+        out.append(colour.toJalviewFormat(featureType)).append(newline);
       }
     }
+
     // Work out which groups are both present and visible
     List<String> groups = new ArrayList<String>();
     int groupIndex = 0;
@@ -1004,7 +747,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @return
    */
   public String printGffFormat(SequenceI[] sequences,
-          Map<String, Object> visible)
+          Map<String, FeatureColourI> visible)
   {
     return printGffFormat(sequences, visible, true, true);
   }
@@ -1021,7 +764,7 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI
    * @return
    */
   public String printGffFormat(SequenceI[] sequences,
-          Map<String, Object> visible, boolean outputVisibleOnly,
+          Map<String, FeatureColourI> visible, boolean outputVisibleOnly,
           boolean includeNonPositionalFeatures)
   {
     StringBuilder out = new StringBuilder(256);
index 00af242..4e1b261 100644 (file)
@@ -51,6 +51,13 @@ public class HtmlSvgOutput
 
   AlignmentPanel ap;
 
+  private IProgressIndicator pIndicator;
+
+  private long pSessionId;
+
+  private boolean headless;
+
+
   public HtmlSvgOutput(File file, AlignmentPanel ap)
   {
     this.av = ap.av;
@@ -61,20 +68,16 @@ public class HtmlSvgOutput
 
   public void generateHtmlSvgOutput(File file)
   {
-    IProgressIndicator pIndicator = ap.alignFrame;
-    long pSessionId = System.currentTimeMillis();
+    pIndicator = ap.alignFrame;
+    pSessionId = System.currentTimeMillis();
     try
     {
-      boolean headless = (System.getProperty("java.awt.headless") != null && System
+      headless = (System.getProperty("java.awt.headless") != null && System
               .getProperty("java.awt.headless").equals("true"));
       if (file == null)
       {
-        if (pIndicator != null && !headless)
-        {
-          pIndicator.setProgressBar(MessageManager.formatMessage(
-                  "status.waiting_for_user_to_select_output_file", "HTML"),
-                  pSessionId);
-        }
+        setProgressMessage(MessageManager.formatMessage(
+                "status.waiting_for_user_to_select_output_file", "HTML"));
         JalviewFileChooser chooser = getHTMLChooser();
         chooser.setFileView(new jalview.io.JalviewFileView());
         chooser.setDialogTitle(ap.alignFrame.getTitle());
@@ -86,135 +89,164 @@ public class HtmlSvgOutput
           jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
                   .getSelectedFile().getParent());
           file = chooser.getSelectedFile();
+          ap.alignFrame.repaint();
         }
         else
         {
-
-          if (pIndicator != null && !headless)
-        {
-            pIndicator.setProgressBar(MessageManager.formatMessage(
-                    "status.cancelled_image_export_operation", "HTML"),
-                    pSessionId);
-          }
+          setProgressMessage(MessageManager.formatMessage(
+                  "status.cancelled_image_export_operation", "HTML"));
           return;
         }
       }
-
-      AlignmentDimension aDimension = ap.getAlignmentDimension();
-      SVGGraphics2D g1 = new SVGGraphics2D(aDimension.getWidth(),
-              aDimension.getHeight());
-      SVGGraphics2D g2 = new SVGGraphics2D(aDimension.getWidth(),
-              aDimension.getHeight());
-
-      String renderStyle = jalview.bin.Cache.getDefault("HTML_RENDERING",
-              "Prompt each time");
-
-      // If we need to prompt, and if the GUI is visible then
-      // Prompt for rendering style
-      if (renderStyle.equalsIgnoreCase("Prompt each time")
-              && !(System.getProperty("java.awt.headless") != null && System
-                      .getProperty("java.awt.headless").equals("true")))
-      {
-        HTMLOptions svgOption = new HTMLOptions();
-        renderStyle = svgOption.getValue();
-
-        if (renderStyle == null || svgOption.cancelled)
-        {
-          return;
-        }
-      }
-
-      if (renderStyle.equalsIgnoreCase("Lineart"))
-      {
-        g1.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
-                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
-        g2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
-                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
-      }
-      printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, g1,
-              g2);
-
-      String titleSvgData = g1.getSVGDocument();
-      String alignSvgData = g2.getSVGDocument();
-      String jsonData = null;
-      boolean isEmbbedBioJSON = Boolean.valueOf(jalview.bin.Cache
-              .getDefault("EXPORT_EMBBED_BIOJSON", "true"));
-      if (isEmbbedBioJSON)
+    } catch (Exception e)
+    {
+      pIndicator.setProgressBar(MessageManager.formatMessage(
+              "info.error_creating_file", "HTML"), pSessionId);
+      e.printStackTrace();
+      return;
+    }
+    final File fileX = file;
+    new Thread()
+    {
+      @Override
+      public void run()
       {
-        AlignExportSettingI exportSettings = new AlignExportSettingI()
+        try
         {
-          @Override
-          public boolean isExportHiddenSequences()
+          setProgressMessage(null);
+          setProgressMessage(MessageManager
+.formatMessage(
+                  "status.exporting_alignment_as_x_file", "HTML"));
+          AlignmentDimension aDimension = ap.getAlignmentDimension();
+          SVGGraphics2D g1 = new SVGGraphics2D(aDimension.getWidth(),
+                  aDimension.getHeight());
+          SVGGraphics2D g2 = new SVGGraphics2D(aDimension.getWidth(),
+                  aDimension.getHeight());
+
+          String renderStyle = jalview.bin.Cache.getDefault(
+                  "HTML_RENDERING", "Prompt each time");
+
+          // If we need to prompt, and if the GUI is visible then
+          // Prompt for rendering style
+          if (renderStyle.equalsIgnoreCase("Prompt each time")
+                  && !(System.getProperty("java.awt.headless") != null && System
+                          .getProperty("java.awt.headless").equals("true")))
           {
-            return true;
+            HTMLOptions svgOption = new HTMLOptions();
+            renderStyle = svgOption.getValue();
+
+            if (renderStyle == null || svgOption.cancelled)
+            {
+              setProgressMessage(MessageManager.formatMessage(
+                      "status.cancelled_image_export_operation", "HTML"));
+              return;
+            }
           }
 
-          @Override
-          public boolean isExportHiddenColumns()
+          if (renderStyle.equalsIgnoreCase("Lineart"))
           {
-            return true;
+            g1.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
+                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
+            g2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
+                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
           }
-
-          @Override
-          public boolean isExportAnnotations()
+          printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
+                  g1, g2);
+
+          String titleSvgData = g1.getSVGDocument();
+          String alignSvgData = g2.getSVGDocument();
+          String jsonData = null;
+          boolean isEmbbedBioJSON = Boolean.valueOf(jalview.bin.Cache
+                  .getDefault("EXPORT_EMBBED_BIOJSON", "true"));
+          if (isEmbbedBioJSON)
           {
-            return true;
+            AlignExportSettingI exportSettings = new AlignExportSettingI()
+            {
+              @Override
+              public boolean isExportHiddenSequences()
+              {
+                return true;
+              }
+
+              @Override
+              public boolean isExportHiddenColumns()
+              {
+                return true;
+              }
+
+              @Override
+              public boolean isExportAnnotations()
+              {
+                return true;
+              }
+
+              @Override
+              public boolean isExportFeatures()
+              {
+                return true;
+              }
+
+              @Override
+              public boolean isExportGroups()
+              {
+                return true;
+              }
+
+              @Override
+              public boolean isCancelled()
+              {
+                return false;
+              }
+
+            };
+            AlignmentExportData exportData = jalview.gui.AlignFrame
+                    .getAlignmentForExport(JSONFile.FILE_DESC, av,
+                            exportSettings);
+            jsonData = new FormatAdapter(ap, exportData.getSettings())
+                    .formatSequences(JSONFile.FILE_DESC,
+                            exportData.getAlignment(),
+                            exportData.getOmitHidden(),
+                            exportData.getStartEndPostions(),
+                            av.getColumnSelection());
           }
-
-          @Override
-          public boolean isExportFeatures()
-          {
-            return true;
-          }
-
-          @Override
-          public boolean isExportGroups()
+          String htmlData = getHtml(titleSvgData, alignSvgData, jsonData);
+          FileOutputStream out = new FileOutputStream(fileX);
+          out.write(htmlData.getBytes());
+          out.flush();
+          out.close();
+          if (!(System.getProperty("java.awt.headless") != null && System
+                  .getProperty("java.awt.headless").equals("true")))
           {
-            return true;
+            jalview.util.BrowserLauncher.openURL("file:///" + fileX);
           }
+        } catch (OutOfMemoryError err)
+        {
+          System.out.println("########################\n"
+                  + "OUT OF MEMORY " + fileX + "\n"
+                  + "########################");
+          new OOMWarning("Creating Image for " + fileX, err);
+        } catch (Exception e)
+        {
+          e.printStackTrace();
+          pIndicator.setProgressBar(MessageManager.formatMessage(
+                  "info.error_creating_file", "HTML"), pSessionId);
+        }
+        setProgressMessage(MessageManager.formatMessage(
+                "status.export_complete", "HTML"));
+      }
+    }.start();
 
-          @Override
-          public boolean isCancelled()
-          {
-            return false;
-          }
+  }
 
-        };
-        AlignmentExportData exportData = jalview.gui.AlignFrame
-                .getAlignmentForExport(JSONFile.FILE_DESC, av,
-                        exportSettings);
-        jsonData = new FormatAdapter(ap, exportData.getSettings())
-                .formatSequences(JSONFile.FILE_DESC,
-                        exportData.getAlignment(),
-                        exportData.getOmitHidden(),
-                        exportData.getStartEndPostions(),
-                        av.getColumnSelection());
-      }
-      String htmlData = getHtml(titleSvgData, alignSvgData, jsonData);
-      FileOutputStream out = new FileOutputStream(file);
-      out.write(htmlData.getBytes());
-      out.flush();
-      out.close();
-      if (!(System.getProperty("java.awt.headless") != null && System
-              .getProperty("java.awt.headless").equals("true")))
-      {
-        jalview.util.BrowserLauncher.openURL("file:///" + file);
-      }
-      if (pIndicator != null && !headless)
-      {
-        pIndicator.setProgressBar(MessageManager.formatMessage(
-                "status.export_complete", "HTML"), pSessionId);
-      }
-    } catch (OutOfMemoryError err)
+  private void setProgressMessage(String message)
+  {
+    if (pIndicator != null && !headless)
     {
-      System.out.println("########################\n" + "OUT OF MEMORY "
-              + file + "\n" + "########################");
-      new OOMWarning("Creating Image for " + file, err);
-    } catch (Exception e)
+      pIndicator.setProgressBar(message, pSessionId);
+    }
+    else
     {
-      e.printStackTrace();
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "info.error_creating_file", "HTML"), pSessionId);
+      System.out.println(message);
     }
   }
 
index 83bb37e..ecce1a3 100644 (file)
@@ -1,7 +1,7 @@
 package jalview.io;
 
 import jalview.api.FeatureColourI;
-import jalview.schemes.FeatureColourAdapter;
+import jalview.schemes.FeatureColour;
 import jalview.schemes.FeatureSettingsAdapter;
 
 import java.awt.Color;
@@ -25,7 +25,7 @@ public class PDBFeatureSettings extends FeatureSettingsAdapter
   {
     if (type.equalsIgnoreCase(FEATURE_INSERTION))
     {
-      return new FeatureColourAdapter()
+      return new FeatureColour()
       {
 
         @Override
index 817ba9c..63263d2 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.io.packed;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
 import jalview.io.NewickFile;
@@ -57,7 +58,7 @@ public class JalviewDataset
   /**
    * @return the featureColours
    */
-  public Map<String, Object> getFeatureColours()
+  public Map<String, FeatureColourI> getFeatureColours()
   {
     return featureColours;
   }
@@ -66,7 +67,7 @@ public class JalviewDataset
    * @param featureColours
    *          the featureColours to set
    */
-  public void setFeatureColours(Map<String, Object> featureColours)
+  public void setFeatureColours(Map<String, FeatureColourI> featureColours)
   {
     this.featureColours = featureColours;
   }
@@ -187,7 +188,7 @@ public class JalviewDataset
   /**
    * current set of feature colours
    */
-  Map<String, Object> featureColours;
+  Map<String, FeatureColourI> featureColours;
 
   /**
    * original identity of each sequence in results
@@ -201,7 +202,7 @@ public class JalviewDataset
     seqDetails = new Hashtable();
     al = new ArrayList<AlignmentSet>();
     parentDataset = null;
-    featureColours = new HashMap<String, Object>();
+    featureColours = new HashMap<String, FeatureColourI>();
   }
 
   /**
@@ -209,7 +210,8 @@ public class JalviewDataset
    * 
    * @param parentAlignment
    */
-  public JalviewDataset(AlignmentI aldataset, Map<String, Object> fc,
+  public JalviewDataset(AlignmentI aldataset,
+          Map<String, FeatureColourI> fc,
           Hashtable seqDets)
   {
     // TODO not used - remove?
@@ -231,7 +233,8 @@ public class JalviewDataset
    *          (may be null) alignment to associate new annotation and trees
    *          with.
    */
-  public JalviewDataset(AlignmentI aldataset, Map<String, Object> fc,
+  public JalviewDataset(AlignmentI aldataset,
+          Map<String, FeatureColourI> fc,
           Hashtable seqDets, AlignmentI parentAlignment)
   {
     this();
index 01369b9..71999f0 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.io.packed;
 
+import jalview.api.FeatureColourI;
 import jalview.datamodel.AlignmentI;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.FileParse;
@@ -157,7 +158,7 @@ public class ParsePackedSet
         // if not, create one.
         if (context.featureColours == null)
         {
-          context.featureColours = new HashMap<String, Object>();
+          context.featureColours = new HashMap<String, FeatureColourI>();
         }
         try
         {
index e9eab82..44f659d 100644 (file)
@@ -450,9 +450,8 @@ public abstract class GStructureChooser extends JPanel implements
     chk_invertFilter.setFont(new java.awt.Font("Verdana", 0, 12));
     chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12));
     chk_rememberSettings.setVisible(false);
-
-    txt_search.setToolTipText(MessageManager
-            .getString("label.enter_pdb_id"));
+    txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
+            MessageManager.getString("label.enter_pdb_id")));
     cmb_filterOption.setToolTipText(MessageManager
             .getString("info.select_filter_option"));
     txt_search.getDocument().addDocumentListener(new DocumentListener()
index 0d14cd9..5d3aa2d 100644 (file)
@@ -50,6 +50,8 @@ public class FeatureRenderer extends FeatureRendererModel
 
   boolean av_validCharWidth, av_isShowSeqFeatureHeight;
 
+  private Integer currentColour;
+
   protected void updateAvConfig()
   {
     av_charHeight = av.getCharHeight();
@@ -175,8 +177,8 @@ public class FeatureRenderer extends FeatureRendererModel
   }
 
   /**
-   * This is used by the Molecule Viewer and Overview to get the accurate
-   * colourof the rendered sequence
+   * This is used by the Molecule Viewer and Overview to get the accurate colour
+   * of the rendered sequence
    */
   public synchronized int findFeatureColour(int initialCol,
           final SequenceI seq, int column)
@@ -246,7 +248,7 @@ public class FeatureRenderer extends FeatureRendererModel
       }
       else
       {
-        return ((Integer) currentColour).intValue();
+        return currentColour.intValue();
       }
     }
 
index 361fb7c..0a01103 100644 (file)
@@ -1,4 +1,4 @@
-#Thu Sep 03 10:55:37 BST 2015
+#Mon Jun 20 15:44:52 BST 2016
 jalview.schemabinding.version2.ThresholdLine=jalview.schemabinding.version2.descriptors.ThresholdLineDescriptor
 jalview.schemabinding.version2.SequenceSetProperties=jalview.schemabinding.version2.descriptors.SequenceSetPropertiesDescriptor
 jalview.schemabinding.version2.StructureState=jalview.schemabinding.version2.descriptors.StructureStateDescriptor
index 9ca6708..7c6308e 100644 (file)
@@ -72,6 +72,16 @@ public class JSeq implements java.io.Serializable
   private boolean _has_hidden;
 
   /**
+   * Field _viewreference.
+   */
+  private boolean _viewreference;
+
+  /**
+   * keeps track of state for field: _viewreference
+   */
+  private boolean _has_viewreference;
+
+  /**
    * Field _featuresList.
    */
   private java.util.Vector _featuresList;
@@ -256,6 +266,13 @@ public class JSeq implements java.io.Serializable
   }
 
   /**
+     */
+  public void deleteViewreference()
+  {
+    this._has_viewreference = false;
+  }
+
+  /**
    * Method enumerateFeatures.
    * 
    * @return an Enumeration over all jalview.schemabinding.version2.Features
@@ -549,6 +566,16 @@ public class JSeq implements java.io.Serializable
   }
 
   /**
+   * Returns the value of field 'viewreference'.
+   * 
+   * @return the value of field 'Viewreference'.
+   */
+  public boolean getViewreference()
+  {
+    return this._viewreference;
+  }
+
+  /**
    * Method hasColour.
    * 
    * @return true if at least one Colour has been added
@@ -589,6 +616,16 @@ public class JSeq implements java.io.Serializable
   }
 
   /**
+   * Method hasViewreference.
+   * 
+   * @return true if at least one Viewreference has been added
+   */
+  public boolean hasViewreference()
+  {
+    return this._has_viewreference;
+  }
+
+  /**
    * Returns the value of field 'hidden'.
    * 
    * @return the value of field 'Hidden'.
@@ -616,6 +653,16 @@ public class JSeq implements java.io.Serializable
   }
 
   /**
+   * Returns the value of field 'viewreference'.
+   * 
+   * @return the value of field 'Viewreference'.
+   */
+  public boolean isViewreference()
+  {
+    return this._viewreference;
+  }
+
+  /**
    * 
    * 
    * @param out
@@ -1004,6 +1051,18 @@ public class JSeq implements java.io.Serializable
   }
 
   /**
+   * Sets the value of field 'viewreference'.
+   * 
+   * @param viewreference
+   *          the value of field 'viewreference'.
+   */
+  public void setViewreference(final boolean viewreference)
+  {
+    this._viewreference = viewreference;
+    this._has_viewreference = true;
+  }
+
+  /**
    * Method unmarshal.
    * 
    * @param reader
index 1d2aad3..5739d90 100644 (file)
@@ -11,6 +11,8 @@ package jalview.schemabinding.version2.descriptors;
 //- Imported classes and packages -/
 //---------------------------------/
 
+import jalview.schemabinding.version2.AnnotationColours;
+
 /**
  * Class AnnotationColoursDescriptor.
  * 
index a7ffaba..107c06d 100644 (file)
@@ -11,6 +11,8 @@ package jalview.schemabinding.version2.descriptors;
 //- Imported classes and packages -/
 //---------------------------------/
 
+import jalview.schemabinding.version2.Features;
+
 /**
  * Class FeaturesDescriptor.
  * 
index 0f000bb..28f23b2 100644 (file)
@@ -334,6 +334,61 @@ public class JSeqDescriptor extends
       fieldValidator.setValidator(typeValidator);
     }
     desc.setValidator(fieldValidator);
+    // -- _viewreference
+    desc = new org.exolab.castor.xml.util.XMLFieldDescriptorImpl(
+            java.lang.Boolean.TYPE, "_viewreference", "viewreference",
+            org.exolab.castor.xml.NodeType.Attribute);
+    handler = new org.exolab.castor.xml.XMLFieldHandler()
+    {
+      public java.lang.Object getValue(java.lang.Object object)
+              throws IllegalStateException
+      {
+        JSeq target = (JSeq) object;
+        if (!target.hasViewreference())
+        {
+          return null;
+        }
+        return (target.getViewreference() ? java.lang.Boolean.TRUE
+                : java.lang.Boolean.FALSE);
+      }
+
+      public void setValue(java.lang.Object object, java.lang.Object value)
+              throws IllegalStateException, IllegalArgumentException
+      {
+        try
+        {
+          JSeq target = (JSeq) object;
+          // if null, use delete method for optional primitives
+          if (value == null)
+          {
+            target.deleteViewreference();
+            return;
+          }
+          target.setViewreference(((java.lang.Boolean) value)
+                  .booleanValue());
+        } catch (java.lang.Exception ex)
+        {
+          throw new IllegalStateException(ex.toString());
+        }
+      }
+
+      public java.lang.Object newInstance(java.lang.Object parent)
+      {
+        return null;
+      }
+    };
+    desc.setHandler(handler);
+    desc.setMultivalued(false);
+    addFieldDescriptor(desc);
+
+    // -- validation code for: _viewreference
+    fieldValidator = new org.exolab.castor.xml.FieldValidator();
+    { // -- local scope
+      org.exolab.castor.xml.validators.BooleanValidator typeValidator;
+      typeValidator = new org.exolab.castor.xml.validators.BooleanValidator();
+      fieldValidator.setValidator(typeValidator);
+    }
+    desc.setValidator(fieldValidator);
     // -- initialize element descriptors
 
     // -- _featuresList
index 77efa7e..d65de13 100644 (file)
@@ -72,6 +72,7 @@ public class JalviewUserColoursDescriptor extends
     desc.setImmutable(true);
     handler = new org.exolab.castor.xml.XMLFieldHandler()
     {
+      @Override
       public java.lang.Object getValue(java.lang.Object object)
               throws IllegalStateException
       {
@@ -79,6 +80,7 @@ public class JalviewUserColoursDescriptor extends
         return target.getSchemeName();
       }
 
+      @Override
       public void setValue(java.lang.Object object, java.lang.Object value)
               throws IllegalStateException, IllegalArgumentException
       {
@@ -92,6 +94,7 @@ public class JalviewUserColoursDescriptor extends
         }
       }
 
+      @Override
       public java.lang.Object newInstance(java.lang.Object parent)
       {
         return null;
@@ -119,6 +122,7 @@ public class JalviewUserColoursDescriptor extends
     desc.setImmutable(true);
     handler = new org.exolab.castor.xml.XMLFieldHandler()
     {
+      @Override
       public java.lang.Object getValue(java.lang.Object object)
               throws IllegalStateException
       {
@@ -126,6 +130,7 @@ public class JalviewUserColoursDescriptor extends
         return target.getVersion();
       }
 
+      @Override
       public void setValue(java.lang.Object object, java.lang.Object value)
               throws IllegalStateException, IllegalArgumentException
       {
@@ -139,6 +144,7 @@ public class JalviewUserColoursDescriptor extends
         }
       }
 
+      @Override
       public java.lang.Object newInstance(java.lang.Object parent)
       {
         return null;
@@ -163,6 +169,7 @@ public class JalviewUserColoursDescriptor extends
             org.exolab.castor.xml.NodeType.Element);
     handler = new org.exolab.castor.xml.XMLFieldHandler()
     {
+      @Override
       public java.lang.Object getValue(java.lang.Object object)
               throws IllegalStateException
       {
@@ -170,6 +177,7 @@ public class JalviewUserColoursDescriptor extends
         return target.getColour();
       }
 
+      @Override
       public void setValue(java.lang.Object object, java.lang.Object value)
               throws IllegalStateException, IllegalArgumentException
       {
@@ -183,6 +191,7 @@ public class JalviewUserColoursDescriptor extends
         }
       }
 
+      @Override
       public void resetValue(Object object) throws IllegalStateException,
               IllegalArgumentException
       {
@@ -196,6 +205,7 @@ public class JalviewUserColoursDescriptor extends
         }
       }
 
+      @Override
       public java.lang.Object newInstance(java.lang.Object parent)
       {
         return new Colour();
@@ -222,6 +232,7 @@ public class JalviewUserColoursDescriptor extends
    * 
    * @return the access mode specified for this class.
    */
+  @Override
   public org.exolab.castor.mapping.AccessMode getAccessMode()
   {
     return null;
@@ -232,6 +243,7 @@ public class JalviewUserColoursDescriptor extends
    * 
    * @return the identity field, null if this class has no identity.
    */
+  @Override
   public org.exolab.castor.mapping.FieldDescriptor getIdentity()
   {
     return super.getIdentity();
@@ -242,6 +254,7 @@ public class JalviewUserColoursDescriptor extends
    * 
    * @return the Java class represented by this descriptor.
    */
+  @Override
   public java.lang.Class getJavaClass()
   {
     return jalview.schemabinding.version2.JalviewUserColours.class;
@@ -252,6 +265,7 @@ public class JalviewUserColoursDescriptor extends
    * 
    * @return the namespace prefix to use when marshaling as XML.
    */
+  @Override
   public java.lang.String getNameSpacePrefix()
   {
     return _nsPrefix;
@@ -262,6 +276,7 @@ public class JalviewUserColoursDescriptor extends
    * 
    * @return the namespace URI used when marshaling and unmarshaling as XML.
    */
+  @Override
   public java.lang.String getNameSpaceURI()
   {
     return _nsURI;
@@ -273,6 +288,7 @@ public class JalviewUserColoursDescriptor extends
    * @return a specific validator for the class described by this
    *         ClassDescriptor.
    */
+  @Override
   public org.exolab.castor.xml.TypeValidator getValidator()
   {
     return this;
@@ -283,6 +299,7 @@ public class JalviewUserColoursDescriptor extends
    * 
    * @return the XML Name for the Class being described.
    */
+  @Override
   public java.lang.String getXMLName()
   {
     return _xmlName;
@@ -294,6 +311,7 @@ public class JalviewUserColoursDescriptor extends
    * @return true if XML schema definition of this Class is that of a global
    *         element or element with anonymous type definition.
    */
+  @Override
   public boolean isElementDefinition()
   {
     return _elementDefinition;
index ece728a..df9ab07 100644 (file)
@@ -11,6 +11,8 @@ package jalview.schemabinding.version2.descriptors;
 //- Imported classes and packages -/
 //---------------------------------/
 
+import jalview.schemabinding.version2.UserColourScheme;
+
 /**
  * Class UserColourSchemeDescriptor.
  * 
index 86e6992..3e26611 100644 (file)
@@ -11,6 +11,8 @@ package jalview.schemabinding.version2.descriptors;
 //- Imported classes and packages -/
 //---------------------------------/
 
+import jalview.schemabinding.version2.VamsasModel;
+
 /**
  * Class VamsasModelDescriptor.
  * 
diff --git a/src/jalview/schemes/FeatureColour.java b/src/jalview/schemes/FeatureColour.java
new file mode 100644 (file)
index 0000000..213868b
--- /dev/null
@@ -0,0 +1,672 @@
+package jalview.schemes;
+
+import jalview.api.FeatureColourI;
+import jalview.datamodel.SequenceFeature;
+import jalview.util.Format;
+
+import java.awt.Color;
+import java.util.StringTokenizer;
+
+/**
+ * A class that wraps either a simple colour or a graduated colour
+ */
+public class FeatureColour implements FeatureColourI
+{
+  private static final String BAR = "|";
+
+  final private Color colour;
+
+  final private Color minColour;
+
+  final private Color maxColour;
+
+  private boolean graduatedColour;
+
+  private boolean colourByLabel;
+
+  private float threshold;
+
+  private float base;
+
+  private float range;
+
+  private boolean belowThreshold;
+
+  private boolean aboveThreshold;
+
+  private boolean thresholdIsMinOrMax;
+
+  private boolean isHighToLow;
+
+  private boolean autoScaled;
+
+  final private float minRed;
+
+  final private float minGreen;
+
+  final private float minBlue;
+
+  final private float deltaRed;
+
+  final private float deltaGreen;
+
+  final private float deltaBlue;
+
+  /**
+   * Parses a Jalview features file format colour descriptor
+   * [label|][mincolour|maxcolour
+   * |[absolute|]minvalue|maxvalue|thresholdtype|thresholdvalue] Examples:
+   * <ul>
+   * <li>red</li>
+   * <li>a28bbb</li>
+   * <li>25,125,213</li>
+   * <li>label</li>
+   * <li>label|||0.0|0.0|above|12.5</li>
+   * <li>label|||0.0|0.0|below|12.5</li>
+   * <li>red|green|12.0|26.0|none</li>
+   * <li>a28bbb|3eb555|12.0|26.0|above|12.5</li>
+   * <li>a28bbb|3eb555|abso|12.0|26.0|below|12.5</li>
+   * </ul>
+   * 
+   * @param descriptor
+   * @return
+   * @throws IllegalArgumentException
+   *           if not parseable
+   */
+  public static FeatureColour parseJalviewFeatureColour(String descriptor)
+  {
+    StringTokenizer gcol = new StringTokenizer(descriptor, "|", true);
+    float min = Float.MIN_VALUE;
+    float max = Float.MAX_VALUE;
+    boolean labelColour = false;
+
+    String mincol = gcol.nextToken();
+    if (mincol == "|")
+    {
+      throw new IllegalArgumentException(
+              "Expected either 'label' or a colour specification in the line: "
+                      + descriptor);
+    }
+    String maxcol = null;
+    if (mincol.toLowerCase().indexOf("label") == 0)
+    {
+      labelColour = true;
+      mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null);
+      // skip '|'
+      mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null);
+    }
+
+    if (!labelColour && !gcol.hasMoreTokens())
+    {
+      /*
+       * only a simple colour specification - parse it
+       */
+      Color colour = UserColourScheme.getColourFromString(descriptor);
+      if (colour == null)
+      {
+        throw new IllegalArgumentException("Invalid colour descriptor: "
+                + descriptor);
+      }
+      return new FeatureColour(colour);
+    }
+
+    /*
+     * autoScaled == true: colours range over actual score range
+     * autoScaled == false ('abso'): colours range over min/max range
+     */
+    boolean autoScaled = true;
+    String tok = null, minval, maxval;
+    if (mincol != null)
+    {
+      // at least four more tokens
+      if (mincol.equals("|"))
+      {
+        mincol = "";
+      }
+      else
+      {
+        gcol.nextToken(); // skip next '|'
+      }
+      maxcol = gcol.nextToken();
+      if (maxcol.equals("|"))
+      {
+        maxcol = "";
+      }
+      else
+      {
+        gcol.nextToken(); // skip next '|'
+      }
+      tok = gcol.nextToken();
+      gcol.nextToken(); // skip next '|'
+      if (tok.toLowerCase().startsWith("abso"))
+      {
+        minval = gcol.nextToken();
+        gcol.nextToken(); // skip next '|'
+        autoScaled = false;
+      }
+      else
+      {
+        minval = tok;
+      }
+      maxval = gcol.nextToken();
+      if (gcol.hasMoreTokens())
+      {
+        gcol.nextToken(); // skip next '|'
+      }
+      try
+      {
+        if (minval.length() > 0)
+        {
+          min = new Float(minval).floatValue();
+        }
+      } catch (Exception e)
+      {
+        throw new IllegalArgumentException(
+                "Couldn't parse the minimum value for graduated colour ("
+                        + descriptor + ")");
+      }
+      try
+      {
+        if (maxval.length() > 0)
+        {
+          max = new Float(maxval).floatValue();
+        }
+      } catch (Exception e)
+      {
+        throw new IllegalArgumentException(
+                "Couldn't parse the maximum value for graduated colour ("
+                        + descriptor + ")");
+      }
+    }
+    else
+    {
+      // add in some dummy min/max colours for the label-only
+      // colourscheme.
+      mincol = "FFFFFF";
+      maxcol = "000000";
+    }
+
+    /*
+     * construct the FeatureColour
+     */
+    FeatureColour featureColour;
+    try
+    {
+      featureColour = new FeatureColour(
+              new UserColourScheme(mincol).findColour('A'),
+              new UserColourScheme(maxcol).findColour('A'), min, max);
+      featureColour.setColourByLabel(labelColour);
+      featureColour.setAutoScaled(autoScaled);
+      // add in any additional parameters
+      String ttype = null, tval = null;
+      if (gcol.hasMoreTokens())
+      {
+        // threshold type and possibly a threshold value
+        ttype = gcol.nextToken();
+        if (ttype.toLowerCase().startsWith("below"))
+        {
+          featureColour.setBelowThreshold(true);
+        }
+        else if (ttype.toLowerCase().startsWith("above"))
+        {
+          featureColour.setAboveThreshold(true);
+        }
+        else
+        {
+          if (!ttype.toLowerCase().startsWith("no"))
+          {
+            System.err.println("Ignoring unrecognised threshold type : "
+                    + ttype);
+          }
+        }
+      }
+      if (featureColour.hasThreshold())
+      {
+        try
+        {
+          gcol.nextToken();
+          tval = gcol.nextToken();
+          featureColour.setThreshold(new Float(tval).floatValue());
+        } catch (Exception e)
+        {
+          System.err.println("Couldn't parse threshold value as a float: ("
+                  + tval + ")");
+        }
+      }
+      if (gcol.hasMoreTokens())
+      {
+        System.err
+                .println("Ignoring additional tokens in parameters in graduated colour specification\n");
+        while (gcol.hasMoreTokens())
+        {
+          System.err.println("|" + gcol.nextToken());
+        }
+        System.err.println("\n");
+      }
+      return featureColour;
+    } catch (Exception e)
+    {
+      throw new IllegalArgumentException(e.getMessage());
+    }
+  }
+
+  /**
+   * Default constructor
+   */
+  public FeatureColour()
+  {
+    this((Color) null);
+  }
+
+  /**
+   * Constructor given a simple colour
+   * 
+   * @param c
+   */
+  public FeatureColour(Color c)
+  {
+    minColour = Color.WHITE;
+    maxColour = Color.BLACK;
+    minRed = 0f;
+    minGreen = 0f;
+    minBlue = 0f;
+    deltaRed = 0f;
+    deltaGreen = 0f;
+    deltaBlue = 0f;
+    colour = c;
+  }
+
+  /**
+   * Constructor given a colour range and a score range
+   * 
+   * @param low
+   * @param high
+   * @param min
+   * @param max
+   */
+  public FeatureColour(Color low, Color high, float min, float max)
+  {
+    graduatedColour = true;
+    colour = null;
+    minColour = low;
+    maxColour = high;
+    threshold = Float.NaN;
+    isHighToLow = min >= max;
+    minRed = low.getRed() / 255f;
+    minGreen = low.getGreen() / 255f;
+    minBlue = low.getBlue() / 255f;
+    deltaRed = (high.getRed() / 255f) - minRed;
+    deltaGreen = (high.getGreen() / 255f) - minGreen;
+    deltaBlue = (high.getBlue() / 255f) - minBlue;
+    if (isHighToLow)
+    {
+      base = max;
+      range = min - max;
+    }
+    else
+    {
+      base = min;
+      range = max - min;
+    }
+  }
+
+  /**
+   * Copy constructor
+   * 
+   * @param fc
+   */
+  public FeatureColour(FeatureColour fc)
+  {
+    colour = fc.colour;
+    minColour = fc.minColour;
+    maxColour = fc.maxColour;
+    minRed = fc.minRed;
+    minGreen = fc.minGreen;
+    minBlue = fc.minBlue;
+    deltaRed = fc.deltaRed;
+    deltaGreen = fc.deltaGreen;
+    deltaBlue = fc.deltaBlue;
+    base = fc.base;
+    range = fc.range;
+    isHighToLow = fc.isHighToLow;
+    setAboveThreshold(fc.isAboveThreshold());
+    setBelowThreshold(fc.isBelowThreshold());
+    setThreshold(fc.getThreshold());
+    setAutoScaled(fc.isAutoScaled());
+    setColourByLabel(fc.isColourByLabel());
+  }
+  
+  /**
+   * Copy constructor with new min/max ranges
+   * @param fc
+   * @param min
+   * @param max
+   */
+  public FeatureColour(FeatureColour fc, float min, float max)
+  {
+    this(fc);
+    graduatedColour = true;
+    updateBounds(min, max);
+  }
+
+  @Override
+  public boolean isGraduatedColour()
+  {
+    return graduatedColour;
+  }
+
+  /**
+   * Sets the 'graduated colour' flag. If true, also sets 'colour by label' to
+   * false.
+   */
+  void setGraduatedColour(boolean b)
+  {
+    graduatedColour = b;
+    if (b)
+    {
+      setColourByLabel(false);
+    }
+  }
+
+  @Override
+  public Color getColour()
+  {
+    return colour;
+  }
+
+  @Override
+  public Color getMinColour()
+  {
+    return minColour;
+  }
+
+  @Override
+  public Color getMaxColour()
+  {
+    return maxColour;
+  }
+
+  @Override
+  public boolean isColourByLabel()
+  {
+    return colourByLabel;
+  }
+
+  /**
+   * Sets the 'colour by label' flag. If true, also sets 'graduated colour' to
+   * false.
+   */
+  @Override
+  public void setColourByLabel(boolean b)
+  {
+    colourByLabel = b;
+    if (b)
+    {
+      setGraduatedColour(false);
+    }
+  }
+  @Override
+  public boolean isBelowThreshold()
+  {
+    return belowThreshold;
+  }
+
+  @Override
+  public void setBelowThreshold(boolean b)
+  {
+    belowThreshold = b;
+    if (b)
+    {
+      setAboveThreshold(false);
+    }
+  }
+
+  @Override
+  public boolean isAboveThreshold()
+  {
+    return aboveThreshold;
+  }
+
+  @Override
+  public void setAboveThreshold(boolean b)
+  {
+    aboveThreshold = b;
+    if (b)
+    {
+      setBelowThreshold(false);
+    }
+  }
+
+  @Override
+  public boolean isThresholdMinMax()
+  {
+    return thresholdIsMinOrMax;
+  }
+
+  @Override
+  public void setThresholdMinMax(boolean b)
+  {
+    thresholdIsMinOrMax = b;
+  }
+
+  @Override
+  public float getThreshold()
+  {
+    return threshold;
+  }
+
+  @Override
+  public void setThreshold(float f)
+  {
+    threshold = f;
+  }
+
+  @Override
+  public boolean isAutoScaled()
+  {
+    return autoScaled;
+  }
+
+  @Override
+  public void setAutoScaled(boolean b)
+  {
+    this.autoScaled = b;
+  }
+
+  /**
+   * Updates the base and range appropriately for the given minmax range
+   * 
+   * @param min
+   * @param max
+   */
+  @Override
+  public void updateBounds(float min, float max)
+  {
+    if (max < min)
+    {
+      base = max;
+      range = min - max;
+      isHighToLow = true;
+    }
+    else
+    {
+      base = min;
+      range = max - min;
+      isHighToLow = false;
+    }
+  }
+
+  /**
+   * Returns the colour for the given instance of the feature. This may be a
+   * simple colour, a colour generated from the feature description (if
+   * isColourByLabel()), or a colour derived from the feature score (if
+   * isGraduatedColour()).
+   * 
+   * @param feature
+   * @return
+   */
+  @Override
+  public Color getColor(SequenceFeature feature)
+  {
+    if (isColourByLabel())
+    {
+      return UserColourScheme
+              .createColourFromName(feature.getDescription());
+    }
+
+    if (!isGraduatedColour())
+    {
+      return getColour();
+    }
+
+    // todo should we check for above/below threshold here?
+    if (range == 0.0)
+    {
+      return getMaxColour();
+    }
+    float scr = feature.getScore();
+    if (Float.isNaN(scr))
+    {
+      return getMinColour();
+    }
+    float scl = (scr - base) / range;
+    if (isHighToLow)
+    {
+      scl = -scl;
+    }
+    if (scl < 0f)
+    {
+      scl = 0f;
+    }
+    if (scl > 1f)
+    {
+      scl = 1f;
+    }
+    return new Color(minRed + scl * deltaRed, minGreen + scl * deltaGreen, minBlue + scl * deltaBlue);
+  }
+
+  /**
+   * Returns the maximum score of the graduated colour range
+   * 
+   * @return
+   */
+  @Override
+  public float getMax()
+  {
+    // regenerate the original values passed in to the constructor
+    return (isHighToLow) ? base : (base + range);
+  }
+
+  /**
+   * Returns the minimum score of the graduated colour range
+   * 
+   * @return
+   */
+  @Override
+  public float getMin()
+  {
+    // regenerate the original value passed in to the constructor
+    return (isHighToLow) ? (base + range) : base;
+  }
+
+  /**
+   * Answers true if the feature has a simple colour, or is coloured by label,
+   * or has a graduated colour and the score of this feature instance is within
+   * the range to render (if any), i.e. does not lie below or above any
+   * threshold set.
+   * 
+   * @param feature
+   * @return
+   */
+  @Override
+  public boolean isColored(SequenceFeature feature)
+  {
+    if (isColourByLabel() || !isGraduatedColour())
+    {
+      return true;
+    }
+
+    float val = feature.getScore();
+    if (Float.isNaN(val))
+    {
+      return true;
+    }
+    if (Float.isNaN(this.threshold))
+    {
+      return true;
+    }
+
+    if (isAboveThreshold() && val <= threshold)
+    {
+      return false;
+    }
+    if (isBelowThreshold() && val >= threshold)
+    {
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public boolean isSimpleColour()
+  {
+    return (!isColourByLabel() && !isGraduatedColour());
+  }
+
+  @Override
+  public boolean hasThreshold()
+  {
+    return isAboveThreshold() || isBelowThreshold();
+  }
+
+  @Override
+  public String toJalviewFormat(String featureType)
+  {
+    String colourString = null;
+    if (isSimpleColour())
+    {
+      colourString = Format.getHexString(getColour());
+    }
+    else
+    {
+      StringBuilder sb = new StringBuilder(32);
+      if (isColourByLabel())
+      {
+        sb.append("label");
+        if (hasThreshold())
+        {
+          sb.append(BAR).append(BAR).append(BAR);
+        }
+      }
+      if (isGraduatedColour())
+      {
+        sb.append(Format.getHexString(getMinColour())).append(BAR);
+        sb.append(Format.getHexString(getMaxColour())).append(BAR);
+        if (!isAutoScaled())
+        {
+          sb.append("abso").append(BAR);
+        }
+      }
+      if (hasThreshold() || isGraduatedColour())
+      {
+        sb.append(getMin()).append(BAR);
+        sb.append(getMax()).append(BAR);
+        if (isBelowThreshold())
+        {
+          sb.append("below").append(BAR).append(getThreshold());
+        }
+        else if (isAboveThreshold())
+        {
+          sb.append("above").append(BAR).append(getThreshold());
+        }
+        else
+        {
+          sb.append("none");
+        }
+      }
+      colourString = sb.toString();
+    }
+    return String.format("%s\t%s", featureType, colourString);
+  }
+
+}
diff --git a/src/jalview/schemes/FeatureColourAdapter.java b/src/jalview/schemes/FeatureColourAdapter.java
deleted file mode 100644 (file)
index a86bee4..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package jalview.schemes;
-
-import jalview.api.FeatureColourI;
-
-import java.awt.Color;
-
-/**
- * A convenience class with implementations of FeatureColourI methods. Override
- * methods as required in subclasses.
- */
-public class FeatureColourAdapter implements FeatureColourI
-{
-  @Override
-  public boolean isGraduatedColour()
-  {
-    return isColourByLabel() || isAboveThreshold() || isBelowThreshold();
-  }
-
-  @Override
-  public Color getColour()
-  {
-    return Color.BLACK;
-  }
-
-  @Override
-  public Color getMinColour()
-  {
-    return Color.WHITE;
-  }
-
-  @Override
-  public Color getMaxColour()
-  {
-    return Color.BLACK;
-  }
-
-  @Override
-  public boolean isColourByLabel()
-  {
-    return false;
-  }
-
-  @Override
-  public boolean isBelowThreshold()
-  {
-    return false;
-  }
-
-  @Override
-  public boolean isAboveThreshold()
-  {
-    return false;
-  }
-
-  @Override
-  public boolean isThresholdMinMax()
-  {
-    return false;
-  }
-
-  @Override
-  public float getThreshold()
-  {
-    return 0f;
-  }
-
-  @Override
-  public boolean isLowToHigh()
-  {
-    return true;
-  }
-
-}
diff --git a/src/jalview/schemes/GraduatedColor.java b/src/jalview/schemes/GraduatedColor.java
deleted file mode 100644 (file)
index 2d1c572..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
- * PURPOSE.  See the GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.schemes;
-
-import jalview.api.FeatureColourI;
-import jalview.datamodel.SequenceFeature;
-
-import java.awt.Color;
-
-/**
- * Value and/or thresholded colour scale used for colouring by annotation and
- * feature score
- * 
- * @author JimP
- * 
- */
-public class GraduatedColor
-{
-  int thresholdState = AnnotationColourGradient.NO_THRESHOLD; // or
-                                                              // ABOVE_THRESHOLD
-                                                              // or
-                                                              // BELOW_THRESHOLD
-
-  float lr, lg, lb, dr, dg, db;
-
-  /**
-   * linear scaling parameters, base, minimum colour threshold, range of linear
-   * scale from lower to upper
-   */
-  float base, range, thrsh;
-
-  /**
-   * when true, colour from u to u-d rather than u to u+d
-   */
-  boolean tolow = false;
-
-  /**
-   * when false, min/max range has been manually set so should not be
-   * dynamically adjusted.
-   */
-  boolean autoScale = true;
-
-  /**
-   * construct a graduatedColor object from simple parameters
-   * 
-   * @param low
-   * @param high
-   * @param min
-   * @param max
-   *          color low->high from min->max
-   */
-  public GraduatedColor(Color low, Color high, float min, float max)
-  {
-    thrsh = Float.NaN;
-    tolow = min >= max;
-    lr = low.getRed() / 255f;
-    lg = low.getGreen() / 255f;
-    lb = low.getBlue() / 255f;
-    dr = (high.getRed() / 255f) - lr;
-    dg = (high.getGreen() / 255f) - lg;
-    db = (high.getBlue() / 255f) - lb;
-    if (tolow)
-    {
-      base = max;
-      range = min - max;
-    }
-    else
-    {
-      base = min;
-      range = max - min;
-    }
-  }
-
-  public GraduatedColor(GraduatedColor oldcs)
-  {
-    lr = oldcs.lr;
-    lg = oldcs.lg;
-    lb = oldcs.lb;
-    dr = oldcs.dr;
-    dg = oldcs.dg;
-    db = oldcs.db;
-    base = oldcs.base;
-    range = oldcs.range;
-    tolow = oldcs.tolow;
-    thresholdState = oldcs.thresholdState;
-    thrsh = oldcs.thrsh;
-    autoScale = oldcs.autoScale;
-    colourByLabel = oldcs.colourByLabel;
-  }
-
-  /**
-   * make a new gradient from an old one with a different scale range
-   * 
-   * @param oldcs
-   * @param min
-   * @param max
-   */
-  public GraduatedColor(GraduatedColor oldcs, float min, float max)
-  {
-    this(oldcs);
-    updateBounds(min, max);
-  }
-
-  public GraduatedColor(FeatureColourI col)
-  {
-    setColourByLabel(col.isColourByLabel());
-  }
-
-  public Color getMinColor()
-  {
-    return new Color(lr, lg, lb);
-  }
-
-  public Color getMaxColor()
-  {
-    return new Color(lr + dr, lg + dg, lb + db);
-  }
-
-  /**
-   * 
-   * @return true if original min/max scale was from high to low
-   */
-  public boolean getTolow()
-  {
-    return tolow;
-  }
-
-  public void setTolow(boolean tolower)
-  {
-    tolow = tolower;
-  }
-
-  public boolean isColored(SequenceFeature feature)
-  {
-    float val = feature.getScore();
-    if (Float.isNaN(val))
-    {
-      return true;
-    }
-    if (this.thresholdState == AnnotationColourGradient.NO_THRESHOLD)
-    {
-      return true;
-    }
-    if (Float.isNaN(this.thrsh))
-    {
-      return true;
-    }
-    boolean rtn = thresholdState == AnnotationColourGradient.ABOVE_THRESHOLD;
-    if (val <= thrsh)
-    {
-      return !rtn; // ? !tolow : tolow;
-    }
-    else
-    {
-      return rtn; // ? tolow : !tolow;
-    }
-  }
-
-  /**
-   * default implementor of a getColourFromString method. TODO: abstract an
-   * interface enabling pluggable colour from string
-   */
-  private UserColourScheme ucs = null;
-
-  private boolean colourByLabel = false;
-
-  /**
-   * 
-   * @return true if colourByLabel style is set
-   */
-  public boolean isColourByLabel()
-  {
-    return colourByLabel;
-  }
-
-  /**
-   * @param colourByLabel
-   *          the colourByLabel to set
-   */
-  public void setColourByLabel(boolean colourByLabel)
-  {
-    this.colourByLabel = colourByLabel;
-  }
-
-  public Color findColor(SequenceFeature feature)
-  {
-    if (colourByLabel)
-    {
-      // TODO: allow user defined feature label colourschemes. Colour space is
-      // {type,regex,%anytype%}x{description string, regex, keyword}
-      if (ucs == null)
-      {
-        ucs = new UserColourScheme();
-      }
-      return ucs.createColourFromName(feature.getDescription());
-    }
-    if (range == 0.0)
-    {
-      return getMaxColor();
-    }
-    float scr = feature.getScore();
-    if (Float.isNaN(scr))
-    {
-      return getMinColor();
-    }
-    float scl = (scr - base) / range;
-    if (tolow)
-    {
-      scl = -scl;
-    }
-    if (scl < 0f)
-    {
-      scl = 0f;
-    }
-    if (scl > 1f)
-    {
-      scl = 1f;
-    }
-    return new Color(lr + scl * dr, lg + scl * dg, lb + scl * db);
-  }
-
-  public void setThresh(float value)
-  {
-    thrsh = value;
-  }
-
-  public float getThresh()
-  {
-    return thrsh;
-  }
-
-  public void setThreshType(int aboveThreshold)
-  {
-    thresholdState = aboveThreshold;
-  }
-
-  public int getThreshType()
-  {
-    return thresholdState;
-  }
-
-  public float getMax()
-  {
-    // regenerate the original values passed in to the constructor
-    return (tolow) ? base : (base + range);
-  }
-
-  public float getMin()
-  {
-    // regenerate the original value passed in to the constructor
-    return (tolow) ? (base + range) : base;
-  }
-
-  public boolean isAutoScale()
-  {
-    return autoScale;
-  }
-
-  public void setAutoScaled(boolean autoscale)
-  {
-    autoScale = autoscale;
-  }
-
-  /**
-   * update the base and range appropriatly for the given minmax range
-   * 
-   * @param a
-   *          float[] {min,max} array containing minmax range for the associated
-   *          score values
-   */
-  public void updateBounds(float min, float max)
-  {
-    if (max < min)
-    {
-      base = max;
-      range = min - max;
-      tolow = true;
-    }
-    else
-    {
-      base = min;
-      range = max - min;
-      tolow = false;
-    }
-  }
-}
index b1e4d58..9ae14ca 100755 (executable)
@@ -101,6 +101,10 @@ public class UserColourScheme extends ResidueColourScheme
 
   public static Color getColourFromString(String colour)
   {
+    if (colour == null)
+    {
+      return null;
+    }
     colour = colour.trim();
 
     Color col = null;
@@ -136,7 +140,7 @@ public class UserColourScheme extends ResidueColourScheme
 
   }
 
-  public Color createColourFromName(String name)
+  public static Color createColourFromName(String name)
   {
     int r, g, b;
 
index 33c566d..fb96b22 100644 (file)
@@ -501,7 +501,8 @@ public class StructureSelectionManager
       if (isMapUsingSIFTs)
       {
         setProgressBar(null);
-        setProgressBar("Obtaining mapping with SIFTS");
+        setProgressBar(MessageManager
+                .getString("status.obtaining_mapping_with_sifts"));
         jalview.datamodel.Mapping sqmpping = maxAlignseq
                 .getMappingFromS1(false);
         if (targetChainId != null && !targetChainId.trim().isEmpty())
@@ -559,7 +560,8 @@ public class StructureSelectionManager
       else
       {
         setProgressBar(null);
-        setProgressBar("Obtaining mapping with NW alignment");
+        setProgressBar(MessageManager
+                .getString("status.obtaining_mapping_with_nw_alignment"));
         seqToStrucMapping.add(getNWMappings(seq, pdbFile, maxChainId,
                 maxChain, pdb, maxAlignseq));
       }
index 72fa605..fcea21d 100755 (executable)
@@ -54,6 +54,12 @@ public class ImageMaker
 
   TYPE type;
 
+  private IProgressIndicator pIndicator;
+
+  private long pSessionId;
+
+  private boolean headless;
+
   public enum TYPE
   {
     EPS("EPS", MessageManager.getString("label.eps_file"), getEPSChooser()), PNG(
@@ -94,17 +100,14 @@ public class ImageMaker
           int height, File file, String fileTitle,
           IProgressIndicator pIndicator, long pSessionId, boolean headless)
   {
+    this.pIndicator = pIndicator;
     this.type = type;
-
+    this.pSessionId = pSessionId;
+    this.headless = headless;
     if (file == null)
     {
-      if (pIndicator != null && !headless)
-      {
-        pIndicator.setProgressBar(
-                MessageManager.formatMessage(
-                        "status.waiting_for_user_to_select_output_file",
-                        type.name), pSessionId);
-      }
+      setProgressMessage(MessageManager.formatMessage(
+              "status.waiting_for_user_to_select_output_file", type.name));
       JalviewFileChooser chooser;
       chooser = type.getChooser();
       chooser.setFileView(new jalview.io.JalviewFileView());
@@ -120,12 +123,8 @@ public class ImageMaker
       }
       else
       {
-        if (pIndicator != null && !headless)
-        {
-          pIndicator.setProgressBar(MessageManager.formatMessage(
-                  "status.cancelled_image_export_operation", type.name),
-                  pSessionId);
-        }
+        setProgressMessage(MessageManager.formatMessage(
+                "status.cancelled_image_export_operation", type.name));
       }
     }
 
@@ -134,6 +133,9 @@ public class ImageMaker
       try
       {
         out = new FileOutputStream(file);
+        setProgressMessage(null);
+        setProgressMessage(MessageManager.formatMessage(
+                "status.exporting_alignment_as_x_file", type.getName()));
         if (type == TYPE.SVG)
         {
           setupSVG(width, height, fileTitle);
@@ -146,19 +148,13 @@ public class ImageMaker
         {
           setupPNG(width, height);
         }
-        if (pIndicator != null && !headless)
-        {
-          pIndicator.setProgressBar(
-MessageManager.formatMessage(
-                  "status.export_complete", type.getName()),
-                  pSessionId);
-        }
+
       } catch (Exception ex)
       {
         System.out.println("Error creating " + type.getName() + " file.");
 
-        pIndicator.setProgressBar(MessageManager.formatMessage(
-                "info.error_creating_file", type.getName()), pSessionId);
+        setProgressMessage(MessageManager.formatMessage(
+                "info.error_creating_file", type.getName()));
       }
     }
   }
@@ -214,6 +210,8 @@ MessageManager.formatMessage(
 
       if (renderStyle == null || eps.cancelled)
       {
+        setProgressMessage(MessageManager.formatMessage(
+                "status.cancelled_image_export_operation", "EPS"));
         return;
       }
     }
@@ -233,6 +231,8 @@ MessageManager.formatMessage(
       pg.setAccurateTextMode(accurateText);
 
       graphics = pg;
+      setProgressMessage(MessageManager.formatMessage(
+              "status.export_complete", type.getName()));
     } catch (Exception ex)
     {
     }
@@ -245,6 +245,8 @@ MessageManager.formatMessage(
     Graphics2D ig2 = (Graphics2D) graphics;
     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
             RenderingHints.VALUE_ANTIALIAS_ON);
+    setProgressMessage(MessageManager.formatMessage(
+            "status.export_complete", type.getName()));
 
   }
 
@@ -268,6 +270,8 @@ MessageManager.formatMessage(
 
       if (renderStyle == null || svgOption.cancelled)
       {
+        setProgressMessage(MessageManager.formatMessage(
+                "status.cancelled_image_export_operation", "SVG"));
         return;
       }
     }
@@ -278,6 +282,8 @@ MessageManager.formatMessage(
               SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
     }
 
+    setProgressMessage(MessageManager.formatMessage(
+            "status.export_complete", type.getName()));
     graphics = g2;
   }
 
@@ -307,6 +313,14 @@ MessageManager.formatMessage(
             "Encapsulated Postscript");
   }
 
+  private void setProgressMessage(String message)
+  {
+    if (pIndicator != null && !headless)
+    {
+      pIndicator.setProgressBar(message, pSessionId);
+    }
+  }
+
   static JalviewFileChooser getSVGChooser()
   {
     if (Jalview.isHeadlessMode())
index ec2c591..a4e4348 100644 (file)
@@ -27,7 +27,8 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.seqfeatures.FeatureRenderer;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.UserColourScheme;
 import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.Color;
@@ -52,28 +53,19 @@ public abstract class FeatureRendererModel implements
    */
   protected float transparency = 1.0f;
 
-  protected Map<String, Object> featureColours = new ConcurrentHashMap<String, Object>();
+  protected Map<String, FeatureColourI> featureColours = new ConcurrentHashMap<String, FeatureColourI>();
 
   protected Map<String, Boolean> featureGroups = new ConcurrentHashMap<String, Boolean>();
 
-  protected Object currentColour;
-
-  /*
-   * feature types in ordering of rendering, where last means on top
-   */
   protected String[] renderOrder;
 
+  Map<String, Float> featureOrder = null;
+
   protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
           this);
 
   protected AlignmentViewport av;
 
-  /*
-   * map holds per feature type, {{min, max}, {min, max}} feature score
-   * values for positional and non-positional features respectively
-   */
-  private Map<String, float[][]> minmax = new Hashtable<String, float[][]>();
-
   @Override
   public AlignViewportI getViewport()
   {
@@ -200,6 +192,8 @@ public abstract class FeatureRendererModel implements
     renderOrder = neworder;
   }
 
+  protected Map<String, float[][]> minmax = new Hashtable<String, float[][]>();
+
   public Map<String, float[][]> getMinMax()
   {
     return minmax;
@@ -449,7 +443,6 @@ public abstract class FeatureRendererModel implements
     List<String> allfeatures = new ArrayList<String>(allFeatures);
     String[] oldRender = renderOrder;
     renderOrder = new String[allfeatures.size()];
-    Object mmrange, fc = null;
     boolean initOrders = (featureOrder == null);
     int opos = 0;
     if (oldRender != null && oldRender.length > 0)
@@ -469,16 +462,13 @@ public abstract class FeatureRendererModel implements
             allfeatures.remove(oldRender[j]);
             if (minmax != null)
             {
-              mmrange = minmax.get(oldRender[j]);
+              float[][] mmrange = minmax.get(oldRender[j]);
               if (mmrange != null)
               {
-                fc = featureColours.get(oldRender[j]);
-                if (fc != null && fc instanceof GraduatedColor
-                        && ((GraduatedColor) fc).isAutoScale())
+                FeatureColourI fc = featureColours.get(oldRender[j]);
+                if (fc != null && !fc.isSimpleColour() && fc.isAutoScaled())
                 {
-                  ((GraduatedColor) fc).updateBounds(
-                          ((float[][]) mmrange)[0][0],
-                          ((float[][]) mmrange)[0][1]);
+                  fc.updateBounds(mmrange[0][0], mmrange[0][1]);
                 }
               }
             }
@@ -502,15 +492,13 @@ public abstract class FeatureRendererModel implements
       if (minmax != null)
       {
         // update from new features minmax if necessary
-        mmrange = minmax.get(newf[i]);
+        float[][] mmrange = minmax.get(newf[i]);
         if (mmrange != null)
         {
-          fc = featureColours.get(newf[i]);
-          if (fc != null && fc instanceof GraduatedColor
-                  && ((GraduatedColor) fc).isAutoScale())
+          FeatureColourI fc = featureColours.get(newf[i]);
+          if (fc != null && !fc.isSimpleColour() && fc.isAutoScaled())
           {
-            ((GraduatedColor) fc).updateBounds(((float[][]) mmrange)[0][0],
-                    ((float[][]) mmrange)[0][1]);
+            fc.updateBounds(mmrange[0][0], mmrange[0][1]);
           }
         }
       }
@@ -522,7 +510,7 @@ public abstract class FeatureRendererModel implements
         setOrder(newf[i], i / (float) denom);
       }
       // set order from newly found feature from persisted ordering.
-      sortOrder[i] = 2 - ((Float) featureOrder.get(newf[i])).floatValue();
+      sortOrder[i] = 2 - featureOrder.get(newf[i]).floatValue();
       if (i < iSize)
       {
         // only sort if we need to
@@ -540,22 +528,20 @@ public abstract class FeatureRendererModel implements
 
   /**
    * get a feature style object for the given type string. Creates a
-   * java.awt.Color for a featureType with no existing colourscheme. TODO:
-   * replace return type with object implementing standard abstract colour/style
-   * interface
+   * java.awt.Color for a featureType with no existing colourscheme.
    * 
    * @param featureType
-   * @return java.awt.Color or GraduatedColor
+   * @return
    */
   @Override
-  public Object getFeatureStyle(String featureType)
+  public FeatureColourI getFeatureStyle(String featureType)
   {
-    Object fc = featureColours.get(featureType);
+    FeatureColourI fc = featureColours.get(featureType);
     if (fc == null)
     {
-      jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
-      Color col = ucs.createColourFromName(featureType);
-      featureColours.put(featureType, fc = col);
+      Color col = UserColourScheme.createColourFromName(featureType);
+      fc = new FeatureColour(col);
+      featureColours.put(featureType, fc);
     }
     return fc;
   }
@@ -569,33 +555,14 @@ public abstract class FeatureRendererModel implements
    */
   public Color getColour(SequenceFeature feature)
   {
-    Object fc = getFeatureStyle(feature.getType());
-    if (fc instanceof Color)
-    {
-      return (Color) fc;
-    }
-    else
-    {
-      if (fc instanceof GraduatedColor)
-      {
-        return ((GraduatedColor) fc).findColor(feature);
-      }
-    }
-    throw new Error("Implementation Error: Unrecognised render object "
-            + fc.getClass() + " for features of type " + feature.getType());
+    FeatureColourI fc = getFeatureStyle(feature.getType());
+    return fc.getColor(feature);
   }
 
   protected boolean showFeature(SequenceFeature sequenceFeature)
   {
-    Object fc = getFeatureStyle(sequenceFeature.type);
-    if (fc instanceof GraduatedColor)
-    {
-      return ((GraduatedColor) fc).isColored(sequenceFeature);
-    }
-    else
-    {
-      return true;
-    }
+    FeatureColourI fc = getFeatureStyle(sequenceFeature.type);
+    return fc.isColored(sequenceFeature);
   }
 
   protected boolean showFeatureOfType(String type)
@@ -604,26 +571,9 @@ public abstract class FeatureRendererModel implements
   }
 
   @Override
-  public void setColour(String featureType, Object col)
+  public void setColour(String featureType, FeatureColourI col)
   {
-    // overwrite
-    // Color _col = (col instanceof Color) ? ((Color) col) : (col instanceof
-    // GraduatedColor) ? ((GraduatedColor) col).getMaxColor() : null;
-    // Object c = featureColours.get(featureType);
-    // if (c == null || c instanceof Color || (c instanceof GraduatedColor &&
-    // !((GraduatedColor)c).getMaxColor().equals(_col)))
-    if (col instanceof FeatureColourI)
-    {
-      if (((FeatureColourI) col).isGraduatedColour())
-      {
-        col = new GraduatedColor((FeatureColourI) col);
-      }
-      else
-      {
-        col = ((FeatureColourI) col).getColour();
-      }
-    }
-      featureColours.put(featureType, col);
+     featureColours.put(featureType, col);
   }
 
   public void setTransparency(float value)
@@ -636,8 +586,6 @@ public abstract class FeatureRendererModel implements
     return transparency;
   }
 
-  Map featureOrder = null;
-
   /**
    * analogous to colour - store a normalized ordering for all feature types in
    * this rendering context.
@@ -652,7 +600,7 @@ public abstract class FeatureRendererModel implements
   {
     if (featureOrder == null)
     {
-      featureOrder = new Hashtable();
+      featureOrder = new Hashtable<String, Float>();
     }
     featureOrder.put(type, new Float(position));
     return position;
@@ -670,14 +618,14 @@ public abstract class FeatureRendererModel implements
     {
       if (featureOrder.containsKey(type))
       {
-        return ((Float) featureOrder.get(type)).floatValue();
+        return featureOrder.get(type).floatValue();
       }
     }
     return -1;
   }
 
   @Override
-  public Map<String, Object> getFeatureColours()
+  public Map<String, FeatureColourI> getFeatureColours()
   {
     return featureColours;
   }
@@ -710,7 +658,7 @@ public abstract class FeatureRendererModel implements
      * note visible feature ordering and colours before update
      */
     List<String> visibleFeatures = getDisplayedFeatureTypes();
-    Map<String, Object> visibleColours = new HashMap<String, Object>(
+    Map<String, FeatureColourI> visibleColours = new HashMap<String, FeatureColourI>(
             getFeatureColours());
 
     FeaturesDisplayedI av_featuresdisplayed = null;
@@ -743,8 +691,7 @@ public abstract class FeatureRendererModel implements
       for (int i = 0; i < data.length; i++)
       {
         String type = data[i][0].toString();
-        setColour(type, data[i][1]); // todo : typesafety - feature color
-        // interface object
+        setColour(type, (FeatureColourI) data[i][1]);
         if (((Boolean) data[i][2]).booleanValue())
         {
           av_featuresdisplayed.setVisible(type);
@@ -869,9 +816,9 @@ public abstract class FeatureRendererModel implements
   {
     if (featureGroups != null)
     {
-      ArrayList gp = new ArrayList();
+      List<String> gp = new ArrayList<String>();
 
-      for (Object grp : featureGroups.keySet())
+      for (String grp : featureGroups.keySet())
       {
         Boolean state = featureGroups.get(grp);
         if (state.booleanValue() == visible)
@@ -913,19 +860,19 @@ public abstract class FeatureRendererModel implements
   }
 
   @Override
-  public Hashtable getDisplayedFeatureCols()
+  public Map<String, FeatureColourI> getDisplayedFeatureCols()
   {
-    Hashtable fcols = new Hashtable();
+    Map<String, FeatureColourI> fcols = new Hashtable<String, FeatureColourI>();
     if (getViewport().getFeaturesDisplayed() == null)
     {
       return fcols;
     }
-    Iterator<String> en = getViewport().getFeaturesDisplayed()
+    Iterator<String> features = getViewport().getFeaturesDisplayed()
             .getVisibleFeatures();
-    while (en.hasNext())
+    while (features.hasNext())
     {
-      String col = en.next();
-      fcols.put(col, featureColours.get(col));
+      String feature = features.next();
+      fcols.put(feature, getFeatureStyle(feature));
     }
     return fcols;
   }
index 1985b6d..dc2ae11 100644 (file)
  */
 package jalview.viewmodel.seqfeatures;
 
-import jalview.schemes.GraduatedColor;
+import jalview.api.FeatureColourI;
+import jalview.schemes.FeatureColour;
 
 import java.util.Arrays;
-import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -32,24 +32,33 @@ public class FeatureRendererSettings implements Cloneable
 {
   String[] renderOrder;
 
-  Map featureGroups;
+  /*
+   * map of {groupName, isDisplayed}
+   */
+  Map<String, Boolean> featureGroups;
 
-  Map featureColours;
+  /*
+   * map of {featureType, colourScheme}
+   */
+  Map<String, FeatureColourI> featureColours;
 
   float transparency;
 
-  Map featureOrder;
+  Map<String, Float> featureOrder;
 
   public FeatureRendererSettings(String[] renderOrder,
-          Hashtable featureGroups, Hashtable featureColours,
-          float transparency, Hashtable featureOrder)
+          Map<String, Boolean> featureGroups,
+          Map<String, FeatureColourI> featureColours, float transparency,
+          Map<String, Float> featureOrder)
   {
     super();
     this.renderOrder = Arrays.copyOf(renderOrder, renderOrder.length);
-    this.featureGroups = new ConcurrentHashMap(featureGroups);
-    this.featureColours = new ConcurrentHashMap(featureColours);
+    this.featureGroups = new ConcurrentHashMap<String, Boolean>(
+            featureGroups);
+    this.featureColours = new ConcurrentHashMap<String, FeatureColourI>(
+            featureColours);
     this.transparency = transparency;
-    this.featureOrder = new ConcurrentHashMap(featureOrder);
+    this.featureOrder = new ConcurrentHashMap<String, Float>(featureOrder);
   }
 
   /**
@@ -61,9 +70,9 @@ public class FeatureRendererSettings implements Cloneable
           jalview.viewmodel.seqfeatures.FeatureRendererModel fr)
   {
     renderOrder = null;
-    featureGroups = new ConcurrentHashMap();
-    featureColours = new ConcurrentHashMap();
-    featureOrder = new ConcurrentHashMap();
+    featureGroups = new ConcurrentHashMap<String, Boolean>();
+    featureColours = new ConcurrentHashMap<String, FeatureColourI>();
+    featureOrder = new ConcurrentHashMap<String, Float>();
     if (fr.renderOrder != null)
     {
       this.renderOrder = new String[fr.renderOrder.length];
@@ -72,26 +81,30 @@ public class FeatureRendererSettings implements Cloneable
     }
     if (fr.featureGroups != null)
     {
-      this.featureGroups = new ConcurrentHashMap(fr.featureGroups);
+      this.featureGroups = new ConcurrentHashMap<String, Boolean>(
+              fr.featureGroups);
     }
     if (fr.featureColours != null)
     {
-      this.featureColours = new ConcurrentHashMap(fr.featureColours);
+      this.featureColours = new ConcurrentHashMap<String, FeatureColourI>(
+              fr.featureColours);
     }
-    Iterator en = fr.featureColours.keySet().iterator();
+    Iterator<String> en = fr.featureColours.keySet().iterator();
     while (en.hasNext())
     {
-      Object next = en.next();
-      Object val = featureColours.get(next);
-      if (val instanceof GraduatedColor)
+      String next = en.next();
+      FeatureColourI val = featureColours.get(next);
+      // if (val instanceof GraduatedColor)
+      if (val.isGraduatedColour() || val.isColourByLabel()) // why this test?
       {
-        featureColours.put(next, new GraduatedColor((GraduatedColor) val));
+        featureColours.put(next, new FeatureColour((FeatureColour) val));
       }
     }
     this.transparency = fr.transparency;
     if (fr.featureOrder != null)
     {
-      this.featureOrder = new ConcurrentHashMap(fr.featureOrder);
+      this.featureOrder = new ConcurrentHashMap<String, Float>(
+              fr.featureOrder);
     }
   }
 }
index 37f3ca5..520b232 100644 (file)
@@ -1,9 +1,9 @@
 package jalview.workers;
 
+import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.gui.AlignFrame;
-import jalview.gui.Desktop;
 
 import java.awt.Color;
 
@@ -28,9 +28,9 @@ public class AlignmentAnnotationFactory
    */
   public static void newCalculator(FeatureCounterI counter)
   {
-    if (Desktop.getCurrentAlignFrame() != null)
+    if (Jalview.getCurrentAlignFrame() != null)
     {
-      newCalculator(Desktop.getCurrentAlignFrame(), counter);
+      newCalculator(Jalview.getCurrentAlignFrame(), counter);
     }
     else
     {
@@ -60,9 +60,9 @@ public class AlignmentAnnotationFactory
    */
   public static void newCalculator(AnnotationProviderI calculator)
   {
-    if (Desktop.getCurrentAlignFrame() != null)
+    if (Jalview.getCurrentAlignFrame() != null)
     {
-      newCalculator(Desktop.getCurrentAlignFrame(), calculator);
+      newCalculator(Jalview.getCurrentAlignFrame(), calculator);
     }
     else
     {
index c87a111..b0b5e92 100644 (file)
@@ -244,12 +244,12 @@ public class Pdb extends EbiFileRetrievedProxy
   }
 
   /**
-   * obtain human glyoxalase chain A sequence
+   * human glyoxalase
    */
   @Override
   public String getTestQuery()
   {
-    return "1QIPA";
+    return "1QIP";
   }
 
   @Override
index 86c2b9f..70056a6 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.ws.jws1;
 
 import jalview.analysis.AlignSeq;
+import jalview.api.FeatureColourI;
 import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
@@ -173,7 +174,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
      * @return null or { Alignment(+features and annotation), NewickFile)}
      */
     public Object[] getAlignment(AlignmentI dataset,
-            Map<String, Object> featureColours)
+            Map<String, FeatureColourI> featureColours)
     {
 
       if (result != null && result.isFinished())
@@ -623,7 +624,7 @@ class SeqSearchWSThread extends JWS1Thread implements WSClientI
     // NewickFile nf[] = new NewickFile[jobs.length];
     for (int j = 0; j < jobs.length; j++)
     {
-      Map<String, Object> featureColours = new HashMap<String, Object>();
+      Map<String, FeatureColourI> featureColours = new HashMap<String, FeatureColourI>();
       Alignment al = null;
       NewickFile nf = null;
       if (jobs[j].hasResults())
index f4b1c31..0cf76e0 100644 (file)
  */
 package jalview.ws.jws2;
 
+import jalview.api.AlignCalcWorkerI;
+import jalview.api.FeatureColourI;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.GraphLine;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
 import jalview.schemes.UserColourScheme;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.WsParamSetI;
@@ -306,8 +308,8 @@ public class AADisorderClient extends JabawsCalcWorker
                 annot.description += "<br/>" + threshNote;
               }
               annot.description += "</html>";
-              Color col = new UserColourScheme(typeName)
-                      .createColourFromName(typeName + scr.getMethod());
+              Color col = UserColourScheme.createColourFromName(typeName
+                      + scr.getMethod());
               for (int p = 0, ps = annot.annotations.length; p < ps; p++)
               {
                 if (annot.annotations[p] != null)
@@ -335,13 +337,13 @@ public class AADisorderClient extends JabawsCalcWorker
                   .cloneFeatureRenderer();
           for (String ft : fc.keySet())
           {
-            Object gc = fr.getFeatureStyle(ft);
-            if (gc instanceof Color)
+            FeatureColourI gc = fr.getFeatureStyle(ft);
+            if (gc.isSimpleColour())
             {
               // set graduated color as fading to white for minimum, and
               // autoscaling to values on alignment
-              GraduatedColor ggc = new GraduatedColor(Color.white,
-                      (Color) gc, Float.MIN_VALUE, Float.MAX_VALUE);
+              FeatureColourI ggc = new FeatureColour(Color.white,
+                      gc.getColour(), Float.MIN_VALUE, Float.MAX_VALUE);
               ggc.setAutoScaled(true);
               fr.setColour(ft, ggc);
             }
diff --git a/test/jalview/bin/ArgsParserTest.java b/test/jalview/bin/ArgsParserTest.java
new file mode 100644 (file)
index 0000000..06e79de
--- /dev/null
@@ -0,0 +1,65 @@
+package jalview.bin;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+import org.testng.annotations.Test;
+
+public class ArgsParserTest
+{
+  @Test(groups = "Functional")
+  public void testGetValue()
+  {
+    ArgsParser ap = new ArgsParser(new String[] { "-name", "Henry", "-job",
+        "Tester" });
+    assertEquals(4, ap.getSize());
+    assertNull(ap.getValue("rubbish"));
+    assertEquals("Tester", ap.getValue("job"));
+    // call to getValue removes the argument and its value
+    assertEquals(2, ap.getSize());
+    assertNull(ap.getValue("job"));
+    assertFalse(ap.contains("job"));
+    assertFalse(ap.contains("Tester"));
+
+    assertEquals("Henry", ap.getValue("name"));
+    assertEquals(0, ap.getSize());
+    assertNull(ap.getValue("name"));
+  }
+
+  @Test(groups = "Functional")
+  public void testGetValue_decoded()
+  {
+    ArgsParser ap = new ArgsParser(new String[] { "-name%241", "Henry",
+        "-job", "Test%203%2a" });
+    // parameter value is decoded
+    assertEquals("Test 3*", ap.getValue("job", true));
+    // parameter name is not decoded
+    assertNull(ap.getValue("name$1", true));
+    assertEquals("Henry", ap.getValue("name%241", true));
+  }
+
+  @Test(groups = "Functional")
+  public void testNextValue()
+  {
+    ArgsParser ap = new ArgsParser(new String[] { "-name", "Henry", "-job",
+        "Tester" });
+    assertEquals("name", ap.nextValue());
+    assertEquals("Henry", ap.nextValue());
+    assertEquals("job", ap.nextValue());
+    assertEquals("Tester", ap.nextValue());
+  }
+
+  @Test(groups = "Functional")
+  public void testContains()
+  {
+    ArgsParser ap = new ArgsParser(new String[] { "-name", "Henry", "-job",
+        "Tester" });
+    assertFalse(ap.contains("Susan"));
+    assertFalse(ap.contains("-name"));
+    assertTrue(ap.contains("name"));
+    // testing for contains removes the argument
+    assertFalse(ap.contains("name"));
+  }
+}
index 8a3b925..42bb091 100644 (file)
@@ -34,7 +34,7 @@ public class PDBEntryTest
   {
   }
 
-  @AfterMethod
+  @AfterMethod(alwaysRun = true)
   public void tearDown() throws Exception
   {
   }
index 90c38d4..fb7e143 100644 (file)
@@ -21,13 +21,13 @@ import org.testng.annotations.Test;
 
 public class EnsemblCdnaTest
 {
-  @BeforeClass
+  @BeforeClass(alwaysRun = true)
   public void setUp()
   {
     SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public void tearDown()
   {
     SequenceOntologyFactory.setInstance(null);
index 183f933..5344575 100644 (file)
@@ -20,13 +20,13 @@ import org.testng.annotations.Test;
 
 public class EnsemblCdsTest
 {
-  @BeforeClass
+  @BeforeClass(alwaysRun = true)
   public void setUp()
   {
     SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public void tearDown()
   {
     SequenceOntologyFactory.setInstance(null);
index 5cf296c..4e815d1 100644 (file)
@@ -22,13 +22,13 @@ import org.testng.annotations.Test;
 
 public class EnsemblGeneTest
 {
-  @BeforeClass
+  @BeforeClass(alwaysRun = true)
   public void setUp()
   {
     SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public void tearDown()
   {
     SequenceOntologyFactory.setInstance(null);
index daad8b1..c711279 100644 (file)
@@ -19,13 +19,13 @@ import org.testng.annotations.Test;
 
 public class EnsemblGenomeTest
 {
-  @BeforeClass
+  @BeforeClass(alwaysRun = true)
   public void setUp()
   {
     SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public void tearDown()
   {
     SequenceOntologyFactory.setInstance(null);
index 6ce8a3b..2d3948f 100644 (file)
@@ -6,7 +6,6 @@ import static org.testng.AssertJUnit.assertTrue;
 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
 
 import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.AppletFormatAdapter;
@@ -16,10 +15,7 @@ import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyLite;
 
 import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.util.Arrays;
-import java.util.List;
 
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
@@ -109,13 +105,13 @@ public class EnsemblSeqProxyTest
                   + "NRDQIIFMVGRGYLSPDLSKVRSNCPKAMKRLMAECLKKKRDERPLFPQILASIELLARS\n"
                   + "LPKIHRSASEPSLNRAGFQTEDFSLYACASPKTPIQAGGYGAFPVH" } };
 
-  @BeforeClass
+  @BeforeClass(alwaysRun = true)
   public void setUp()
   {
     SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public void tearDown()
   {
     SequenceOntologyFactory.setInstance(null);
index c9b2980..10224fa 100644 (file)
@@ -53,7 +53,7 @@ public class JmolViewerTest
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
     jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
index cd28a2b..93a98b8 100644 (file)
@@ -54,7 +54,7 @@ public class JalviewChimeraView
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
     jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
index be07485..ea92e3c 100644 (file)
@@ -3,11 +3,8 @@ package jalview.ext.so;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
-import jalview.ext.so.SequenceOntology;
-import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyI;
 
-import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -15,20 +12,20 @@ public class SequenceOntologyTest
 {
   private SequenceOntologyI so;
 
-  @BeforeClass
+  @BeforeClass(alwaysRun = true)
   public void setUp() {
     long now = System.currentTimeMillis();
-    SequenceOntologyFactory.setInstance(new SequenceOntology());
+    try
+    {
+      so = new SequenceOntology();
+    } catch (Throwable t)
+    {
+      System.out.println("SOTest error ");
+      t.printStackTrace(System.err);
+    }
     long elapsed = System.currentTimeMillis() - now;
     System.out.println("Load and cache of Sequence Ontology took "
             + elapsed + "ms");
-    so = SequenceOntologyFactory.getInstance();
-  }
-
-  @AfterClass
-  public void tearDown()
-  {
-    SequenceOntologyFactory.setInstance(null);
   }
 
   @Test(groups = "Functional")
index ac1d304..69792bb 100644 (file)
@@ -23,8 +23,6 @@ package jalview.fts.service.pdb;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
-import jalview.fts.service.pdb.PDBFTSPanel;
-
 import javax.swing.JInternalFrame;
 import javax.swing.JTextField;
 
@@ -40,7 +38,7 @@ public class PDBFTSPanelTest
   {
   }
 
-  @AfterMethod
+  @AfterMethod(alwaysRun = true)
   public void tearDown() throws Exception
   {
   }
index ebc0405..ed248bb 100644 (file)
@@ -59,7 +59,7 @@ public class PDBFTSRestClientTest
   {
   }
 
-  @AfterMethod
+  @AfterMethod(alwaysRun = true)
   public void tearDown() throws Exception
   {
   }
index ff8c179..9d0cedb 100644 (file)
@@ -47,7 +47,7 @@ public class JAL1353bugdemo
   {
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
   }
index 52eadcb..212bcce 100644 (file)
@@ -48,7 +48,7 @@ public class PaintRefresherTest
     PaintRefresher.components.clear();
   }
 
-  @AfterMethod
+  @AfterMethod(alwaysRun = true)
   public void tearDown()
   {
     PaintRefresher.components.clear();
index ae6bf38..da2cde5 100644 (file)
@@ -60,7 +60,7 @@ public class StructureChooserTest
     seq.setPDBId(pdbIds);
   }
 
-  @AfterMethod
+  @AfterMethod(alwaysRun = true)
   public void tearDown() throws Exception
   {
     seq = null;
index c472576..62d76a2 100644 (file)
@@ -180,7 +180,7 @@ public class AnnotatedPDBFileInputTest
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
     jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
index 29bd567..2f5d0c5 100644 (file)
@@ -26,6 +26,7 @@ import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.api.FeatureColourI;
 import jalview.api.FeatureRenderer;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
@@ -33,8 +34,6 @@ import jalview.datamodel.SequenceDummy;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
 
 import java.awt.Color;
 import java.io.File;
@@ -54,7 +53,7 @@ public class FeaturesFileTest
     File f = new File("examples/uniref50.fa");
     AlignmentI al = readAlignmentFile(f);
     AlignFrame af = new AlignFrame(al, 500, 500);
-    Map<String, Object> colours = af.getFeatureRenderer()
+    Map<String, FeatureColourI> colours = af.getFeatureRenderer()
             .getFeatureColours();
     FeaturesFile featuresFile = new FeaturesFile(
             "examples/exampleFeatures.txt", FormatAdapter.FILE);
@@ -68,8 +67,8 @@ public class FeaturesFileTest
      */
     colours = af.getFeatureRenderer().getFeatureColours();
     assertEquals("26 feature group colours not found", 26, colours.size());
-    assertEquals(colours.get("Cath"), new Color(0x93b1d1));
-    assertEquals(colours.get("ASX-MOTIF"), new Color(0x6addbb));
+    assertEquals(colours.get("Cath").getColour(), new Color(0x93b1d1));
+    assertEquals(colours.get("ASX-MOTIF").getColour(), new Color(0x6addbb));
 
     /*
      * verify (some) features on sequences
@@ -151,7 +150,7 @@ public class FeaturesFileTest
     File f = new File("examples/uniref50.fa");
     AlignmentI al = readAlignmentFile(f);
     AlignFrame af = new AlignFrame(al, 500, 500);
-    Map<String, Object> colours = af.getFeatureRenderer()
+    Map<String, FeatureColourI> colours = af.getFeatureRenderer()
             .getFeatureColours();
     // GFF2 uses space as name/value separator in column 9
     String gffData = "METAL\tcc9900\n" + "GFF\n"
@@ -165,7 +164,7 @@ public class FeaturesFileTest
     // verify colours read or synthesized
     colours = af.getFeatureRenderer().getFeatureColours();
     assertEquals("1 feature group colours not found", 1, colours.size());
-    assertEquals(colours.get("METAL"), new Color(0xcc9900));
+    assertEquals(colours.get("METAL").getColour(), new Color(0xcc9900));
 
     // verify feature on FER_CAPAA
     SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence()
@@ -206,45 +205,6 @@ public class FeaturesFileTest
   }
 
   /**
-   * Test various ways of describing a feature colour scheme
-   * 
-   * @throws Exception
-   */
-  @Test(groups = { "Functional" })
-  public void testParseGraduatedColourScheme() throws Exception
-  {
-    FeaturesFile ff = new FeaturesFile();
-
-    // colour by label:
-    GraduatedColor gc = ff.parseGraduatedColourScheme(
-            "BETA-TURN-IR\t9a6a94", "label");
-    assertTrue(gc.isColourByLabel());
-    assertEquals(Color.white, gc.getMinColor());
-    assertEquals(Color.black, gc.getMaxColor());
-    assertTrue(gc.isAutoScale());
-
-    // using colour name, rgb, etc:
-    String spec = "blue|255,0,255|absolute|20.0|95.0|below|66.0";
-    gc = ff.parseGraduatedColourScheme("BETA-TURN-IR\t" + spec, spec);
-    assertFalse(gc.isColourByLabel());
-    assertEquals(Color.blue, gc.getMinColor());
-    assertEquals(new Color(255, 0, 255), gc.getMaxColor());
-    assertFalse(gc.isAutoScale());
-    assertFalse(gc.getTolow());
-    assertEquals(20.0f, gc.getMin(), 0.001f);
-    assertEquals(95.0f, gc.getMax(), 0.001f);
-    assertEquals(AnnotationColourGradient.BELOW_THRESHOLD,
-            gc.getThreshType());
-    assertEquals(66.0f, gc.getThresh(), 0.001f);
-
-    // inverse gradient high to low:
-    spec = "blue|255,0,255|95.0|20.0|below|66.0";
-    gc = ff.parseGraduatedColourScheme("BETA-TURN-IR\t" + spec, spec);
-    assertTrue(gc.isAutoScale());
-    assertTrue(gc.getTolow());
-  }
-
-  /**
    * Test parsing a features file with GFF formatted content only
    * 
    * @throws Exception
@@ -255,7 +215,7 @@ public class FeaturesFileTest
     File f = new File("examples/uniref50.fa");
     AlignmentI al = readAlignmentFile(f);
     AlignFrame af = new AlignFrame(al, 500, 500);
-    Map<String, Object> colours = af.getFeatureRenderer()
+    Map<String, FeatureColourI> colours = af.getFeatureRenderer()
             .getFeatureColours();
     // GFF3 uses '=' separator for name/value pairs in colum 9
     String gffData = "##gff-version 3\n"
@@ -307,7 +267,7 @@ public class FeaturesFileTest
     File f = new File("examples/uniref50.fa");
     AlignmentI al = readAlignmentFile(f);
     AlignFrame af = new AlignFrame(al, 500, 500);
-    Map<String, Object> colours = af.getFeatureRenderer()
+    Map<String, FeatureColourI> colours = af.getFeatureRenderer()
             .getFeatureColours();
 
     /*
@@ -430,7 +390,7 @@ public class FeaturesFileTest
     File f = new File("examples/uniref50.fa");
     AlignmentI al = readAlignmentFile(f);
     AlignFrame af = new AlignFrame(al, 500, 500);
-    Map<String, Object> colours = af.getFeatureRenderer()
+    Map<String, FeatureColourI> colours = af.getFeatureRenderer()
             .getFeatureColours();
     String features = "METAL\tcc9900\n"
             + "GAMMA-TURN\tred|0,255,255|20.0|95.0|below|66.0\n"
@@ -448,7 +408,7 @@ public class FeaturesFileTest
      * first with no features displayed
      */
     FeatureRenderer fr = af.alignPanel.getFeatureRenderer();
-    Map<String, Object> visible = fr
+    Map<String, FeatureColourI> visible = fr
             .getDisplayedFeatureCols();
     String exported = featuresFile.printJalviewFormat(
             al.getSequencesArray(), visible);
index cde1cbc..2eb3703 100644 (file)
@@ -46,7 +46,7 @@ public class FileIOTester
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
   }
index d327134..93fb12b 100644 (file)
@@ -262,7 +262,7 @@ public class JSONFileTest
     passedCount = 0;
   }
 
-  @AfterTest
+  @AfterTest(alwaysRun = true)
   public void tearDown() throws Exception
   {
     testJsonFile = null;
index 5e2ceb9..00d4ee0 100644 (file)
@@ -36,6 +36,8 @@ import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.ColourSchemeI;
 
 import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.testng.Assert;
 import org.testng.AssertJUnit;
@@ -43,6 +45,7 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+@Test(singleThreaded = true)
 public class Jalview2xmlTests
 {
 
@@ -59,7 +62,7 @@ public class Jalview2xmlTests
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
     jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
@@ -413,6 +416,78 @@ public class Jalview2xmlTests
             Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length);
   }
 
+  /**
+   * based on above test store and recovery of expanded views.
+   * 
+   * @throws Exception
+   */
+  @Test(groups = { "Functional" })
+  public void testStoreAndRecoverReferenceSeqSettings() throws Exception
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+    String afid = "";
+    {
+      AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+              "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
+      assertTrue("Didn't read in the example file correctly.", af != null);
+      afid = af.getViewport().getSequenceSetId();
+    }
+    Map<String, SequenceI> refs = new HashMap<String, SequenceI>();
+    int n = 1;
+    for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
+    {
+      // mark representative
+      SequenceI rep = ap.getAlignment().getSequenceAt(
+              n++ % ap.getAlignment().getHeight());
+      refs.put(ap.getViewName(), rep);
+      // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
+      // todo refactor the to an alignment view controller
+      ap.getAlignViewport().setDisplayReferenceSeq(true);
+      ap.getAlignViewport().setColourByReferenceSeq(true);
+      ap.getAlignViewport().getAlignment().setSeqrep(rep);
+    }
+    File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
+            ".jvp");
+    try
+    {
+      new Jalview2XML(false).saveState(tfile);
+    } catch (Error e)
+    {
+      Assert.fail("Didn't save the expanded view state", e);
+    } catch (Exception e)
+    {
+      Assert.fail("Didn't save the expanded view state", e);
+    }
+    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.getAlignFrames() != null)
+    {
+      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+    }
+    {
+      AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
+            tfile.getAbsolutePath(), FormatAdapter.FILE);
+      afid = af.getViewport().getSequenceSetId();
+    }
+    for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
+    {
+      // check representative
+      SequenceI rep = ap.getAlignment().getSeqrep();
+      Assert.assertNotNull(rep,
+              "Couldn't restore sequence representative from project");
+      // can't use a strong equals here, because by definition, the sequence IDs
+      // will be different.
+      // could set vamsas session save/restore flag to preserve IDs across
+      // load/saves.
+      Assert.assertEquals(refs.get(ap.getViewName()).toString(),
+              rep.toString(),
+              "Representative wasn't the same when recovered.");
+      Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
+              "Display reference sequence view setting not set.");
+      Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
+              "Colour By Reference Seq view setting not set.");
+    }
+  }
+
   @Test(groups = { "Functional" })
   public void testIsVersionStringLaterThan()
   {
index ab3d9df..164c259 100644 (file)
@@ -52,7 +52,7 @@ public class JalviewExportPropertiesTests
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
     jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
index d8e21c4..f89f58b 100644 (file)
@@ -172,7 +172,7 @@ public class NewickFileTests
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
   }
index d41446b..c084792 100644 (file)
@@ -34,7 +34,7 @@ public class RNAMLfileTest
   {
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
   }
diff --git a/test/jalview/schemes/FeatureColourTest.java b/test/jalview/schemes/FeatureColourTest.java
new file mode 100644 (file)
index 0000000..9b1bd73
--- /dev/null
@@ -0,0 +1,301 @@
+package jalview.schemes;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
+
+import jalview.datamodel.SequenceFeature;
+import jalview.util.Format;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class FeatureColourTest
+{
+  @Test(groups = { "Functional" })
+  public void testIsColored_simpleColour()
+  {
+    FeatureColour fc = new FeatureColour(Color.RED);
+    assertTrue(fc.isColored(new SequenceFeature()));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testIsColored_colourByLabel()
+  {
+    FeatureColour fc = new FeatureColour();
+    fc.setColourByLabel(true);
+    assertTrue(fc.isColored(new SequenceFeature()));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testIsColored_aboveThreshold()
+  {
+    // graduated colour range from score 20 to 100
+    FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 20f,
+            100f);
+
+    // score 0 is adjusted to bottom of range
+    SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 0f,
+            null);
+    assertTrue(fc.isColored(sf));
+    assertEquals(Color.WHITE, fc.getColor(sf));
+
+    // score 120 is adjusted to top of range
+    sf.setScore(120f);
+    assertEquals(Color.BLACK, fc.getColor(sf));
+
+    // value below threshold is still rendered
+    // setting threshold has no effect yet...
+    fc.setThreshold(60f);
+    sf.setScore(36f);
+    assertTrue(fc.isColored(sf));
+    assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+
+    // now apply threshold:
+    fc.setAboveThreshold(true);
+    assertFalse(fc.isColored(sf));
+    // colour is still returned though ?!?
+    assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+
+    sf.setScore(84); // above threshold now
+    assertTrue(fc.isColored(sf));
+    assertEquals(new Color(51, 51, 51), fc.getColor(sf));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetColor_simpleColour()
+  {
+    FeatureColour fc = new FeatureColour(Color.RED);
+    assertEquals(Color.RED, fc.getColor(new SequenceFeature()));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetColor_colourByLabel()
+  {
+    FeatureColour fc = new FeatureColour();
+    fc.setColourByLabel(true);
+    SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
+            null);
+    Color expected = UserColourScheme.createColourFromName("desc");
+    assertEquals(expected, fc.getColor(sf));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetColor_Graduated()
+  {
+    // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0, 0)
+    FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
+    // feature score is 75 which is 3/4 of the way from GRAY to RED
+    SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
+            null);
+    // the colour gradient is computed in float values from 0-1 (where 1 == 255)
+    float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
+    float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
+    float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
+    Color expected = new Color(red, green, blue);
+    assertEquals(expected, fc.getColor(sf));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetColor_belowThreshold()
+  {
+    // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
+    FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 50f,
+            150f);
+    SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
+            null);
+    fc.setThreshold(100f); // ignore for now
+    assertTrue(fc.isColored(sf));
+    assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+
+    fc.setAboveThreshold(true); // feature lies below threshold
+    assertFalse(fc.isColored(sf));
+    assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+  }
+
+  /**
+   * Test output of feature colours to Jalview features file format
+   */
+  @Test(groups = { "Functional" })
+  public void testToJalviewFormat()
+  {
+    /*
+     * plain colour - to RGB hex code
+     */
+    FeatureColour fc = new FeatureColour(Color.RED);
+    String redHex = Format.getHexString(Color.RED);
+    String hexColour = redHex;
+    assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
+    
+    /*
+     * colour by label (no threshold)
+     */
+    fc = new FeatureColour();
+    fc.setColourByLabel(true);
+    assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
+
+    /*
+     * colour by label (autoscaled) (an odd state you can reach by selecting
+     * 'above threshold', then deselecting 'threshold is min/max' then 'colour
+     * by label')
+     */
+    fc.setAutoScaled(true);
+    assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
+
+    /*
+     * colour by label (above threshold) (min/max values are output though not
+     * used by this scheme)
+     */
+    fc.setAutoScaled(false);
+    fc.setThreshold(12.5f);
+    fc.setAboveThreshold(true);
+    assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
+            fc.toJalviewFormat("domain"));
+
+    /*
+     * colour by label (below threshold)
+     */
+    fc.setBelowThreshold(true);
+    assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
+            fc.toJalviewFormat("domain"));
+
+    /*
+     * graduated colour, no threshold
+     */
+    fc = new FeatureColour(Color.GREEN, Color.RED, 12f, 25f);
+    String greenHex = Format.getHexString(Color.GREEN);
+    String expected = String.format("domain\t%s|%s|abso|12.0|25.0|none",
+            greenHex, redHex);
+    assertEquals(expected, fc.toJalviewFormat("domain"));
+
+    /*
+     * colour ranges over the actual score ranges (not min/max)
+     */
+    fc.setAutoScaled(true);
+    expected = String.format("domain\t%s|%s|12.0|25.0|none", greenHex,
+            redHex);
+    assertEquals(expected, fc.toJalviewFormat("domain"));
+
+    /*
+     * graduated colour below threshold
+     */
+    fc.setThreshold(12.5f);
+    fc.setBelowThreshold(true);
+    expected = String.format("domain\t%s|%s|12.0|25.0|below|12.5",
+            greenHex, redHex);
+    assertEquals(expected, fc.toJalviewFormat("domain"));
+
+    /*
+     * graduated colour above threshold
+     */
+    fc.setThreshold(12.5f);
+    fc.setAboveThreshold(true);
+    fc.setAutoScaled(false);
+    expected = String.format("domain\t%s|%s|abso|12.0|25.0|above|12.5",
+            greenHex, redHex);
+    assertEquals(expected, fc.toJalviewFormat("domain"));
+  }
+
+  /**
+   * Test parsing of feature colours from Jalview features file format
+   */
+  @Test(groups = { "Functional" })
+  public void testParseJalviewFeatureColour()
+  {
+    /*
+     * simple colour by name
+     */
+    FeatureColour fc = FeatureColour.parseJalviewFeatureColour("red");
+    assertTrue(fc.isSimpleColour());
+    assertEquals(Color.RED, fc.getColour());
+
+    /*
+     * simple colour by hex code
+     */
+    fc = FeatureColour.parseJalviewFeatureColour(Format
+            .getHexString(Color.RED));
+    assertTrue(fc.isSimpleColour());
+    assertEquals(Color.RED, fc.getColour());
+
+    /*
+     * simple colour by rgb triplet
+     */
+    fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
+    assertTrue(fc.isSimpleColour());
+    assertEquals(Color.RED, fc.getColour());
+
+    /*
+     * malformed colour
+     */
+    try
+    {
+      fc = FeatureColour.parseJalviewFeatureColour("oops");
+      fail("expected exception");
+    } catch (IllegalArgumentException e)
+    {
+      assertEquals("Invalid colour descriptor: oops", e.getMessage());
+    }
+
+    /*
+     * colour by label (no threshold)
+     */
+    fc = FeatureColour.parseJalviewFeatureColour("label");
+    assertTrue(fc.isColourByLabel());
+    assertFalse(fc.hasThreshold());
+
+    /*
+     * colour by label (with threshold)
+     */
+    fc = FeatureColour
+            .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
+    assertTrue(fc.isColourByLabel());
+    assertTrue(fc.isAboveThreshold());
+    assertEquals(12.0f, fc.getThreshold());
+
+    /*
+     * graduated colour (by name) (no threshold)
+     */
+    fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
+    assertTrue(fc.isGraduatedColour());
+    assertFalse(fc.hasThreshold());
+    assertEquals(Color.RED, fc.getMinColour());
+    assertEquals(Color.GREEN, fc.getMaxColour());
+    assertEquals(10f, fc.getMin());
+    assertEquals(20f, fc.getMax());
+    assertTrue(fc.isAutoScaled());
+
+    /*
+     * graduated colour (by hex code) (above threshold)
+     */
+    String descriptor = String.format("%s|%s|10.0|20.0|above|15",
+            Format.getHexString(Color.RED),
+            Format.getHexString(Color.GREEN));
+    fc = FeatureColour.parseJalviewFeatureColour(descriptor);
+    assertTrue(fc.isGraduatedColour());
+    assertTrue(fc.hasThreshold());
+    assertTrue(fc.isAboveThreshold());
+    assertEquals(15f, fc.getThreshold());
+    assertEquals(Color.RED, fc.getMinColour());
+    assertEquals(Color.GREEN, fc.getMaxColour());
+    assertEquals(10f, fc.getMin());
+    assertEquals(20f, fc.getMax());
+    assertTrue(fc.isAutoScaled());
+
+    /*
+     * graduated colour (by RGB triplet) (below threshold), absolute scale
+     */
+    descriptor = String.format("255,0,0|0,255,0|abso|10.0|20.0|below|15");
+    fc = FeatureColour.parseJalviewFeatureColour(descriptor);
+    assertTrue(fc.isGraduatedColour());
+    assertFalse(fc.isAutoScaled());
+    assertTrue(fc.hasThreshold());
+    assertTrue(fc.isBelowThreshold());
+    assertEquals(15f, fc.getThreshold());
+    assertEquals(Color.RED, fc.getMinColour());
+    assertEquals(Color.GREEN, fc.getMaxColour());
+    assertEquals(10f, fc.getMin());
+    assertEquals(20f, fc.getMax());
+  }
+}
diff --git a/test/jalview/schemes/UserColourSchemeTest.java b/test/jalview/schemes/UserColourSchemeTest.java
new file mode 100644 (file)
index 0000000..88f4331
--- /dev/null
@@ -0,0 +1,50 @@
+package jalview.schemes;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertSame;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+public class UserColourSchemeTest
+{
+
+  @Test(groups = "functional")
+  public void testGetColourFromString()
+  {
+    /*
+     * by colour name - if known to AWT, and included in
+     * 
+     * @see ColourSchemeProperty.getAWTColorFromName()
+     */
+    assertSame(Color.RED, UserColourScheme.getColourFromString("red"));
+    assertSame(Color.RED, UserColourScheme.getColourFromString("Red"));
+    assertSame(Color.RED, UserColourScheme.getColourFromString(" RED "));
+
+    /*
+     * by RGB hex code
+     */
+    String hexColour = Integer.toHexString(Color.RED.getRGB() & 0xffffff);
+    assertEquals(Color.RED, UserColourScheme.getColourFromString(hexColour));
+    // 'hex' prefixes _not_ wanted here
+    assertNull(UserColourScheme.getColourFromString("0x" + hexColour));
+    assertNull(UserColourScheme.getColourFromString("#" + hexColour));
+
+    /*
+     * by RGB triplet
+     */
+    String rgb = String.format("%d,%d,%d", Color.red.getRed(),
+            Color.red.getGreen(), Color.red.getBlue());
+    assertEquals(Color.RED, UserColourScheme.getColourFromString(rgb));
+
+    /*
+     * odds and ends
+     */
+    assertNull(UserColourScheme.getColourFromString(null));
+    assertNull(UserColourScheme.getColourFromString("rubbish"));
+    assertEquals(Color.WHITE, UserColourScheme.getColourFromString("-1"));
+    assertNull(UserColourScheme.getColourFromString(String
+            .valueOf(Integer.MAX_VALUE)));
+  }
+}
index d020173..b560f01 100644 (file)
@@ -76,4 +76,39 @@ public class PDBSequenceFetcherTest
     }
   }
 
+  @Test(groups = { "Network" }, enabled = true)
+  public void testPdbSeqRetrieve() throws Exception
+  {
+    Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+            Boolean.TRUE.toString());
+    testRetrieveProteinSeqFromPDB();
+  }
+
+  @Test(groups = { "Network" }, enabled = true)
+  public void testmmCifSeqRetrieve() throws Exception
+  {
+    Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+            Boolean.FALSE.toString());
+    testRetrieveProteinSeqFromPDB();
+  }
+
+  private void testRetrieveProteinSeqFromPDB() throws Exception
+  {
+    List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
+    AlignmentI response = sps.get(0).getSequenceRecords("1QIP");
+    assertTrue(response != null);
+    assertTrue(response.getHeight() == 4);
+    for (SequenceI sq : response.getSequences())
+    {
+      assertTrue("No annotation transfered to sequence.",
+              sq.getAnnotation().length > 0);
+      assertTrue("No PDBEntry on sequence.",
+              sq.getAllPDBEntries().size() > 0);
+      org.testng.Assert
+              .assertEquals(sq.getEnd() - sq.getStart() + 1,
+                      sq.getLength(),
+                      "Sequence start/end doesn't match number of residues in sequence");
+    }
+  }
+
 }
index 46feebc..4550fe8 100644 (file)
@@ -37,7 +37,7 @@ public class JalviewJabawsTestUtils
   {
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
   }
index afb24c4..9398d18 100644 (file)
@@ -84,7 +84,7 @@ public class JpredJabaStructExportImport
     assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
     if (af != null)
index b57e5d0..fe96e07 100644 (file)
@@ -36,6 +36,7 @@ import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.AutoCalcSetting;
 
 import java.awt.Component;
+import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -51,6 +52,8 @@ import compbio.metadata.WrongParameterException;
 
 public class RNAStructExportImport
 {
+  private static final String JAR_FILE_NAME = "testRnalifold_param.jar";
+
   public static String testseqs = "examples/RF00031_folded.stk";
 
   public static Jws2Discoverer disc;
@@ -108,13 +111,18 @@ public class RNAStructExportImport
                                                       // public?
   }
 
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
     if (af != null)
     {
       af.setVisible(false);
       af.dispose();
+      File f = new File(JAR_FILE_NAME);
+      if (f.exists())
+      {
+        f.delete();
+      }
     }
   }
 
@@ -267,10 +275,10 @@ public class RNAStructExportImport
     // write out parameters
     jalview.gui.AlignFrame nalf = null;
     assertTrue("Couldn't write out the Jar file",
-            new Jalview2XML(false).saveAlignment(af,
-                    "testRnalifold_param.jar", "trial parameter writeout"));
+            new Jalview2XML(false).saveAlignment(af, JAR_FILE_NAME,
+                    "trial parameter writeout"));
     assertTrue("Couldn't read back the Jar file", (nalf = new Jalview2XML(
-            false).loadJalviewAlign("testRnalifold_param.jar")) != null);
+            false).loadJalviewAlign(JAR_FILE_NAME)) != null);
     if (nalf != null)
     {
       AutoCalcSetting acs = af.getViewport().getCalcIdSettingsFor(
index 44cefe2..8ee4f40 100644 (file)
@@ -62,7 +62,7 @@ public class DbRefFetcherTest
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterClass(alwaysRun = true)
   public static void tearDownAfterClass() throws Exception
   {
   }