Merge branch 'bug/JAL-998_wrap-sequence-tooltip' into Release_2_8_2_Branch
authorCharles Ofoegbu <tcnofoegbu@dundee.ac.uk>
Wed, 26 Nov 2014 16:06:04 +0000 (16:06 +0000)
committerCharles Ofoegbu <tcnofoegbu@dundee.ac.uk>
Wed, 26 Nov 2014 16:06:04 +0000 (16:06 +0000)
82 files changed:
.classpath
build.xml
help/help.jhm
help/helpTOC.xml
help/html/features/annotation.html
help/html/features/chimera.html
help/html/features/preferences.html
help/html/features/viewingpdbs.html
help/html/features/xsspannotation.html [new file with mode: 0644]
help/html/menus/popupMenu.html
help/html/releases.html
help/html/webServices/jnet.html
help/html/whatsNew.html
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/MCview/PDBChain.java
src/MCview/PDBViewer.java
src/MCview/PDBfile.java
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/AnnotationSorter.java
src/jalview/analysis/Rna.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AnnotationPanel.java
src/jalview/appletgui/RedundancyPanel.java
src/jalview/appletgui/SeqPanel.java
src/jalview/bin/Cache.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewLite.java
src/jalview/commands/EditCommand.java
src/jalview/commands/RemoveGapColCommand.java
src/jalview/commands/RemoveGapsCommand.java
src/jalview/commands/SlideSequencesCommand.java
src/jalview/commands/TrimRegionCommand.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentAnnotation.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/HiddenSequences.java
src/jalview/ext/jmol/PDBFileWithJmol.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/Desktop.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/Help.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/Preferences.java
src/jalview/gui/RedundancyPanel.java
src/jalview/gui/SVGOptions.java [new file with mode: 0644]
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/WsJobParameters.java
src/jalview/gui/WsPreferences.java
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/FormatAdapter.java
src/jalview/io/RnamlFile.java
src/jalview/io/StockholmFile.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/jbgui/GPreferences.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/schemes/AnnotationColourGradient.java
src/jalview/schemes/ColourSchemeProperty.java
src/jalview/schemes/ResidueProperties.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/util/ImageMaker.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/ws/jws1/JPredThread.java
src/jalview/ws/jws2/AADisorderClient.java
src/jalview/ws/jws2/JabaWsServerQuery.java
src/jalview/ws/jws2/JabawsCalcWorker.java
src/jalview/ws/jws2/Jws2Discoverer.java
src/jalview/ws/jws2/MsaWSClient.java
test/jalview/commands/EditCommandTest.java [new file with mode: 0644]
test/jalview/ext/jmol/PDBFileWithJmolTest.java
test/jalview/ext/paradise/TestAnnotate3D.java
test/jalview/gui/HelpTest.java [new file with mode: 0644]
test/jalview/io/RNAMLfileTest.java
test/jalview/io/StockholmFileTest.java
test/jalview/ws/jabaws/JalviewJabawsTestUtils.java

index 38d2106..f87dd26 100644 (file)
        <classpathentry kind="lib" path="lib/log4j-to-slf4j-2.0-rc2.jar"/>
        <classpathentry kind="lib" path="lib/slf4j-log4j12-1.7.7.jar"/>
        <classpathentry kind="lib" path="lib/VARNAv3-91.jar"/>
+
        <classpathentry kind="lib" path="lib/jfreesvg-2.1.jar"/>
        <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
        <classpathentry kind="lib" path="lib/xml-apis.jar"/>
-       <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin17"/>
        <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
        <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Plugin.jar"/>
index 19b41e5..d8ebe1e 100755 (executable)
--- a/build.xml
+++ b/build.xml
         <include name="*.jar"/>
       </fileset> -->
       </path>
+       
     <!-- Jalview Version String displayed by application on startup and used to check for updates -->
     <property name="JALVIEW_VERSION" value="DEVELOPMENT" />
+       
+    <property name="INSTALLATION" value="Source" />
+       
     <!-- 2.4 (VAMSAS)" -->
     <!-- Include debugging information in javac true or false -->
     <property name="javac.debug" value="true" />
     <properties file="${outputDir}/.build_properties">
       <header>
           ---Jalview Build Details---
-        </header>
+        </header>      
       <property name="VERSION" value="${JALVIEW_VERSION}" />
+      <property name="INSTALLATION" value="${INSTALLATION}" />
       <property name="BUILD_DATE" value="${build.date}" />
     </properties>
   </target>
index c6cc626..b6b0063 100755 (executable)
@@ -39,6 +39,7 @@
    <mapID target="disorder" url="html/webServices/proteinDisorder.html"/>
    <mapID target="aacon" url="html/webServices/AACon.html"/>
    <mapID target="rnaalifold" url="html/webServices/RNAalifold.html"/>
+   <mapID target="seqannots" url="html/features/annotation.html#seqannots"/>
    <mapID target="seqfetch" url="html/features/seqfetch.html"/>
    <mapID target="dbreffetcher" url="html/webServices/dbreffetcher.html"/>
    <mapID target="seqmappings" url="html/features/seqmappings.html"/>
@@ -54,6 +55,7 @@
    <mapID target="pdbjmol" url="html/features/jmol.html"/>
    <mapID target="chimera" url="html/features/chimera.html"/>
    <mapID target="varna" url="html/features/varna.html"/>
+   <mapID target="xsspannotation" url="html/features/xsspannotation.html"/>
    <mapID target="preferences" url="html/features/preferences.html"/>     
    <mapID target="commandline" url="html/features/commandline.html"/>
    <mapID target="clarguments" url="html/features/clarguments.html"/>
index 6ae5c78..1d45e7a 100755 (executable)
@@ -97,6 +97,9 @@
                <tocitem text="Pairwise Alignments" target="pairwise"/>
                <tocitem text="Remove Redundancy" target="redundancy"/>
        </tocitem>
+       <tocitem text="Sequence Annotations" target="seqannots" expand="true">
+               <tocitem text="Annotation from Structure" target="xsspannotation" expand="false"/>
+       </tocitem>
        <tocitem text="Alignment Annotations" target ="alannotation" expand="false">
           <tocitem text="Conservation" target="calcs.alconserv"/>          
           <tocitem text="Quality" target="calcs.alquality"/>
index 49128c2..a036bd5 100755 (executable)
@@ -39,6 +39,15 @@ and symbolic annotations can be added to an alignment via an <a
 href="annotationsFormat.html">Annotations File</a> dragged into the
 alignment window or loaded from the alignment's file menu.
 </p>
+<p><a name="seqannots"/><strong>Sequence Reference Annotation</strong>
+</p>
+<p>
+               Sequence reference annotation is created from 3D structure
+               data, and from the results of sequence based prediction of
+               <a href="../webServices/jnet.html">secondary structure</a> and <a
+                       href="../webServices/proteinDisorder.html">disordered region</a>
+               prediction methods. 
+</p>
 <p><strong>Interactive Alignment Annotation</strong></p>
 <p>
 Annotation rows are added using the <strong>Annotation Label</strong>
index e866597..236701a 100644 (file)
@@ -133,6 +133,8 @@ atoms in the displayed structures. For comprehensive details of Chimera's comman
                they are insertions (relative to the associated sequence in the
                alignment) and grey if they are N or C terminal flanks outside the
                region mapped to the alignment window's sequence.</em></li>
+               <li><strong>By Chain<br>
+               </strong><em>Uses the Chimera 'rainbow chain' command to apply a different colour to each chain.</em></li>
                <li><strong>Charge &amp; Cysteine<br>
                </strong><em> Highlights cysteines in yellow, anionic (Aspartic Acid or
                Glutamic Acid) residues in red, and cationic (Lysine or Arginine)
index b2d8b93..657359e 100755 (executable)
@@ -113,16 +113,16 @@ will be loaded.</p>
 <p><a name="structure"><strong>&quot;Structure&quot;
 Preferences tab</strong></a><em> added in Jalview 2.8.2</em></p>
 <p><em>Process secondary structure from PDB</em> - if selected, then structure information
-read from PDB will be processed to derive secondary structure annotation.
-<p><em>Use RNAView for secondary structure</em> - if selected, the RNAView service will be 
-automatically called to derive secondary structure information.
-<p><em>Add secondary structure annotation to alignment</em> - if selected, PDB secondary structure
-annotation will be shown on the alignment when available.
-<p><em>Add Temperature Factor annotation to alignment</em> - if selected, PDB Temperature Factor
-annotation will be shown on the alignment when available. 
+read from PDB will be processed and annotation added to associated sequences.
+<p><em>Use RNAView for secondary structure</em> - if selected, the pyRNA RNAView service (<a href="https://github.com/fjossinet/PyRNA">https://github.com/fjossinet/PyRNA</a>) will be 
+called to derive secondary structure information for RNA chains.
+<p><em>Add secondary structure annotation to alignment</em> - if selected, <a href="http://swift.cmbi.ru.nl/gv/dssp/">Jmol's implementation DSSP</a> will be used to add annotation to polypeptide chains in the structure.
+<p><em>Add Temperature Factor annotation to alignment</em> - if selected, values extracted from the Temperature Factor
+column for the backbone atoms in the PDB file will be extracted as annotation lines shown on the alignment. 
 <p><em>Default structure viewer</em> - choose JMOL or CHIMERA for viewing 3D structures. 
 <p><em>Path to Chimera program</em> - Optional, as Jalview will search standard installation paths for Windows, Linux or MacOS. 
-If you have installed Chimera in a non-standard location, you can specify it here. Enter the full path to the Chimera executable program.  
+If you have installed Chimera in a non-standard location, you can specify it here, by entering the full path to the Chimera executable program.
+Double-click this field to open a file chooser dialog.  
 
 <p><a name="connections"><strong>&quot;Connections&quot;
 Preferences tab</strong></a></p>
index 8fc557e..75a5c9c 100755 (executable)
 </head>
 <body>
 <p><strong>Viewing PDB Structures</strong></p>
-
-<p>Jalview can view protein structures associated with a sequence
-via the <strong>"Structure&rarr;"</strong> submenu from a
-sequence's <a href="../menus/popupMenu.html">pop-up menu</a>.</p>
-A <a href="jmol.html">Jmol viewer</a> has been included since Jalview 2.3. Jalview 2.8.2 added support for <a href="https://www.cgl.ucsf.edu/chimera/">Chimera</a>,
-provided this has been separately installed. Choice of default viewer is configurable in the Preferences <a href="preferences.html#structure">Structure tab</a>. 
-  
-<p>The following menu entries are provided for viewing structure data<br>
+       <p>
+               Jalview can view protein structures associated with a sequence via the
+               <strong>"Structure&rarr;"</strong> submenu from a sequence's <a
+                       href="../menus/popupMenu.html">pop-up menu</a>.
+       </p>
+       The
+       <a href="jmol.html">Jmol viewer</a> has been included since Jalview
+       2.3. Jalview 2.8.2 included support for
+       <a href="https://www.cgl.ucsf.edu/chimera/">Chimera</a>, provided it is
+       installed and can be launched by Jalview. The default viewer can be
+       configured in the
+       <a href="preferences.html#structure">Structure tab</a> in the
+       <strong>Tools&rarr;Preferences</strong> dialog box.
+       <p>
+               Structure data imported into Jalview can also be processed to display
+               secondary structure and temperature factor annotation. See the <a
+                       href="xsspannotation.html">Annotation from Structure</a> page for
+               more information.
+       </p>
+       <p>The following menu entries are provided for viewing structure data<br>
   <ul>
     <li>The <strong>&quot;Structure&#8594;View
         Structure&#8594;</strong> submenu allows a single PDB structure to be chosen
diff --git a/help/html/features/xsspannotation.html b/help/html/features/xsspannotation.html
new file mode 100644 (file)
index 0000000..0dc7475
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 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.
+ -->
+<head>
+<title>Annotation from 3D structure data</title>
+</head>
+<body>
+       <p>
+               <strong>Working with annotation from 3D structure data</strong>
+       </p>
+       <p>
+               Jalview can process PDB data associated with sequences to display
+               values extracted from the <em>Temperature Factor</em> column for
+               corresponding sites, and secondary structure from DSSP or RNAView (as
+               appropriate).
+       </p>
+       <p>
+               <strong>Extracting data from PDB files<br /></strong>Annotation is
+               created for structure files retrieved directly from the PDB loaded
+               from the file system (via the <strong>Structure&rarr;Associate
+                       Structure...&rarr;From file</strong> option, or when displayed via the View
+               Structures Menu.<br /> Structure annotation is not automatically
+               added to an alignment, but any available structure annotation rows for
+               the current selection or a particular sequence can be added via the <strong>Add
+                       Reference Annotation</strong> in the <strong>Selection</strong> and <strong>Sequence
+                       ID</strong> sub-menus of the Sequence ID Panel's popup menu.<br/> <em>Please
+                       note:</em>Protein structures are analysed
+               <em>in situ</em>, but Jalview employs a web service to process RNA
+               structures which can cause long delays if your internet connection is
+               slow.
+       </p>
+       <p>
+               The <a href="../menus/alwannotation.html"><em>Annotations</em>
+                       alignment menu</a> provides settings useful for controlling the display
+               of secondary structure annotation.
+       </p>
+       <p>
+               <strong>Shading sequences by associated structure annotation<br /></strong>The
+               annotation colouring dialog (opened by the <strong>Colour&rarr;By
+                       Annotation</strong> option) allows sequences with associated secondary
+               structure data to be shaded according to secondary structure type.
+               Once the dialog is opened, select the <em>Per Sequence</em> option and
+               then choose <em>Secondary structure</em> from the dropdown menu.<br />When
+               colouring alignments by secondary structure, two modes can be
+               employed. The default is to shade sequences with the same colour as
+               the secondary structure glyph. If, however, <em>original colours</em>
+               is selected and another colourscheme has already been applied, then
+               only portions of the sequence with defined secondary structure will be
+               shaded with the previously applied scheme.<br />
+       </p>
+       <p>
+               <strong>Configuration options for processing PDB files<br /></strong>
+               Occasionally, you may wish to disable secondary structure processing. 
+               Configuration options in the <strong>Structure</strong> tab in the <strong>Tools&rarr;Preferences</strong>
+               dialog allow the processing of structure data to be disabled, or
+               selectively enabled. For more information, take a look at the <a href="preferences.html#structure">documentation for the structure panel</a>.
+       </p>
+       <p>
+               <em>The display of secondary structure data was introduced in
+                       Jalview 2.8.2, and is made possible by Jalview's use of <a
+                       href="jmol.html">Jmol's DSSP implementation</a>, based on the
+                       original <a href="http://www.ncbi.nlm.nih.gov/pubmed/6667333">Kabsch
+                               and Sander algorithm</a> ported by <a
+                       href="http://swift.cmbi.ru.nl/gv/dssp/">Robbie P. Joosten and
+                               colleagues</a>, and a client for <a
+                       href="https://github.com/fjossinet/PyRNA">Fabrice Jossinet's
+                               pyRNA services</a> that was developed by Anne Menard, Jim Procter and
+                       Yann Ponty as part of the Jalview Summer of Code 2012.
+               </em>
+       </p>
+</body>
+</html>
index 511b85f..63bb815 100755 (executable)
@@ -41,7 +41,7 @@ not be accessible when in 'Cursor Mode' (toggled with the F2 key).</em></p>
       <li><strong>Hide Annotations...<br>
           </strong><em>Choose to hide either All or 
           a selected type of annotation for the selected sequences. (Since Jalview 2.8.2)</em></li>
-      <li><strong>Add Reference Annotations...<br>
+      <li><a name="addrefannot"><strong>Add Reference Annotations<br>
           </strong><em>Add to the alignment window any annotations on the selected sequences
           which have been read from reference sources or calculated (for example, 
           secondary structure derived from 3D structure). (Since Jalview 2.8.2)</em></li>
@@ -134,7 +134,7 @@ not be accessible when in 'Cursor Mode' (toggled with the F2 key).</em></p>
         window will be displayed asking for a new sequence name and sequence description 
         to be entered. Press OK to accept your edit. To save sequence descriptions, 
         you must save in Fasta, PIR or Jalview File format.</em></li>
-      <li><em> </em></li>
+      <li><a href="sqaddrefannot"><strong>Add Reference Annotations<br></strong><em>When enabled, copies any available alignment annotation for this sequence to the current view.</em></li>
       <li><strong>Represent Group With (Sequence Id)</strong><br>
         <em>All sequences in the current selection group will be hidden, apart 
         from (Sequence Id). Any edits performed on the visible representative 
index 6b92a2c..8913a32 100755 (executable)
        </tr>
                <tr>
                        <td><div align="center">
+                                       <strong><a name="Jalview.2.8.2">2.8.2</a><br /> <em>18/11/2014</em></strong>
+                               </div></td>
+                       <td>
+                               <!--  New features --> <!--  For major releases, split into sections: Application | Applet | General | Deployment and Documentation -->
+                               <em>General</em>
+                               <ul>
+                               </ul> <em>Application</em>
+                               <ul>
+                                       <li>Update Jalview project format:
+                                               <ul>
+                                               </ul>
+                                       </li>
+                               </ul>
+                       </td>
+                       <td>
+                               <!--  issues resolved --> <em>Application</em>
+                               <ul>
+
+                               </ul> <em>Applet</em>
+                               <ul>
+                               </ul> <em>Other</em>
+                               <ul>
+                               </ul>
+                       </td>
+               </tr>
+               <tr>
+                       <td><div align="center">
                                        <strong><a name="Jalview.2.8.1">2.8.1</a><br /> <em>4/6/2014</em></strong>
                                </div></td>
                        <td>
index 9a7acd9..5555c73 100755 (executable)
@@ -110,10 +110,11 @@ The annotation bars below the alignment are as follows:
        invoked to rationalise significantly different primary predictions.</em></li>
 </ul>
 </p>
+<em>JNet annotation created in Jalview 2.8.2 and later versions can be displayed on other alignments via the <a href="">Add reference annotation</a></em>
 <em>As of Jalview 2.6, the Jnet service accessed accessed via the
 'Secondary structure prediction' submenu should be considered a legacy
 Jalview SOAP service, and will be replaced in the near future by a
-JABAWS Jnet service.</em>
+JABAWS Jnet service (now available in the Jalview 2.9 development version).</em>
 
 </body>
 </html>
index dd536b1..ae45aae 100755 (executable)
 </head>
 <body>
        <p>
-               <strong>What's new ?</strong></p>
-       <p>
-               Jalview 2.8.1 includes new features for group creation, RNA secondary
-               structure prediction and a host bug fixes. It also includes support
-               for <a href="http://www.compbio.dundee.ac.uk/JABAWS">version 2.1
-                       of JABA</a> and includes a Spanish translation of its user interface.<br />
-               The highlights are detailed below, and the full list is given in the <a
-                       href="releases.html#Jalview2.8.1">Jalview 2.8.1 Release Notes</a>.
-       </p>
-       <p>The Desktop and web based applet include new keystrokes for
-               defining and undefining groups, and PAM250 has been added to the range
-               of score models available for use by the tree and PCA calculations.
-               The Jalview project file format has also been extended for handling
-               RNA and protein secondary structure annotation, in anticipation for
-               new structure based secondary structure support in Jalview 2.8.2.</p>
-       <p><strong>Internationalisation</strong></p>
-       <p>Jalview 2.8.1 is the first release to include support for
-               displaying Jalview's user interface in different languages. In August
-               2013, David Rold&aacute;n-Martinez took on the task of
-               internationalising Jalview's user interface. He also recruited Sara
-               Hern&aacute;ndez D&iacute;az and Laura Ferrandis Martinez who created
-               Jalview's first spanish user interface translation.</p>
-       <p>
-               If you notice any problems, or would like to help translate Jalview's
-               user interface into other languages, head over to <a
-                       href="http://issues.jalview.org">issues.jalview.org</a> and put in a
-               feature request describing the translations you can provide to the <a
-                       href="http://issues.jalview.org/browse/JAL/component/10682">i18n
-                       component</a>. David has also <a
-                       href="https://wiki.jalview.org/index.php/Development:i18n">documented
-                       the process of creating i18n translations</a> to help you get started.
+               <strong>What's new ?</strong>
        </p>
-       <p><strong>RNA Secondary Structure Prediction with JABA 2.1</strong></p>
-       <p>
-               This version of Jalview includes a client to access the new services available in <a
-                       href="http://www.compbio.dundee.ac.uk/jabaws/">JABA v2.1</a> , which
-               provides services for RNA consensus secondary structure prediction and
-               two new alignment programs (<a
-                       href="http://sourceforge.net/projects/glprobs/">GLProbs</a> and <a
-                       href="http://sourceforge.net/projects/msaprobs/">MSAProbs</a>).</p>
        <p>
-               To see how to perform RNA secondary structure predictions like the one below, take a look at the <a href="webServices/RNAalifold.html">RNAAliFold
-                       client documentation</a>. 
+               Jalview 2.8.2 is the first release produced by our new core
+               development team.<br /> It incorporates many minor improvements and
+               bug-fixes, and also includes new features for working with 3D
+               structure data, shading alignments by secondary structure and
+               generation of alignment figures as Scalable Vector Graphics. <br />As
+               ever, the highlights are detailed below, and the full list is given in
+               the <a href="releases.html#Jalview2.8.2">Jalview 2.8.2 Release
+                       Notes</a>.
        </p>
-  <div align="center">
-    <img src="webServices/RNAalifoldAnnotationRows.png" width="500" height="216"> <br> <em>The RNAalifold client was implemented by Jalview's 2013
-                       summer student, Dan Barton.</em>
-       </div>
 </body>
 </html>
index 511e5e9..cabee76 100644 (file)
@@ -107,7 +107,7 @@ action.change_params = Change Parameters
 action.apply = Apply
 action.apply_threshold_all_groups = Apply threshold to all groups
 action.apply_all_groups = Apply to all Groups
-action.by_chain = By chain
+action.by_chain = By Chain
 action.by_sequence = By Sequence
 action.paste_annotations = Paste Annotations
 action.format = Format
@@ -249,8 +249,8 @@ label.autoadd_secstr = Add secondary structure annotation to alignment
 label.autoadd_temp = Add Temperature Factor annotation to alignment
 label.structure_viewer = Default structure viewer
 label.chimera_path = Path to Chimera program
-label.chimera_path_tip = Jalview will try standard locations, plus any path entered here.
-label.invalid_path = File not found or not executable
+label.chimera_path_tip = Jalview will first try any path entered here, else standard installation locations.<br>Double-click to browse for file.
+label.invalid_chimera_path = Chimera path not found or not executable
 label.min_colour = Minimum Colour
 label.max_colour = Maximum Colour
 label.use_original_colours = Use Original Colours
@@ -344,7 +344,7 @@ label.dont_ask_me_again = Don't ask me again
 label.select_eps_character_rendering_style = Select EPS character rendering style
 label.invert_selection = Invert Selection
 label.optimise_order = Optimise Order
-label.seq_sort_by_score = Seq sort by Score
+label.seq_sort_by_score = Sequence sort by Score
 label.load_colours = Load Colours
 label.save_colours = Save Colours
 label.fetch_das_features = Fetch DAS Features
@@ -778,7 +778,9 @@ label.services_at = Services at {0}
 label.rest_client_submit = {0} using {1}
 label.fetch_retrieve_from =Retrieve from {0}</html>
 label.fetch_retrieve_from_all_sources = Retrieve from all {0} sources in {1}<br>First is :{2}<html> 
-label.feature_settings_click_drag = <html>Click/drag feature types up or down to change render order.<br/>Double click to select columns containing feature in alignment/current selection<br/>Pressing Alt will select columns outside features rather than inside<br/>Pressing Shift to modify current selection (rather than clear current selection)<br/>Press CTRL or Command/Meta to toggle columns in/outside features<br/></html>
+#label.feature_settings_click_drag = <html>Click/drag feature types up or down to change render order.<br/>Double click to select columns containing feature in alignment/current selection<br/>Pressing Alt will select columns outside features rather than inside<br/>Pressing Shift to modify current selection (rather than clear current selection)<br/>Press CTRL or Command/Meta to toggle columns in/outside features<br/></html>
+label.feature_settings_click_drag = Drag up or down to change render order.<br/>Double click to select columns containing feature.
+label.transparency_tip = Adjust transparency to 'see through' feature colours.
 label.opt_and_params_further_details = see further details by right-clicking
 label.opt_and_params_show_brief_desc_image_link = <html>Click to show brief description<br><img src="{0}"/> Right click for further information.</html> 
 label.opt_and_params_show_brief_desc = <html>Click to show brief description<br></html>
index a1663d9..dc403d0 100644 (file)
@@ -748,7 +748,7 @@ label.services_at = Servicios en {0}
 label.rest_client_submit = {0} utilizando {1}
 label.fetch_retrieve_from =Recuperar de {0}
 label.fetch_retrieve_from_all_sources = Recuperar de todas las fuentes {0} en {1}<br>La primera es :{2}
-label.feature_settings_click_drag = Haga clic o arrastre los tipos de las características hacia arriba o hacia abajo para cambiar el orden de visualización.<br/>Haga doble clic para seleccionar las columnas que contienen las características del alineamiento/selección actual.<br/>Presionando Alt seleccionará las columnas exteriores a las características en lugar de las interiores<br/>Presione Shift para modificar la selección actual (en lugar de borrarla)<br/>Presione CTRL o Command/Meta para cambiar las columans externas o internas a las características<br/>
+label.feature_settings_click_drag = Haga clic o arrastre los tipos de las características hacia arriba o hacia abajo para cambiar el orden de visualización.<br/>Haga doble clic para seleccionar las columnas que contienen las características del alineamiento/selección actual.<br/>
 label.opt_and_params_further_details = ver los detalles adicionales haciendo clic en el botón derecho
 label.opt_and_params_show_brief_desc_image_link = Haga clic para ver una descripción breve<br><img src="{0}"/>Haga clic en el botón derecho para obtener información adicional.
 label.opt_and_params_show_brief_desc = Haga clic para ver una descripción breve<br>
index 2dd6d37..408108b 100755 (executable)
@@ -267,7 +267,7 @@ public class PDBChain
     bonds.addElement(new Bond(start, end, at1, at2));
   }
 
-  public void makeResidueList()
+  public void makeResidueList(boolean visibleChainAnnotation)
   {
     int count = 0;
     Object symbol;
@@ -377,23 +377,27 @@ public class PDBChain
               .elementAt(i));
       resFeatures.setElementAt(null, i);
     }
-    Annotation[] annots = new Annotation[resAnnotation.size()];
-    float max = 0;
-    for (i = 0, iSize = annots.length; i < iSize; i++)
+    if (visibleChainAnnotation)
     {
-      annots[i] = (Annotation) resAnnotation.elementAt(i);
-      if (annots[i].value > max)
+      Annotation[] annots = new Annotation[resAnnotation.size()];
+      float max = 0;
+      for (i = 0, iSize = annots.length; i < iSize; i++)
       {
-        max = annots[i].value;
+        annots[i] = (Annotation) resAnnotation.elementAt(i);
+        if (annots[i].value > max)
+        {
+          max = annots[i].value;
+        }
+        resAnnotation.setElementAt(null, i);
       }
-      resAnnotation.setElementAt(null, i);
+
+      AlignmentAnnotation tfactorann = new AlignmentAnnotation(
+              "Temperature Factor", "Temperature Factor for " + pdbid + id,
+              annots, 0, max,
+              AlignmentAnnotation.LINE_GRAPH);
+      tfactorann.setSequenceRef(sequence);
+      sequence.addAlignmentAnnotation(tfactorann);
     }
-    AlignmentAnnotation tfactorann = new AlignmentAnnotation(
-            "PDB.TempFactor", "Temperature Factor for "
-                    + sequence.getName(), annots, 0, max,
-            AlignmentAnnotation.LINE_GRAPH);
-    tfactorann.setSequenceRef(sequence);
-    sequence.addAlignmentAnnotation(tfactorann);
   }
 
   public void setChargeColours()
@@ -548,34 +552,37 @@ public class PDBChain
         }
       }
       }
-      float min = -1, max = 0;
-      Annotation[] an = new Annotation[sq.getEnd() - sq.getStart() + 1];
-      for (int i = sq.getStart(), j = sq.getEnd(), k = 0; i <= j; i++, k++)
+      if (false)
       {
-        int prn = mapping.getPDBResNum(k + 1);
-
-        an[k] = new Annotation(prn);
-        if (min == -1)
-        {
-          min = k;
-          max = k;
-        }
-        else
+        // Useful for debugging mappings - adds annotation for mapped position
+        float min = -1, max = 0;
+        Annotation[] an = new Annotation[sq.getEnd() - sq.getStart() + 1];
+        for (int i = sq.getStart(), j = sq.getEnd(), k = 0; i <= j; i++, k++)
         {
-          if (min > k)
+          int prn = mapping.getPDBResNum(k + 1);
+
+          an[k] = new Annotation(prn);
+          if (min == -1)
           {
             min = k;
+            max = k;
           }
-          else if (max < k)
+          else
           {
-            max = k;
+            if (min > k)
+            {
+              min = k;
+            }
+            else if (max < k)
+            {
+              max = k;
+            }
           }
         }
+        sq.addAlignmentAnnotation(new AlignmentAnnotation("PDB.RESNUM",
+                "PDB Residue Numbering for " + this.pdbid + ":" + this.id,
+                an, min, max, AlignmentAnnotation.LINE_GRAPH));
       }
-      sq.addAlignmentAnnotation(new AlignmentAnnotation("PDB.RESNUM",
-              "PDB Residue Numbering for " + this.pdbid + ":" + this.id,
-              an, min, max, AlignmentAnnotation.LINE_GRAPH));
-
     }
   }
 }
index d3535c0..bf285b9 100755 (executable)
@@ -113,7 +113,7 @@ public class PDBViewer extends JInternalFrame implements Runnable
       try
       {
         tmpPDBFile = pdbentry.getFile();
-        PDBfile pdbfile = new PDBfile(false,false,tmpPDBFile,
+        PDBfile pdbfile = new PDBfile(false, false, false, tmpPDBFile,
                 jalview.io.AppletFormatAdapter.FILE);
 
         pdbcanvas.init(pdbentry, seq, chains, ap, protocol);
index b22eb29..691fdcd 100755 (executable)
@@ -47,32 +47,38 @@ public class PDBfile extends jalview.io.AlignFile
    */
   boolean VisibleChainAnnotation = false;
 
-  boolean processSecondaryStructure=true;
-  
+  boolean processSecondaryStructure = true;
+
+  boolean externalSecondaryStructure = false;
 
   public PDBfile(boolean visibleChainAnnotation,
-          boolean processSecondaryStructure)
+          boolean processSecondaryStructure, boolean externalSecStr)
   {
     super();
     VisibleChainAnnotation = visibleChainAnnotation;
     this.processSecondaryStructure = processSecondaryStructure;
+    this.externalSecondaryStructure = externalSecStr;
   }
 
   public PDBfile(boolean visibleChainAnnotation,
-          boolean processSecondaryStructure, String file, String protocol) throws IOException
+          boolean processSecondaryStructure, boolean externalSecStr,
+          String file, String protocol) throws IOException
   {
     super(false, file, protocol);
     VisibleChainAnnotation = visibleChainAnnotation;
     this.processSecondaryStructure = processSecondaryStructure;
+    this.externalSecondaryStructure = externalSecStr;
     doParse();
   }
 
   public PDBfile(boolean visibleChainAnnotation,
-          boolean processSecondaryStructure, FileParse source) throws IOException
+          boolean processSecondaryStructure, boolean externalSecStr,
+          FileParse source) throws IOException
   {
     super(false, source);
     VisibleChainAnnotation = visibleChainAnnotation;
     this.processSecondaryStructure = processSecondaryStructure;
+    this.externalSecondaryStructure = externalSecStr;
     doParse();
   }
 
@@ -189,8 +195,7 @@ public class PDBfile extends jalview.io.AlignFile
         entry.setProperty(new Hashtable());
         if (chains.elementAt(i).id != null)
         {
-          entry.getProperty().put("CHAIN",
-                  chains.elementAt(i).id);
+          entry.getProperty().put("CHAIN", chains.elementAt(i).id);
         }
         if (inFile != null)
         {
@@ -217,7 +222,7 @@ public class PDBfile extends jalview.io.AlignFile
 
         AlignmentAnnotation[] chainannot = chainseq.getAnnotation();
 
-        if (chainannot != null)
+        if (chainannot != null && VisibleChainAnnotation)
         {
           for (int ai = 0; ai < chainannot.length; ai++)
           {
@@ -228,34 +233,34 @@ public class PDBfile extends jalview.io.AlignFile
       }
       if (processSecondaryStructure)
       {
-      if (rna.size() > 0)
-      {
-        try
+        if (externalSecondaryStructure && rna.size() > 0)
         {
-          processPdbFileWithAnnotate3d(rna);
-        } catch (Exception x)
-        {
-          System.err
-                  .println("Exceptions when dealing with RNA in pdb file");
-          x.printStackTrace();
+          try
+          {
+            processPdbFileWithAnnotate3d(rna);
+          } catch (Exception x)
+          {
+            System.err
+                    .println("Exceptions when dealing with RNA in pdb file");
+            x.printStackTrace();
 
+          }
         }
-      }
-      ;
-      if (prot.size() > 0)
-      {
-        try
+        ;
+        if (prot.size() > 0)
         {
-          processPdbFileWithJmol(prot);
-        } catch (Exception x)
-        {
-          System.err
-                  .println("Exceptions from Jmol when processing data in pdb file");
-          x.printStackTrace();
+          try
+          {
+            processPdbFileWithJmol(prot);
+          } catch (Exception x)
+          {
+            System.err
+                    .println("Exceptions from Jmol when processing data in pdb file");
+            x.printStackTrace();
 
+          }
         }
       }
-      }
     } catch (OutOfMemoryError er)
     {
       System.out.println("OUT OF MEMORY LOADING PDB FILE");
@@ -277,11 +282,11 @@ public class PDBfile extends jalview.io.AlignFile
 
   public static boolean isCalcIdHandled(String calcId)
   {
-    return calcId != null
- && (calcIdPrefix.equals(calcId));
+    return calcId != null && (calcIdPrefix.equals(calcId));
   }
 
-  public static boolean isCalcIdForFile(AlignmentAnnotation alan, String pdbFile)
+  public static boolean isCalcIdForFile(AlignmentAnnotation alan,
+          String pdbFile)
   {
     return alan.getCalcId() != null
             && calcIdPrefix.equals(alan.getCalcId())
@@ -301,19 +306,23 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (SequenceI sq : seqs)
     {
-      for (AlignmentAnnotation aa : sq.getAnnotation())
+      if (sq.getAnnotation() != null)
       {
-        String oldId = aa.getCalcId();
-        if (oldId == null)
+        for (AlignmentAnnotation aa : sq.getAnnotation())
         {
-          oldId = "";
+          String oldId = aa.getCalcId();
+          if (oldId == null)
+          {
+            oldId = "";
+          }
+          aa.setCalcId(calcIdPrefix);
+          aa.setProperty("PDBID", id);
+          aa.setProperty("oldCalcId", oldId);
         }
-        aa.setCalcId(calcIdPrefix);
-        aa.setProperty("PDBID", id);
-        aa.setProperty("oldCalcId", oldId);
       }
     }
   }
+
   private void processPdbFileWithJmol(ArrayList<SequenceI> prot)
           throws Exception
   {
@@ -352,8 +361,8 @@ public class PDBfile extends jalview.io.AlignFile
           AlignmentI al, String pep, boolean b)
   {
     List<List<? extends Object>> replaced = AlignSeq
-            .replaceMatchingSeqsWith(seqs,
-            annotations, prot, al, AlignSeq.PEP, false);
+            .replaceMatchingSeqsWith(seqs, annotations, prot, al, pep,
+                    false);
     for (PDBChain ch : chains)
     {
       int p = 0;
@@ -371,8 +380,7 @@ public class PDBfile extends jalview.io.AlignFile
         p = -p - 1;
         // set shadow entry for chains
         ch.shadow = (SequenceI) replaced.get(1).get(p);
-        ch.shadowMap = ((AlignSeq) replaced.get(2)
-.get(p))
+        ch.shadowMap = ((AlignSeq) replaced.get(2).get(p))
                 .getMappingFromS1(false);
       }
     }
@@ -445,7 +453,7 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      chains.elementAt(i).makeResidueList();
+      chains.elementAt(i).makeResidueList(VisibleChainAnnotation);
     }
   }
 
@@ -490,8 +498,8 @@ public class PDBfile extends jalview.io.AlignFile
   {
     for (int i = 0; i < chains.size(); i++)
     {
-      chains.elementAt(i).setChainColours(Color.getHSBColor(
-              1.0f / i, .4f, 1.0f));
+      chains.elementAt(i).setChainColours(
+              Color.getHSBColor(1.0f / i, .4f, 1.0f));
     }
   }
 
index 307a06f..ba7e520 100755 (executable)
@@ -1153,7 +1153,7 @@ public class AlignSeq
               ap++;
             }
           }
-          if (sq.getAnnotation() != null)
+          if (sq.getAnnotation() != null && sq.getAnnotation().length > 0)
           {
             annotations.addAll(inspos, Arrays.asList(sq.getAnnotation()));
           }
index a5d2164..81398eb 100644 (file)
@@ -209,6 +209,10 @@ public class AnnotationSorter
   public void sort(AlignmentAnnotation[] alignmentAnnotations,
           SequenceAnnotationOrder order)
   {
+    if (alignmentAnnotations == null)
+    {
+      return;
+    }
     // cache 'alignment sequence position' for the annotations
     saveSequenceIndices(alignmentAnnotations);
 
index e4a0d76..227bf09 100644 (file)
 
 package jalview.analysis;
 
+import jalview.analysis.SecStrConsensus.SimpleBP;
+import jalview.datamodel.SequenceFeature;
+import jalview.util.MessageManager;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -33,10 +37,6 @@ import java.util.Hashtable;
 import java.util.Stack;
 import java.util.Vector;
 
-import jalview.analysis.SecStrConsensus.SimpleBP;
-import jalview.datamodel.SequenceFeature;
-import jalview.util.MessageManager;
-
 public class Rna
 {
 
@@ -65,7 +65,7 @@ public class Rna
     {
       for (int i = 0; i < openingPars.length; i++)
       {
-        System.out.println(closingPars[i] + "->" + openingPars[i]);
+        // System.out.println(closingPars[i] + "->" + openingPars[i]);
         put(closingPars[i], openingPars[i]);
       }
     }
@@ -107,7 +107,6 @@ public class Rna
   public static Vector<SimpleBP> GetSimpleBPs(CharSequence line)
           throws WUSSParseException
   {
-    System.out.println(line);
     Hashtable<Character, Stack<Integer>> stacks = new Hashtable<Character, Stack<Integer>>();
     Vector<SimpleBP> pairs = new Vector<SimpleBP>();
     int i = 0;
index eba1200..98a4a1c 100644 (file)
  */
 package jalview.appletgui;
 
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import jalview.analysis.*;
-import jalview.commands.*;
-import jalview.datamodel.*;
-import jalview.schemes.*;
-import jalview.util.MessageManager;
-import jalview.util.UrlLink;
+import jalview.analysis.AAFrequency;
+import jalview.analysis.Conservation;
+import jalview.commands.ChangeCaseCommand;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.SequenceAnnotationReport;
+import jalview.schemes.Blosum62ColourScheme;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.ClustalxColourScheme;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.NucleotideColourScheme;
+import jalview.schemes.PIDColourScheme;
+import jalview.schemes.ResidueProperties;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TaylorColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.schemes.ZappoColourScheme;
+import jalview.util.MessageManager;
+import jalview.util.UrlLink;
+
+import java.awt.CheckboxMenuItem;
+import java.awt.Frame;
+import java.awt.Menu;
+import java.awt.MenuItem;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.Vector;
 
 public class APopupMenu extends java.awt.PopupMenu implements
         ActionListener, ItemListener
@@ -549,7 +573,9 @@ public class APopupMenu extends java.awt.PopupMenu implements
       if (sg != null)
       {
         if (seq == null)
+        {
           seq = (Sequence) sg.getSequenceAt(0);
+        }
 
         EditNameDialog dialog = new EditNameDialog(seq.getSequenceAsString(
                 sg.getStartRes(), sg.getEndRes() + 1), null,
@@ -560,7 +586,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
         if (dialog.accept)
         {
           EditCommand editCommand = new EditCommand(MessageManager.getString("label.edit_sequences"),
-                  EditCommand.REPLACE, dialog.getName().replace(' ',
+                  Action.REPLACE, dialog.getName().replace(' ',
                           ap.av.getGapCharacter()),
                   sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
                   sg.getStartRes(), sg.getEndRes() + 1,
@@ -742,11 +768,15 @@ public class APopupMenu extends java.awt.PopupMenu implements
       PDBEntry entry = (PDBEntry) seq.getPDBId().firstElement();
 
       if (ap.av.applet.jmolAvailable)
+      {
         new jalview.appletgui.AppletJmol(entry, new Sequence[]
         { seq }, null, ap, AppletFormatAdapter.URL);
+      }
       else
+      {
         new MCview.AppletPDBViewer(entry, new Sequence[]
         { seq }, null, ap, AppletFormatAdapter.URL);
+      }
 
     }
     else
index 34ec2cf..ed64215 100644 (file)
@@ -27,6 +27,7 @@ import jalview.api.SequenceStructureBinding;
 import jalview.bin.JalviewLite;
 import jalview.commands.CommandI;
 import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
 import jalview.commands.OrderCommand;
 import jalview.commands.RemoveGapColCommand;
 import jalview.commands.RemoveGapsCommand;
@@ -1833,7 +1834,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     }
 
     // !newAlignment
-    addHistoryItem(new EditCommand(MessageManager.getString("label.add_sequences"), EditCommand.PASTE,
+    addHistoryItem(new EditCommand(
+            MessageManager.getString("label.add_sequences"), Action.PASTE,
             seqs, 0, viewport.getAlignment().getWidth(),
             viewport.getAlignment()));
 
@@ -1883,8 +1885,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     /*
      * //ADD HISTORY ITEM
      */
-    addHistoryItem(new EditCommand(MessageManager.getString("label.cut_sequences"), EditCommand.CUT, cut,
-            sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
+    addHistoryItem(new EditCommand(
+            MessageManager.getString("label.cut_sequences"), Action.CUT,
+            cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
             viewport.getAlignment()));
 
     viewport.setSelectionGroup(null);
index 4b9fa67..22996f7 100755 (executable)
@@ -256,7 +256,9 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
           anot[index] = new Annotation(label, "", type, 0);
         }
 
-        anot[index].secondaryStructure = type;
+        
+        anot[index].secondaryStructure = type != 'S' ? type : label
+                .length() == 0 ? ' ' : label.charAt(0);
         anot[index].displayCharacter = label;
       }
     }
index 1547862..8e364f0 100644 (file)
  */
 package jalview.appletgui;
 
-import java.util.*;
-import java.util.List;
-import java.awt.*;
-import java.awt.event.*;
-
 import jalview.analysis.AlignSeq;
-import jalview.commands.*;
-import jalview.datamodel.*;
+import jalview.commands.CommandI;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
 import jalview.util.MessageManager;
 
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
 public class RedundancyPanel extends SliderPanel implements Runnable,
         WindowListener
 {
@@ -197,7 +207,7 @@ public class RedundancyPanel extends SliderPanel implements Runnable,
       }
 
       EditCommand cut = new EditCommand(MessageManager.getString("action.remove_redundancy"),
-              EditCommand.CUT, deleted, 0, width, ap.av.getAlignment());
+              Action.CUT, deleted, 0, width, ap.av.getAlignment());
       AlignmentI alignment = ap.av.getAlignment();
       for (int i = 0; i < del.size(); i++)
       {
index de4d979..592fd4f 100644 (file)
  */
 package jalview.appletgui;
 
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import jalview.commands.*;
-import jalview.datamodel.*;
-import jalview.schemes.*;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
 import jalview.structure.SelectionSource;
 import jalview.structure.SequenceListener;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Panel;
+import java.awt.Point;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.Vector;
+
 public class SeqPanel extends Panel implements MouseMotionListener,
         MouseListener, SequenceListener
 {
@@ -147,7 +159,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
   void setCursorPosition()
   {
-    SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(
+    SequenceI sequence = av.getAlignment().getSequenceAt(
             seqCanvas.cursorY);
 
     seqCanvas.cursorX = sequence.findIndex(getKeyboardNo1()) - 1;
@@ -240,7 +252,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
   void setSelectionAreaAtCursor(boolean topLeft)
   {
-    SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(
+    SequenceI sequence = av.getAlignment().getSequenceAt(
             seqCanvas.cursorY);
 
     if (av.getSelectionGroup() != null)
@@ -648,7 +660,9 @@ public class SeqPanel extends Panel implements MouseMotionListener,
   {
     String tmp = sequence.hashCode() + index + "";
     if (lastMessage == null || !lastMessage.equals(tmp))
+    {
       ssm.mouseOverSequence(sequence, index, pos, av);
+    }
 
     lastMessage = tmp;
   }
@@ -698,7 +712,9 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
     int respos = sequence.findPosition(res);
     if (ssm != null)
+    {
       mouseOverSequence(sequence, res, respos);
+    }
 
     StringBuffer text = new StringBuffer("Sequence " + (seq + 1) + " ID: "
             + sequence.getName());
@@ -813,7 +829,9 @@ public class SeqPanel extends Panel implements MouseMotionListener,
                         .containsKey(features[i].featureGroup)
                 && !((Boolean) seqCanvas.fr.featureGroups
                         .get(features[i].featureGroup)).booleanValue())
+        {
           continue;
+        }
 
         if ((features[i].getBegin() <= res)
                 && (features[i].getEnd() >= res))
@@ -938,7 +956,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     {
       if (av.isHiddenRepSequence(seq))
       {
-        sg = (SequenceGroup) av.getRepresentedSequences(seq);
+        sg = av.getRepresentedSequences(seq);
         groupEditing = true;
       }
     }
@@ -1164,7 +1182,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, groupSeqs,
+          editCommand.appendEdit(Action.INSERT_GAP, groupSeqs,
                   startres, startres - lastres, av.getAlignment(), true);
         }
       }
@@ -1180,7 +1198,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.DELETE_GAP, groupSeqs,
+          editCommand.appendEdit(Action.DELETE_GAP, groupSeqs,
                   startres, lastres - startres, av.getAlignment(), true);
         }
 
@@ -1202,7 +1220,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, new SequenceI[]
+          editCommand.appendEdit(Action.INSERT_GAP, new SequenceI[]
           { seq }, lastres, startres - lastres, av.getAlignment(), true);
         }
       }
@@ -1237,7 +1255,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
           if (max > 0)
           {
-            editCommand.appendEdit(EditCommand.DELETE_GAP, new SequenceI[]
+            editCommand.appendEdit(Action.DELETE_GAP, new SequenceI[]
             { seq }, startres, max, av.getAlignment(), true);
           }
         }
@@ -1273,10 +1291,10 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       }
     }
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, blankColumn, 1,
+    editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1,
             av.getAlignment(), true);
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, j, 1,
+    editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1,
             av.getAlignment(), true);
 
   }
@@ -1284,10 +1302,10 @@ public class SeqPanel extends Panel implements MouseMotionListener,
   void deleteChar(int j, SequenceI[] seq, int fixedColumn)
   {
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, j, 1,
+    editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1,
             av.getAlignment(), true);
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, fixedColumn, 1,
+    editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1,
             av.getAlignment(), true);
   }
 
@@ -1312,7 +1330,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       return;
     }
 
-    SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(seq);
+    SequenceI sequence = av.getAlignment().getSequenceAt(seq);
 
     if (sequence == null || res > sequence.getLength())
     {
index 24ed1b4..3b0a23e 100755 (executable)
@@ -150,6 +150,7 @@ import org.apache.log4j.SimpleLayout;
  * <li>FOLLOW_SELECTIONS (true) Controls whether a new alignment view should
  * respond to selections made in other alignments containing the same sequences.
  * </li>
+ * <li>JWS2HOSTURLS comma-separated list of URLs to try for JABAWS services</li>
  * <li>SHOW_WSDISCOVERY_ERRORS (true) Controls if the web service URL discovery
  * warning dialog box is displayed.</li>
  * <li>ANNOTATIONCOLOUR_MIN (orange) Shade used for minimum value of annotation
index 184c267..f80f341 100755 (executable)
@@ -24,6 +24,7 @@ import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.ws.jws2.Jws2Discoverer;
 
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -34,6 +35,7 @@ import java.io.IOException;
 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;
@@ -106,40 +108,7 @@ public class Jalview
 
     if (aparser.contains("help") || aparser.contains("h"))
     {
-      System.out
-              .println("Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
-                      + "-nodisplay\tRun Jalview without User Interface.\n"
-                      + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
-                      + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
-                      + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
-                      + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
-                      + "-features FILE\tUse the given file to mark features on the alignment.\n"
-                      + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
-                      + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
-                      + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
-                      + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
-                      + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
-                      + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
-                      + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
-                      + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
-                      + "-png FILE\tCreate PNG image FILE from alignment.\n"
-                      + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
-                      + "-eps FILE\tCreate EPS file FILE from alignment.\n"
-                      + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
-                      + "-noquestionnaire\tTurn off questionnaire check.\n"
-                      + "-nousagestats\tTurn off google analytics tracking for this session.\n"
-                      + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
-                      // +
-                      // "-setprop PROPERTY=VALUE\tSet the given Jalview property, after all other properties files have been read\n\t (quote the 'PROPERTY=VALUE' pair to ensure spaces are passed in correctly)"
-                      + "-dasserver nickname=URL\tAdd and enable a das server with given nickname\n\t\t\t(alphanumeric or underscores only) for retrieval of features for all alignments.\n"
-                      + "\t\t\tSources that also support the sequence command may be specified by prepending the URL with sequence:\n"
-                      + "\t\t\t e.g. sequence:http://localdas.somewhere.org/das/source)\n"
-                      + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
-                      // +
-                      // "-vdoc vamsas-document\tImport vamsas document into new session or join existing session with same URN\n"
-                      // + "-vses vamsas-session\tJoin session with given URN\n"
-                      + "-groovy FILE\tExecute groovy script in FILE, after all other arguments have been processed (if FILE is the text 'STDIN' then the file will be read from STDIN)\n"
-                      + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
+      showUsage();
       System.exit(0);
     }
     if (aparser.contains("nodisplay") || aparser.contains("nogui")
@@ -150,6 +119,20 @@ public class Jalview
     }
     Cache.loadProperties(aparser.getValue("props")); // must do this before
     // anything else!
+
+    final String jabawsUrl = aparser.getValue("jabaws");
+    if (jabawsUrl != null)
+    {
+      try
+      {
+        Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
+      } catch (MalformedURLException e)
+      {
+        System.err.println("Invalid jabaws parameter: " + jabawsUrl
+                + " ignored");
+      }
+    }
+
     String defs = aparser.getValue("setprop");
     while (defs != null)
     {
@@ -619,6 +602,45 @@ public class Jalview
     }
   }
 
+  private static void showUsage()
+  {
+    System.out
+            .println("Usage: jalview -open [FILE] [OUTPUT_FORMAT] [OUTPUT_FILE]\n\n"
+                    + "-nodisplay\tRun Jalview without User Interface.\n"
+                    + "-props FILE\tUse the given Jalview properties file instead of users default.\n"
+                    + "-colour COLOURSCHEME\tThe colourscheme to be applied to the alignment\n"
+                    + "-annotations FILE\tAdd precalculated annotations to the alignment.\n"
+                    + "-tree FILE\tLoad the given newick format tree file onto the alignment\n"
+                    + "-features FILE\tUse the given file to mark features on the alignment.\n"
+                    + "-fasta FILE\tCreate alignment file FILE in Fasta format.\n"
+                    + "-clustal FILE\tCreate alignment file FILE in Clustal format.\n"
+                    + "-pfam FILE\tCreate alignment file FILE in PFAM format.\n"
+                    + "-msf FILE\tCreate alignment file FILE in MSF format.\n"
+                    + "-pileup FILE\tCreate alignment file FILE in Pileup format\n"
+                    + "-pir FILE\tCreate alignment file FILE in PIR format.\n"
+                    + "-blc FILE\tCreate alignment file FILE in BLC format.\n"
+                    + "-jalview FILE\tCreate alignment file FILE in Jalview format.\n"
+                    + "-png FILE\tCreate PNG image FILE from alignment.\n"
+                    + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
+                    + "-eps FILE\tCreate EPS file FILE from alignment.\n"
+                    + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
+                    + "-noquestionnaire\tTurn off questionnaire check.\n"
+                    + "-nousagestats\tTurn off google analytics tracking for this session.\n"
+                    + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
+                    // +
+                    // "-setprop PROPERTY=VALUE\tSet the given Jalview property, after all other properties files have been read\n\t (quote the 'PROPERTY=VALUE' pair to ensure spaces are passed in correctly)"
+                    + "-jabaws URL\tSpecify URL for Jabaws services (e.g. for a local installation).\n"
+                    + "-dasserver nickname=URL\tAdd and enable a das server with given nickname\n\t\t\t(alphanumeric or underscores only) for retrieval of features for all alignments.\n"
+                    + "\t\t\tSources that also support the sequence command may be specified by prepending the URL with sequence:\n"
+                    + "\t\t\t e.g. sequence:http://localdas.somewhere.org/das/source)\n"
+                    + "-fetchfrom nickname\tQuery nickname for features for the alignments and display them.\n"
+                    // +
+                    // "-vdoc vamsas-document\tImport vamsas document into new session or join existing session with same URN\n"
+                    // + "-vses vamsas-session\tJoin session with given URN\n"
+                    + "-groovy FILE\tExecute groovy script in FILE, after all other arguments have been processed (if FILE is the text 'STDIN' then the file will be read from STDIN)\n"
+                    + "\n~Read documentation in Application or visit http://www.jalview.org for description of Features and Annotations file~\n\n");
+  }
+
   private static void startUsageStats(final Desktop desktop)
   {
     /**
index 0abd31b..ae8bc98 100644 (file)
@@ -1269,7 +1269,7 @@ public class JalviewLite extends Applet implements
 
   public static boolean debug = false;
 
-  static String builddate = null, version = null;
+  static String builddate = null, version = null, installation = null;
 
   private static void initBuildDetails()
   {
@@ -1277,6 +1277,7 @@ public class JalviewLite extends Applet implements
     {
       builddate = "unknown";
       version = "test";
+      installation = "Webstart";
       java.net.URL url = JalviewLite.class
               .getResource("/.build_properties");
       if (url != null)
@@ -1296,6 +1297,10 @@ public class JalviewLite extends Applet implements
             {
               builddate = line.substring(line.indexOf("=") + 1);
             }
+            if (line.indexOf("INSTALLATION") > -1)
+            {
+              installation = line.substring(line.indexOf("=") + 1);
+            }
           }
         } catch (Exception ex)
         {
@@ -1311,6 +1316,12 @@ public class JalviewLite extends Applet implements
     return builddate;
   }
 
+  public static String getInstallation()
+  {
+    initBuildDetails();
+    return installation;
+  }
+
   public static String getVersion()
   {
     initBuildDetails();
@@ -1360,6 +1371,7 @@ public class JalviewLite extends Applet implements
 
       System.err.println("JalviewLite Version " + getVersion());
       System.err.println("Build Date : " + getBuildDate());
+      System.err.println("Installation : " + getInstallation());
 
     }
     String externalsviewer = getParameter("externalstructureviewer");
index 5c698a8..82de3b2 100644 (file)
@@ -27,8 +27,10 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 
+import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.ListIterator;
 
 /**
  * 
@@ -54,19 +56,12 @@ import java.util.List;
  */
 public class EditCommand implements CommandI
 {
-  public static final int INSERT_GAP = 0;
-
-  public static final int DELETE_GAP = 1;
-
-  public static final int CUT = 2;
-
-  public static final int PASTE = 3;
-
-  public static final int REPLACE = 4;
-
-  public static final int INSERT_NUC = 5;
+  public enum Action
+  {
+    INSERT_GAP, DELETE_GAP, CUT, PASTE, REPLACE, INSERT_NUC
+  };
 
-  Edit[] edits;
+  private List<Edit> edits = new ArrayList<Edit>();
 
   String description;
 
@@ -79,32 +74,75 @@ public class EditCommand implements CommandI
     this.description = description;
   }
 
-  public EditCommand(String description, int command, SequenceI[] seqs,
+  public EditCommand(String description, Action command, SequenceI[] seqs,
           int position, int number, AlignmentI al)
   {
     this.description = description;
-    if (command == CUT || command == PASTE)
+    if (command == Action.CUT || command == Action.PASTE)
     {
-      edits = new Edit[]
-      { new Edit(command, seqs, position, number, al) };
+      setEdit(new Edit(command, seqs, position, number, al));
     }
 
     performEdit(0, null);
   }
 
-  public EditCommand(String description, int command, String replace,
+  public EditCommand(String description, Action command, String replace,
           SequenceI[] seqs, int position, int number, AlignmentI al)
   {
     this.description = description;
-    if (command == REPLACE)
+    if (command == Action.REPLACE)
     {
-      edits = new Edit[]
-      { new Edit(command, seqs, position, number, al, replace) };
+      setEdit(new Edit(command, seqs, position, number, al, replace));
     }
 
     performEdit(0, null);
   }
 
+  /**
+   * Set the list of edits to the specified item (only).
+   * 
+   * @param e
+   */
+  protected void setEdit(Edit e)
+  {
+    edits.clear();
+    edits.add(e);
+  }
+
+  /**
+   * Add the given edit command to the stored list of commands.
+   * 
+   * @param e
+   */
+  protected void addEdit(Edit e)
+  {
+    edits.add(e);
+  }
+
+  /**
+   * Clear the list of stored edit commands.
+   * 
+   */
+  protected void clearEdits()
+  {
+    edits.clear();
+  }
+
+  /**
+   * Returns the i'th stored Edit command.
+   * 
+   * @param i
+   * @return
+   */
+  protected Edit getEdit(int i)
+  {
+    if (i >= 0 && i < edits.size())
+    {
+      return edits.get(i);
+    }
+    return null;
+  }
+
   @Override
   final public String getDescription()
   {
@@ -114,12 +152,17 @@ public class EditCommand implements CommandI
   @Override
   public int getSize()
   {
-    return edits == null ? 0 : edits.length;
+    return edits.size();
   }
 
+  /**
+   * Return the alignment for the first edit (or null if no edit).
+   * 
+   * @return
+   */
   final public AlignmentI getAlignment()
   {
-    return edits[0].al;
+    return (edits.isEmpty() ? null : edits.get(0).al);
   }
 
   /**
@@ -135,7 +178,8 @@ public class EditCommand implements CommandI
    * @param al
    * @param performEdit
    */
-  final public void appendEdit(int command, SequenceI[] seqs, int position,
+  final public void appendEdit(Action command, SequenceI[] seqs,
+          int position,
           int number, AlignmentI al, boolean performEdit)
   {
     appendEdit(command, seqs, position, number, al, performEdit, null);
@@ -153,7 +197,8 @@ public class EditCommand implements CommandI
    * @param performEdit
    * @param views
    */
-  final public void appendEdit(int command, SequenceI[] seqs, int position,
+  final public void appendEdit(Action command, SequenceI[] seqs,
+          int position,
           int number, AlignmentI al, boolean performEdit, AlignmentI[] views)
   {
     Edit edit = new Edit(command, seqs, position, number,
@@ -164,52 +209,62 @@ public class EditCommand implements CommandI
       edit.fullAlignmentHeight = true;
     }
 
-    if (edits != null)
-    {
-      Edit[] temp = new Edit[edits.length + 1];
-      System.arraycopy(edits, 0, temp, 0, edits.length);
-      edits = temp;
-      edits[edits.length - 1] = edit;
-    }
-    else
-    {
-      edits = new Edit[]
-      { edit };
-    }
+    edits.add(edit);
 
     if (performEdit)
     {
-      performEdit(edits.length - 1, views);
+      performEdit(edit, views);
     }
   }
 
+  /**
+   * Execute all the edit commands, starting at the given commandIndex
+   * 
+   * @param commandIndex
+   * @param views
+   */
   final void performEdit(int commandIndex, AlignmentI[] views)
   {
-    int eSize = edits.length;
-    for (int e = commandIndex; e < eSize; e++)
+    ListIterator<Edit> iterator = edits.listIterator(commandIndex);
+    while (iterator.hasNext())
     {
-      switch (edits[e].command)
-      {
-      case INSERT_GAP:
-        insertGap(edits[e]);
-        break;
-      case DELETE_GAP:
-        deleteGap(edits[e]);
-        break;
-      case CUT:
-        cut(edits[e], views);
-        break;
-      case PASTE:
-        paste(edits[e], views);
-        break;
-      case REPLACE:
-        replace(edits[e]);
-        break;
+      Edit edit = iterator.next();
+      performEdit(edit, views);
+    }
+  }
+
+  /**
+   * Execute one edit command in all the specified alignment views
+   * 
+   * @param edit
+   * @param views
+   */
+  protected void performEdit(Edit edit, AlignmentI[] views)
+  {
+    switch (edit.command)
+    {
+    case INSERT_GAP:
+      insertGap(edit);
+      break;
+    case DELETE_GAP:
+      deleteGap(edit);
+      break;
+    case CUT:
+      cut(edit, views);
+      break;
+    case PASTE:
+      paste(edit, views);
+      break;
+    case REPLACE:
+      replace(edit);
+      break;
+    case INSERT_NUC:
       // TODO:add deleteNuc for UNDO
       // case INSERT_NUC:
       // insertNuc(edits[e]);
-      // break;
-      }
+      break;
+    default:
+      break;
     }
   }
 
@@ -219,32 +274,49 @@ public class EditCommand implements CommandI
     performEdit(0, views);
   }
 
+  /**
+   * Undo the stored list of commands, in reverse order.
+   */
   @Override
   final public void undoCommand(AlignmentI[] views)
   { 
-    for(Edit e : edits){
-       switch (e.command)
-        {
-        case INSERT_GAP:
-          deleteGap(e);
-          break;
-        case DELETE_GAP:
-          insertGap(e);
-          break;
-        case CUT:
-          paste(e, views);
-          break;
-        case PASTE:
-          cut(e, views);
-          break;
-        case REPLACE:
-          replace(e);
-          break;
-        }
+    ListIterator<Edit> iterator = edits.listIterator(edits.size());
+    while (iterator.hasPrevious())
+    {
+      Edit e = iterator.previous();
+      switch (e.command)
+      {
+      case INSERT_GAP:
+        deleteGap(e);
+        break;
+      case DELETE_GAP:
+        insertGap(e);
+        break;
+      case CUT:
+        paste(e, views);
+        break;
+      case PASTE:
+        cut(e, views);
+        break;
+      case REPLACE:
+        replace(e);
+        break;
+      case INSERT_NUC:
+        // not implemented
+        break;
+      default:
+        break;
+      }
     }
   }
 
-  final void insertGap(Edit command)
+  /**
+   * Insert gap(s) in sequences as specified by the command, and adjust
+   * annotations.
+   * 
+   * @param command
+   */
+  final private void insertGap(Edit command)
   {
 
     for (int s = 0; s < command.seqs.length; s++)
@@ -270,7 +342,13 @@ public class EditCommand implements CommandI
   // adjustAnnotations(command, true, false, null);
   // }
 
-  final void deleteGap(Edit command)
+  /**
+   * Delete gap(s) in sequences as specified by the command, and adjust
+   * annotations.
+   * 
+   * @param command
+   */
+  final private void deleteGap(Edit command)
   {
     for (int s = 0; s < command.seqs.length; s++)
     {
@@ -281,6 +359,13 @@ public class EditCommand implements CommandI
     adjustAnnotations(command, false, false, null);
   }
 
+  /**
+   * Carry out a Cut action. The cut characters are saved in case Undo is
+   * requested.
+   * 
+   * @param command
+   * @param views
+   */
   void cut(Edit command, AlignmentI[] views)
   {
     boolean seqDeleted = false;
@@ -288,29 +373,30 @@ public class EditCommand implements CommandI
 
     for (int i = 0; i < command.seqs.length; i++)
     {
-      if (command.seqs[i].getLength() > command.position)
+      final SequenceI sequence = command.seqs[i];
+      if (sequence.getLength() > command.position)
       {
-        command.string[i] = command.seqs[i].getSequence(command.position,
+        command.string[i] = sequence.getSequence(command.position,
                 command.position + command.number);
-        SequenceI oldds = command.seqs[i].getDatasetSequence();
+        SequenceI oldds = sequence.getDatasetSequence();
         if (command.oldds != null && command.oldds[i] != null)
         {
           // we are redoing an undone cut.
-          command.seqs[i].setDatasetSequence(null);
+          sequence.setDatasetSequence(null);
         }
-        command.seqs[i].deleteChars(command.position, command.position
+        sequence.deleteChars(command.position, command.position
                 + command.number);
         if (command.oldds != null && command.oldds[i] != null)
         {
           // oldds entry contains the cut dataset sequence.
-          command.seqs[i].setDatasetSequence(command.oldds[i]);
+          sequence.setDatasetSequence(command.oldds[i]);
           command.oldds[i] = oldds;
         }
         else
         {
           // modify the oldds if necessary
-          if (oldds != command.seqs[i].getDatasetSequence()
-                  || command.seqs[i].getSequenceFeatures() != null)
+          if (oldds != sequence.getDatasetSequence()
+                  || sequence.getSequenceFeatures() != null)
           {
             if (command.oldds == null)
             {
@@ -320,16 +406,16 @@ public class EditCommand implements CommandI
             adjustFeatures(
                     command,
                     i,
-                    command.seqs[i].findPosition(command.position),
-                    command.seqs[i].findPosition(command.position
+                    sequence.findPosition(command.position),
+                    sequence.findPosition(command.position
                             + command.number), false);
           }
         }
       }
 
-      if (command.seqs[i].getLength() < 1)
+      if (sequence.getLength() < 1)
       {
-        command.al.deleteSequence(command.seqs[i]);
+        command.al.deleteSequence(sequence);
         seqDeleted = true;
       }
     }
@@ -337,6 +423,13 @@ public class EditCommand implements CommandI
     adjustAnnotations(command, false, seqDeleted, views);
   }
 
+  /**
+   * Perform the given Paste command. This may be to add cut or copied sequences
+   * to an alignment, or to undo a 'Cut' action on a region of the alignment.
+   * 
+   * @param command
+   * @param views
+   */
   void paste(Edit command, AlignmentI[] views)
   {
     StringBuffer tmp;
@@ -540,7 +633,7 @@ public class EditCommand implements CommandI
     if (modifyVisibility && !insert)
     {
       // only occurs if a sequence was added or deleted.
-      command.deletedAnnotationRows = new Hashtable();
+      command.deletedAnnotationRows = new Hashtable<SequenceI, AlignmentAnnotation[]>();
     }
     if (command.fullAlignmentHeight)
     {
@@ -624,7 +717,7 @@ public class EditCommand implements CommandI
                     && command.deletedAnnotationRows
                             .containsKey(command.seqs[s]))
             {
-              AlignmentAnnotation[] revealed = (AlignmentAnnotation[]) command.deletedAnnotationRows
+              AlignmentAnnotation[] revealed = command.deletedAnnotationRows
                       .get(command.seqs[s]);
               command.seqs[s].setAlignmentAnnotation(revealed);
               if (revealed != null)
@@ -695,7 +788,7 @@ public class EditCommand implements CommandI
 
     if (!insert)
     {
-      command.deletedAnnotations = new Hashtable();
+      command.deletedAnnotations = new Hashtable<String, Annotation[]>();
     }
 
     int aSize;
@@ -758,7 +851,7 @@ public class EditCommand implements CommandI
                   && command.deletedAnnotations
                           .containsKey(annotations[a].annotationId))
           {
-            Annotation[] restore = (Annotation[]) command.deletedAnnotations
+            Annotation[] restore = command.deletedAnnotations
                     .get(annotations[a].annotationId);
 
             System.arraycopy(restore, 0, temp, command.position,
@@ -776,7 +869,7 @@ public class EditCommand implements CommandI
                   && command.deletedAnnotations
                           .containsKey(annotations[a].annotationId))
           {
-            Annotation[] restore = (Annotation[]) command.deletedAnnotations
+            Annotation[] restore = command.deletedAnnotations
                     .get(annotations[a].annotationId);
 
             temp = new Annotation[annotations[a].annotations.length
@@ -871,7 +964,7 @@ public class EditCommand implements CommandI
       if (command.editedFeatures != null
               && command.editedFeatures.containsKey(seq))
       {
-        sequence.setSequenceFeatures((SequenceFeature[]) command.editedFeatures
+        sequence.setSequenceFeatures(command.editedFeatures
                 .get(seq));
       }
 
@@ -927,7 +1020,7 @@ public class EditCommand implements CommandI
 
     if (command.editedFeatures == null)
     {
-      command.editedFeatures = new Hashtable();
+      command.editedFeatures = new Hashtable<SequenceI, SequenceFeature[]>();
     }
 
     command.editedFeatures.put(seq, oldsf);
@@ -940,15 +1033,15 @@ public class EditCommand implements CommandI
 
     boolean fullAlignmentHeight = false;
 
-    Hashtable deletedAnnotationRows;
+    Hashtable<SequenceI, AlignmentAnnotation[]> deletedAnnotationRows;
 
-    Hashtable deletedAnnotations;
+    Hashtable<String, Annotation[]> deletedAnnotations;
 
-    Hashtable editedFeatures;
+    Hashtable<SequenceI, SequenceFeature[]> editedFeatures;
 
     AlignmentI al;
 
-    int command;
+    Action command;
 
     char[][] string;
 
@@ -960,7 +1053,7 @@ public class EditCommand implements CommandI
 
     char gapChar;
 
-    Edit(int command, SequenceI[] seqs, int position, int number,
+    Edit(Action command, SequenceI[] seqs, int position, int number,
             char gapChar)
     {
       this.command = command;
@@ -970,7 +1063,7 @@ public class EditCommand implements CommandI
       this.gapChar = gapChar;
     }
 
-    Edit(int command, SequenceI[] seqs, int position, int number,
+    Edit(Action command, SequenceI[] seqs, int position, int number,
             AlignmentI al)
     {
       this.gapChar = al.getGapCharacter();
@@ -989,7 +1082,7 @@ public class EditCommand implements CommandI
       fullAlignmentHeight = (al.getHeight() == seqs.length);
     }
 
-    Edit(int command, SequenceI[] seqs, int position, int number,
+    Edit(Action command, SequenceI[] seqs, int position, int number,
             AlignmentI al, String replace)
     {
       this.command = command;
index 6172ce8..ac93d4e 100644 (file)
@@ -39,7 +39,8 @@ package jalview.commands;
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
 
 public class RemoveGapColCommand extends EditCommand
 {
@@ -55,7 +56,7 @@ public class RemoveGapColCommand extends EditCommand
     int startCol = -1, endCol = -1;
     columnsDeleted = 0;
 
-    edits = new Edit[0];
+    clearEdits();
 
     boolean delete = true;
     for (int i = start; i <= end; i++)
@@ -86,7 +87,8 @@ public class RemoveGapColCommand extends EditCommand
 
       if (!delete && startCol > -1)
       {
-        this.appendEdit(DELETE_GAP, seqs, startCol - columnsDeleted, endCol
+        this.appendEdit(Action.DELETE_GAP, seqs, startCol - columnsDeleted,
+                endCol
                 - startCol, al, false, null);
 
         columnsDeleted += (endCol - startCol);
@@ -100,7 +102,8 @@ public class RemoveGapColCommand extends EditCommand
       // This is for empty columns at the
       // end of the alignment
 
-      this.appendEdit(DELETE_GAP, seqs, startCol - columnsDeleted, end
+      this.appendEdit(Action.DELETE_GAP, seqs, startCol - columnsDeleted,
+              end
               - startCol + 1, al, false, null);
 
       columnsDeleted += (end - startCol + 1);
index 2e8d744..60d09f7 100644 (file)
@@ -39,7 +39,8 @@ package jalview.commands;
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
 
 public class RemoveGapsCommand extends EditCommand
 {
@@ -74,7 +75,7 @@ public class RemoveGapsCommand extends EditCommand
 
     int j, jSize;
 
-    edits = new Edit[0];
+    clearEdits();
 
     boolean delete = true;
     char[] sequence;
@@ -108,7 +109,7 @@ public class RemoveGapsCommand extends EditCommand
 
         if (!delete && startCol > -1)
         {
-          this.appendEdit(DELETE_GAP, new SequenceI[]
+          this.appendEdit(Action.DELETE_GAP, new SequenceI[]
           { seqs[s] }, start + startCol - deletedCols, endCol - startCol,
                   al, false, null);
 
@@ -119,7 +120,7 @@ public class RemoveGapsCommand extends EditCommand
       }
       if (delete && startCol > -1)
       {
-        this.appendEdit(DELETE_GAP, new SequenceI[]
+        this.appendEdit(Action.DELETE_GAP, new SequenceI[]
         { seqs[s] }, start + startCol - deletedCols, jSize - startCol, al,
                 false, null);
       }
index 1ad3d9e..382085c 100644 (file)
@@ -20,7 +20,7 @@
  */
 package jalview.commands;
 
-import jalview.datamodel.*;
+import jalview.datamodel.SequenceI;
 
 public class SlideSequencesCommand extends EditCommand
 {
@@ -37,21 +37,29 @@ public class SlideSequencesCommand extends EditCommand
     for (i = 0; i < lSize; i++)
     {
       for (j = 0; j < slideSize; j++)
+      {
         if (!jalview.util.Comparison.isGap(seqsLeft[i].getCharAt(j)))
         {
           gapsInsertedBegin = true;
           break;
         }
+      }
     }
 
+    Edit e = null;
+
     if (!gapsInsertedBegin)
-      edits = new Edit[]
-      { new Edit(DELETE_GAP, seqsLeft, 0, slideSize, gapChar) };
+    {
+      e = new Edit(Action.DELETE_GAP, seqsLeft, 0, slideSize, gapChar);
+      setEdit(e);
+    }
     else
-      edits = new Edit[]
-      { new Edit(INSERT_GAP, seqsRight, 0, slideSize, gapChar) };
+    {
+      e = new Edit(Action.INSERT_GAP, seqsRight, 0, slideSize, gapChar);
+      setEdit(e);
+    }
 
-    performEdit(0, null);
+    performEdit(e, null);
   }
 
   public boolean getGapsInsertedBegin()
@@ -63,12 +71,12 @@ public class SlideSequencesCommand extends EditCommand
   {
     boolean same = false;
 
-    if (command.edits[0].seqs.length == edits[0].seqs.length)
+    if (command.getEdit(0).seqs.length == getEdit(0).seqs.length)
     {
       same = true;
-      for (int i = 0; i < command.edits[0].seqs.length; i++)
+      for (int i = 0; i < command.getEdit(0).seqs.length; i++)
       {
-        if (edits[0].seqs[i] != command.edits[0].seqs[i])
+        if (getEdit(0).seqs[i] != command.getEdit(0).seqs[i])
         {
           same = false;
         }
@@ -77,10 +85,7 @@ public class SlideSequencesCommand extends EditCommand
 
     if (same)
     {
-      Edit[] temp = new Edit[command.edits.length + 1];
-      System.arraycopy(command.edits, 0, temp, 0, command.edits.length);
-      command.edits = temp;
-      command.edits[command.edits.length - 1] = edits[0];
+      command.addEdit(getEdit(0));
     }
 
     return same;
index a757d1a..ebbe827 100644 (file)
  */
 package jalview.commands;
 
-import java.util.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.util.ShiftList;
 
-import jalview.datamodel.*;
-import jalview.util.*;
+import java.util.List;
 
 public class TrimRegionCommand extends EditCommand
 {
@@ -39,7 +42,7 @@ public class TrimRegionCommand extends EditCommand
 
   SequenceGroup selectionGroup;
 
-  Vector deletedHiddenColumns;
+  List<int[]> deletedHiddenColumns;
 
   int columnsDeleted;
 
@@ -59,8 +62,7 @@ public class TrimRegionCommand extends EditCommand
 
       columnsDeleted = column;
 
-      edits = new Edit[]
-      { new Edit(CUT, seqs, 0, column, al) };
+      setEdit(new Edit(Action.CUT, seqs, 0, column, al));
     }
     else if (command.equalsIgnoreCase(TRIM_RIGHT))
     {
@@ -72,17 +74,16 @@ public class TrimRegionCommand extends EditCommand
 
       columnsDeleted = width - 1;
 
-      edits = new Edit[]
-      { new Edit(CUT, seqs, column + 1, width, al) };
+      setEdit(new Edit(Action.CUT, seqs, column + 1, width, al));
     }
 
     // We need to keep a record of the sequence start
     // in order to restore the state after a redo
-    int i, isize = edits[0].seqs.length;
+    int i, isize = getEdit(0).seqs.length;
     start = new int[isize];
     for (i = 0; i < isize; i++)
     {
-      start[i] = edits[0].seqs[i].getStart();
+      start[i] = getEdit(0).seqs[i].getStart();
     }
 
     performEdit(0, null);
@@ -160,7 +161,7 @@ public class TrimRegionCommand extends EditCommand
       int[] region;
       for (int i = 0; i < deletedHiddenColumns.size(); i++)
       {
-        region = (int[]) deletedHiddenColumns.elementAt(i);
+        region = deletedHiddenColumns.get(i);
         colSel.hideColumns(region[0], region[1]);
       }
     }
index b2d4f0f..4057773 100755 (executable)
@@ -147,7 +147,9 @@ public class Alignment implements AlignmentI
   public SequenceI[] getSequencesArray()
   {
     if (sequences == null)
+    {
       return null;
+    }
     synchronized (sequences)
     {
       return sequences.toArray(new SequenceI[sequences.size()]);
@@ -211,7 +213,9 @@ public class Alignment implements AlignmentI
       }
     }
     if (hiddenSequences != null)
+    {
       hiddenSequences.adjustHeightSequenceAdded();
+    }
   }
 
   /**
@@ -245,7 +249,9 @@ public class Alignment implements AlignmentI
   public void finalize()
   {
     if (getDataset() != null)
+    {
       getDataset().removeAlignmentRef();
+    }
 
     dataset = null;
     sequences = null;
@@ -754,7 +760,9 @@ public class Alignment implements AlignmentI
         continue;
       }
       if (tIndex < temp.length)
+      {
         temp[tIndex++] = annotations[i];
+      }
     }
 
     if (swap)
@@ -950,6 +958,27 @@ public class Alignment implements AlignmentI
     else if (dataset == null && data != null)
     {
       dataset = data;
+      for (int i = 0; i < getHeight(); i++)
+      {
+        SequenceI currentSeq = getSequenceAt(i);
+        SequenceI dsq = currentSeq.getDatasetSequence();
+        if (dsq == null)
+        {
+          dsq = currentSeq.createDatasetSequence();
+          dataset.addSequence(dsq);
+        }
+        else
+        {
+          while (dsq.getDatasetSequence() != null)
+          {
+            dsq = dsq.getDatasetSequence();
+          }
+          if (dataset.findIndex(dsq) == -1)
+          {
+            dataset.addSequence(dsq);
+          }
+        }
+      }
     }
     dataset.addAlignmentRef();
   }
@@ -1150,7 +1179,9 @@ public class Alignment implements AlignmentI
   public void setProperty(Object key, Object value)
   {
     if (alignmentProperties == null)
+    {
       alignmentProperties = new Hashtable();
+    }
 
     alignmentProperties.put(key, value);
   }
@@ -1159,9 +1190,13 @@ public class Alignment implements AlignmentI
   public Object getProperty(Object key)
   {
     if (alignmentProperties != null)
+    {
       return alignmentProperties.get(key);
+    }
     else
+    {
       return null;
+    }
   }
 
   @Override
@@ -1183,7 +1218,9 @@ public class Alignment implements AlignmentI
   public void addCodonFrame(AlignedCodonFrame codons)
   {
     if (codons == null)
+    {
       return;
+    }
     if (codonFrameList == null)
     {
       codonFrameList = new AlignedCodonFrame[]
@@ -1217,15 +1254,21 @@ public class Alignment implements AlignmentI
   public AlignedCodonFrame[] getCodonFrame(SequenceI seq)
   {
     if (seq == null || codonFrameList == null)
+    {
       return null;
+    }
     Vector cframes = new Vector();
     for (int f = 0; f < codonFrameList.length; f++)
     {
       if (codonFrameList[f].involvesSequence(seq))
+      {
         cframes.addElement(codonFrameList[f]);
+      }
     }
     if (cframes.size() == 0)
+    {
       return null;
+    }
     AlignedCodonFrame[] cfr = new AlignedCodonFrame[cframes.size()];
     cframes.copyInto(cfr);
     return cfr;
@@ -1252,7 +1295,9 @@ public class Alignment implements AlignmentI
   public boolean removeCodonFrame(AlignedCodonFrame codons)
   {
     if (codons == null || codonFrameList == null)
+    {
       return false;
+    }
     boolean removed = false;
     int i = 0, iSize = codonFrameList.length;
     while (i < iSize)
index 0731991..e137225 100755 (executable)
@@ -75,9 +75,10 @@ public class AlignmentAnnotation
   public SequenceFeature[] _rnasecstr = null;
 
   /**
-   * position of annotation resulting in invalid WUSS parsing or -1
+   * position of annotation resulting in invalid WUSS parsing or -1. -2 means
+   * there was no RNA structure in this annotation
    */
-  private long invalidrnastruc = -1;
+  private long invalidrnastruc = -2;
 
   /**
    * Updates the _rnasecstr field Determines the positions that base pair and
@@ -110,10 +111,47 @@ public class AlignmentAnnotation
       isrna = true;
       showAllColLabels = true;
       scaleColLabel = true;
+      _markRnaHelices();
     }
     // System.out.println("featuregroup " + _rnasecstr[0].getFeatureGroup());
+
   }
 
+  private void _markRnaHelices()
+  {
+    int mxval = 0;
+    // Figure out number of helices
+    // Length of rnasecstr is the number of pairs of positions that base pair
+    // with each other in the secondary structure
+    for (int x = 0; x < _rnasecstr.length; x++)
+    {
+
+      /*
+       * System.out.println(this.annotation._rnasecstr[x] + " Begin" +
+       * this.annotation._rnasecstr[x].getBegin());
+       */
+      // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup());
+      int val = 0;
+      try
+      {
+        val = Integer.valueOf(_rnasecstr[x].getFeatureGroup());
+        if (mxval < val)
+        {
+          mxval = val;
+        }
+      } catch (NumberFormatException q)
+      {
+      }
+      ;
+
+      annotations[_rnasecstr[x].getBegin()].value = val;
+      annotations[_rnasecstr[x].getEnd()].value = val;
+
+      // annotations[_rnasecstr[x].getBegin()].displayCharacter = "" + val;
+      // annotations[_rnasecstr[x].getEnd()].displayCharacter = "" + val;
+    }
+    setScore(mxval);
+  }
   /**
    * map of positions in the associated annotation
    */
@@ -455,11 +493,10 @@ public class AlignmentAnnotation
     @Override
     public char charAt(int index)
     {
-      String dc;
       return ((index + offset < 0) || (index + offset) >= max
-              || annotations[index + offset] == null || (dc = annotations[index
-              + offset].displayCharacter.trim()).length() < 1) ? '.' : dc
-              .charAt(0);
+              || annotations[index + offset] == null || (annotations[index
+ + offset].secondaryStructure < ' ') ? ' '
+              : annotations[index + offset].secondaryStructure);
     }
 
     public String toString()
@@ -469,9 +506,8 @@ public class AlignmentAnnotation
 
       for (int i = offset; i < mx; i++)
       {
-        String dc;
-        string[i] = (annotations[i] == null || (dc = annotations[i].displayCharacter
-                .trim()).length() < 1) ? '.' : dc.charAt(0);
+        string[i] = (annotations[i] == null || (annotations[i].secondaryStructure < 32)) ? ' '
+                : annotations[i].secondaryStructure;
       }
       return new String(string);
     }
index 35d467a..f414d13 100644 (file)
  */
 package jalview.datamodel;
 
-import java.util.*;
+import jalview.util.ShiftList;
 
-import jalview.util.*;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Vector;
 
 /**
  * NOTE: Columns are zero based.
@@ -186,9 +189,9 @@ public class ColumnSelection
    * @param left
    *          shift in edit (+ve for removal, or -ve for inserts)
    */
-  public Vector compensateForEdit(int start, int change)
+  public List<int[]> compensateForEdit(int start, int change)
   {
-    Vector deletedHiddenColumns = null;
+    List<int[]> deletedHiddenColumns = null;
     for (int i = 0; i < size(); i++)
     {
       int temp = columnAt(i);
@@ -201,14 +204,14 @@ public class ColumnSelection
 
     if (hiddenColumns != null)
     {
-      deletedHiddenColumns = new Vector();
+      deletedHiddenColumns = new ArrayList<int[]>();
       int hSize = hiddenColumns.size();
       for (int i = 0; i < hSize; i++)
       {
         int[] region = (int[]) hiddenColumns.elementAt(i);
         if (region[0] > start && start + change > region[1])
         {
-          deletedHiddenColumns.addElement(hiddenColumns.elementAt(i));
+          deletedHiddenColumns.add(region);
 
           hiddenColumns.removeElementAt(i);
           i--;
@@ -752,6 +755,7 @@ public class ColumnSelection
   public boolean isVisible(int column)
   {
     if (hiddenColumns != null)
+    {
       for (int i = 0; i < hiddenColumns.size(); i++)
       {
         int[] region = (int[]) hiddenColumns.elementAt(i);
@@ -760,6 +764,7 @@ public class ColumnSelection
           return false;
         }
       }
+    }
 
     return true;
   }
@@ -1018,7 +1023,9 @@ public class ColumnSelection
         w += els.length;
       }
       if (w == 0)
+      {
         return;
+      }
       Enumeration e = annels.elements();
       alignmentAnnotation.annotations = new Annotation[w];
       w = 0;
index aefb5cc..bfeafd6 100755 (executable)
@@ -20,7 +20,9 @@
  */
 package jalview.datamodel;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 public class HiddenSequences
 {
@@ -143,34 +145,34 @@ public class HiddenSequences
     alignment.deleteSequence(sequence);
   }
 
-  public Vector showAll(
+  public List<SequenceI> showAll(
           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
   {
-    Vector revealedSeqs = new Vector();
+    List<SequenceI> revealedSeqs = new ArrayList<SequenceI>();
     for (int i = 0; i < hiddenSequences.length; i++)
     {
       if (hiddenSequences[i] != null)
       {
-        Vector tmp = showSequence(i, hiddenRepSequences);
-        for (int t = 0; t < tmp.size(); t++)
+        List<SequenceI> tmp = showSequence(i, hiddenRepSequences);
+        for (SequenceI seq : tmp)
         {
-          revealedSeqs.addElement(tmp.elementAt(t));
+          revealedSeqs.add(seq);
         }
       }
     }
     return revealedSeqs;
   }
 
-  public Vector showSequence(int alignmentIndex,
+  public List<SequenceI> showSequence(int alignmentIndex,
           Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
   {
-    Vector revealedSeqs = new Vector();
+    List<SequenceI> revealedSeqs = new ArrayList<SequenceI>();
     SequenceI repSequence = alignment.getSequenceAt(alignmentIndex);
     if (repSequence != null && hiddenRepSequences != null
             && hiddenRepSequences.containsKey(repSequence))
     {
       hiddenRepSequences.remove(repSequence);
-      revealedSeqs.addElement(repSequence);
+      revealedSeqs.add(repSequence);
     }
 
     int start = adjustForHiddenSeqs(alignmentIndex - 1);
@@ -192,7 +194,7 @@ public class HiddenSequences
         {
           if (seq.getLength() > 0)
           {
-            revealedSeqs.addElement(seq);
+            revealedSeqs.add(seq);
             asequences.add(alignmentIndex, seq);
           }
           else
index 9fa6bf4..f5710d3 100644 (file)
@@ -186,9 +186,12 @@ public class PDBFileWithJmol extends AlignFile implements
                   seqs.add(sq);
                   if (!isNa)
                   {
+                    String mt = model.getModelTitle() == null ? getDataName()
+                            : model.getModelTitle();
+                    mt += _lastChainId;
                     AlignmentAnnotation ann = new AlignmentAnnotation(
                             "Secondary Structure",
-                            "Secondary Structure from PDB File", asecstr);
+                            "Secondary Structure for " + mt, asecstr);
                     ann.belowAlignment=true;
                     ann.visible=true;
                     ann.autoCalculated=false;
index 090b61d..fb03f04 100644 (file)
@@ -343,8 +343,7 @@ public abstract class JalviewChimeraBinding extends
   public void colourByChain()
   {
     colourBySequence = false;
-    // this is not a valid Chimera command; is there one? Menu option hidden
-    evalStateCommand("select *;color chain",false);
+    evalStateCommand("rainbow chain", false);
   }
 
   public void colourByCharge()
index 684e7ac..07c4a54 100644 (file)
@@ -34,6 +34,7 @@ import jalview.api.analysis.ScoreModelI;
 import jalview.bin.Cache;
 import jalview.commands.CommandI;
 import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
 import jalview.commands.OrderCommand;
 import jalview.commands.RemoveGapColCommand;
 import jalview.commands.RemoveGapsCommand;
@@ -1410,7 +1411,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (viewport.historyList.size() > 0)
     {
       undoMenuItem.setEnabled(true);
-      CommandI command = (CommandI) viewport.historyList.peek();
+      CommandI command = viewport.historyList.peek();
       undoMenuItem.setText(MessageManager.formatMessage(
               "label.undo_command", new String[]
               { command.getDescription() }));
@@ -1425,7 +1426,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       redoMenuItem.setEnabled(true);
 
-      CommandI command = (CommandI) viewport.redoList.peek();
+      CommandI command = viewport.redoList.peek();
       redoMenuItem.setText(MessageManager.formatMessage(
               "label.redo_command", new String[]
               { command.getDescription() }));
@@ -1489,7 +1490,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       return;
     }
-    CommandI command = (CommandI) viewport.historyList.pop();
+    CommandI command = viewport.historyList.pop();
     viewport.redoList.push(command);
     command.undoCommand(getViewAlignments());
 
@@ -1528,7 +1529,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       return;
     }
 
-    CommandI command = (CommandI) viewport.redoList.pop();
+    CommandI command = viewport.redoList.pop();
     viewport.historyList.push(command);
     command.doCommand(getViewAlignments());
 
@@ -1990,7 +1991,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         // /////
         // ADD HISTORY ITEM
         //
-        addHistoryItem(new EditCommand(MessageManager.getString("label.add_sequences"), EditCommand.PASTE,
+        addHistoryItem(new EditCommand(
+                MessageManager.getString("label.add_sequences"),
+                Action.PASTE,
                 sequences, 0, alignment.getWidth(), alignment));
       }
       // Add any annotations attached to sequences
@@ -2261,8 +2264,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     /*
      * //ADD HISTORY ITEM
      */
-    addHistoryItem(new EditCommand(MessageManager.getString("label.cut_sequences"), EditCommand.CUT, cut,
-            sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
+    addHistoryItem(new EditCommand(
+            MessageManager.getString("label.cut_sequences"), Action.CUT,
+            cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
             viewport.getAlignment()));
 
     viewport.setSelectionGroup(null);
@@ -5797,7 +5801,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         aa.visible = visible;
       }
     }
-    this.alignPanel.paintAlignment(true);
+    alignPanel.validateAnnotationDimensions(false);
+    alignPanel.alignmentChanged();
   }
 
   /**
index 5c383d8..d24f6c4 100644 (file)
@@ -42,9 +42,8 @@ import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.analysis.NJTree;
 import jalview.api.AlignViewportI;
 import jalview.bin.Cache;
-import jalview.datamodel.AlignmentAnnotation;
+import jalview.commands.CommandI;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
@@ -140,9 +139,9 @@ public class AlignViewport extends AlignmentViewport implements
 
   boolean gatherViewsHere = false;
 
-  Stack historyList = new Stack();
+  Stack<CommandI> historyList = new Stack<CommandI>();
 
-  Stack redoList = new Stack();
+  Stack<CommandI> redoList = new Stack<CommandI>();
 
   int thresholdTextColour = 0;
 
@@ -337,10 +336,6 @@ public class AlignViewport extends AlignmentViewport implements
               false);
       showGroupConsensus = Cache.getDefault("SHOW_GROUP_CONSENSUS", false);
       showConsensus = Cache.getDefault("SHOW_IDENTITY", true);
-      consensus = new AlignmentAnnotation("Consensus", "PID",
-              new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
-      consensus.hasText = true;
-      consensus.autoCalculated = true;
     }
     initAutoAnnotation();
     if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
index ad6f9e5..6e8417f 100755 (executable)
@@ -478,20 +478,29 @@ public class AnnotationLabels extends JPanel implements MouseListener,
         {
           desc.append("<br/>");
         }
-
+        // if (aa.hasProperties())
+        // {
+        // desc.append("<table>");
+        // for (String prop : aa.getProperties())
+        // {
+        // desc.append("<tr><td>" + prop + "</td><td>"
+        // + aa.getProperty(prop) + "</td><tr>");
+        // }
+        // desc.append("</table>");
+        // }
       }
       else
       {
         // begin the tooltip's html fragment
         desc.append("<html>");
+        if (aa.hasScore())
+        {
+          // TODO: limit precision of score to avoid noise from imprecise
+          // doubles
+          // (64.7 becomes 64.7+/some tiny value).
+          desc.append(" Score: " + aa.score);
+        }
       }
-      if (aa.hasScore())
-      {
-        // TODO: limit precision of score to avoid noise from imprecise doubles
-        // (64.7 becomes 64.7+/some tiny value).
-        desc.append(" Score: " + aa.score);
-      }
-
       if (desc.length() > 6)
       {
         desc.append("</html>");
@@ -502,7 +511,6 @@ public class AnnotationLabels extends JPanel implements MouseListener,
         this.setToolTipText(null);
       }
     }
-
   }
 
   /**
index 4adeb83..9f56206 100755 (executable)
  */
 package jalview.gui;
 
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-
-import javax.swing.*;
-
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceI;
 import jalview.renderer.AnnotationRenderer;
 import jalview.renderer.AwtRenderPanelI;
 import jalview.util.MessageManager;
 
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.image.BufferedImage;
+
+import javax.swing.JColorChooser;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.Scrollable;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
+
 /**
  * AnnotationPanel displays visible portion of annotation rows below unwrapped
  * alignment
@@ -289,7 +315,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         int index = av.getColumnSelection().columnAt(i);
 
         if (!av.getColumnSelection().isVisible(index))
+        {
           continue;
+        }
 
         if (anot[index] == null)
         {
@@ -314,7 +342,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         int index = av.getColumnSelection().columnAt(i);
 
         if (!av.getColumnSelection().isVisible(index))
+        {
           continue;
+        }
 
         if (anot[index] == null)
         {
@@ -373,14 +403,18 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         int index = av.getColumnSelection().columnAt(i);
 
         if (!av.getColumnSelection().isVisible(index))
+        {
           continue;
+        }
 
         if (anot[index] == null)
         {
           anot[index] = new Annotation(label, "", type, 0);
         }
 
-        anot[index].secondaryStructure = type;
+        
+        anot[index].secondaryStructure = type != 'S' ? type : label
+                .length() == 0 ? ' ' : label.charAt(0);
         anot[index].displayCharacter = label;
 
       }
@@ -406,7 +440,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       int index = columnSelection.columnAt(i);
       // always check for current display state - just in case
       if (!viscols.isVisible(index))
+      {
         continue;
+      }
       String tlabel = null;
       if (anot[index] != null)
       { // LML added stem code
@@ -765,7 +801,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     }
     imgWidth = (av.endRes - av.startRes + 1) * av.charWidth;
     if (imgWidth < 1)
+    {
       return;
+    }
     if (image == null || imgWidth != image.getWidth(this)
             || image.getHeight(this) != getHeight())
     {
@@ -984,6 +1022,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       return bounds;
     }
     else
+    {
       return null;
+    }
   }
 }
index cfac4ef..02865e1 100644 (file)
@@ -144,9 +144,6 @@ public class ChimeraViewFrame extends GStructureViewer implements Runnable,
       _alignwith = new Vector<AlignmentPanel>();
     }
 
-    // no colour by chain command in Chimera?
-    chainColour.setVisible(false);
-
     // save As not yet implemented
     savemenu.setVisible(false);
 
index faffd89..007fefd 100644 (file)
@@ -26,6 +26,7 @@ import jalview.io.FormatAdapter;
 import jalview.io.IdentifyFile;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
+import jalview.structure.StructureSelectionManager;
 import jalview.util.ImageMaker;
 import jalview.util.MessageManager;
 import jalview.ws.params.ParamManager;
@@ -286,7 +287,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     instance = this;
     doVamsasClientCheck();
     doGroovyCheck();
-
+    doConfigureStructurePrefs();
     setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
@@ -322,8 +323,11 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     }
     jconsole = new Console(this, showjconsole);
     // add essential build information
-    jconsole.setHeader("Jalview Desktop "
+    jconsole.setHeader("Jalview Version: "
             + jalview.bin.Cache.getProperty("VERSION") + "\n"
+            + "Jalview Installation: "
+            + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
+            + "\n"
             + "Build Date: "
             + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
             + "Java version: " + System.getProperty("java.version") + "\n"
@@ -416,6 +420,27 @@ public class Desktop extends jalview.jbgui.GDesktop implements
             });
   }
 
+  public void doConfigureStructurePrefs()
+  {
+    // configure services
+    StructureSelectionManager ssm = StructureSelectionManager
+            .getStructureSelectionManager(this);
+    if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
+    {
+      ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
+              Preferences.ADD_TEMPFACT_ANN, true));
+    ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
+    ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
+            true));
+    }
+    else
+    {
+      ssm.setAddTempFacAnnot(false);
+      ssm.setProcessSecondaryStructure(false);
+      ssm.setSecStructServices(false);
+    }
+  }
+
   public void checkForNews()
   {
     final Desktop me = this;
@@ -2580,7 +2605,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
                                                 + ermsg
                                                 + "</td></tr></table>"
                                                 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
-                                                + " or mis-configured HTTP proxy settings.</p>"
+                                                + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
                                                 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
                                                 + " Tools->Preferences dialog box to change them.</p></html>"),
                                 "Web Service Configuration Problem",
index 693e6fe..2210148 100644 (file)
@@ -27,6 +27,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.gui.Help.HelpId;
 import jalview.io.JalviewFileChooser;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.GraduatedColor;
@@ -61,6 +62,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Vector;
 
+import javax.help.HelpSetException;
 import javax.swing.AbstractCellEditor;
 import javax.swing.BorderFactory;
 import javax.swing.Icon;
@@ -132,7 +134,19 @@ public class FeatureSettings extends JPanel
       ex.printStackTrace();
     }
 
-    table = new JTable();
+    table = new JTable() {
+      @Override
+      public String getToolTipText(MouseEvent e) {
+        if (table.columnAtPoint(e.getPoint()) == 0) {
+          /*
+           * Tooltip for feature name only
+           */
+          return JvSwingUtils.wrapTooltip(true,
+                MessageManager.getString("label.feature_settings_click_drag"));
+        }
+        return null;
+      }
+    };
     table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));
     table.setFont(new Font("Verdana", Font.PLAIN, 12));
     table.setDefaultRenderer(Color.class, new ColorRenderer());
@@ -201,8 +215,8 @@ public class FeatureSettings extends JPanel
         }
       }
     });
-    table.setToolTipText(JvSwingUtils
-                    .wrapTooltip(true, MessageManager.getString("label.feature_settings_click_drag")));
+//    table.setToolTipText(JvSwingUtils.wrapTooltip(true,
+//            MessageManager.getString("label.feature_settings_click_drag")));
     scrollPane.setViewportView(table);
 
     dassourceBrowser = new DasSourceBrowser(this);
@@ -572,7 +586,9 @@ public class FeatureSettings extends JPanel
                 || ((Boolean) fr.featureGroups.get(group)).booleanValue())
         {
           if (group != null)
+          {
             checkGroupState(group);
+          }
           type = tmpfeatures[index].getType();
           if (!visibleChecks.contains(type))
           {
@@ -610,7 +626,9 @@ public class FeatureSettings extends JPanel
     if (fr.renderOrder != null)
     {
       if (!handlingUpdate)
+       {
         fr.findAllFeatures(groupChanged != null); // prod to update
+      }
       // colourschemes. but don't
       // affect display
       // First add the checks in the previous render order,
@@ -691,12 +709,18 @@ public class FeatureSettings extends JPanel
     {
       order[i] = fr.getOrder(data[i][0].toString());
       if (order[i] < 0)
+      {
         order[i] = fr.setOrder(data[i][0].toString(), i / order.length);
+      }
       if (i > 1)
+      {
         sort = sort || order[i - 1] > order[i];
+      }
     }
     if (sort)
+    {
       jalview.util.QuickSort.sort(order, data);
+    }
   }
 
   void load()
@@ -887,7 +911,9 @@ public class FeatureSettings extends JPanel
   public void orderByAvWidth()
   {
     if (table == null || table.getModel() == null)
+    {
       return;
+    }
     Object[][] data = ((FeatureTableModel) table.getModel()).getData();
     float[] width = new float[data.length];
     float[] awidth;
@@ -909,7 +935,9 @@ public class FeatureSettings extends JPanel
         width[i] = 0;
       }
       if (max < width[i])
+      {
         max = width[i];
+      }
     }
     boolean sort = false;
     for (int i = 0; i < width.length; i++)
@@ -929,11 +957,15 @@ public class FeatureSettings extends JPanel
         fr.setOrder(data[i][0].toString(), width[i]); // store for later
       }
       if (i > 0)
+      {
         sort = sort || width[i - 1] > width[i];
+      }
     }
     if (sort)
+     {
       jalview.util.QuickSort.sort(width, data);
     // update global priority order
+    }
 
     updateFeatureRenderer(data, false);
     table.repaint();
@@ -1001,7 +1033,9 @@ public class FeatureSettings extends JPanel
 
   JButton sortByDens = new JButton();
 
-  JPanel transbuttons = new JPanel(new GridLayout(4, 1));
+  JButton help = new JButton();
+
+  JPanel transbuttons = new JPanel(new GridLayout(5, 1));
 
   private void jbInit() throws Exception
   {
@@ -1047,6 +1081,21 @@ public class FeatureSettings extends JPanel
         sortByDens(null);
       }
     });
+    help.setFont(JvSwingUtils.getLabelFont());
+    help.setText(MessageManager.getString("action.help"));
+    help.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        try
+        {
+          Help.showHelpWindow(HelpId.SequenceFeatureSettings);
+        } catch (HelpSetException e1)
+        {
+          e1.printStackTrace();
+        }
+      }
+    });
     cancel.setFont(JvSwingUtils.getLabelFont());
     cancel.setText(MessageManager.getString("action.cancel"));
     cancel.addActionListener(new ActionListener()
@@ -1094,6 +1143,8 @@ public class FeatureSettings extends JPanel
     });
 
     transparency.setMaximum(70);
+    transparency.setToolTipText(MessageManager
+            .getString("label.transparency_tip"));
     fetchDAS.setText(MessageManager.getString("label.fetch_das_features"));
     fetchDAS.addActionListener(new ActionListener()
     {
@@ -1129,6 +1180,9 @@ public class FeatureSettings extends JPanel
     transbuttons.add(invert);
     transbuttons.add(sortByScore);
     transbuttons.add(sortByDens);
+    transbuttons.add(help);
+    JPanel sliderPanel = new JPanel();
+    sliderPanel.add(transparency);
     transPanel.add(transparency);
     transPanel.add(transbuttons);
     buttonPanel.add(ok);
index dac17c0..ae3f457 100644 (file)
@@ -2,6 +2,7 @@ package jalview.gui;
 
 import java.net.URL;
 
+import javax.help.BadIDException;
 import javax.help.HelpBroker;
 import javax.help.HelpSet;
 import javax.help.HelpSetException;
@@ -14,6 +15,23 @@ import javax.help.HelpSetException;
  */
 public class Help
 {
+  public enum HelpId
+  {
+    Home("home"), SequenceFeatureSettings("seqfeatures.settings");
+
+    private String id;
+
+    private HelpId(String loc)
+    {
+      this.id = loc;
+    }
+
+    @Override
+    public String toString()
+    {
+      return this.id;
+    }
+  }
 
   private static final long HALF_A_MO = 500; // half a second
 
@@ -33,10 +51,11 @@ public class Help
    * 
    * This is a workaround for issue JAL-914 - both Desktop and AlignFrame
    * responding to F1 key, resulting in duplicate help windows opened.
+   * @param id TODO
    * 
    * @throws HelpSetException
    */
-  public static void showHelpWindow() throws HelpSetException
+  public static void showHelpWindow(HelpId id) throws HelpSetException
   {
     long timeNow = System.currentTimeMillis();
 
@@ -48,8 +67,21 @@ public class Help
       HelpSet hs = new HelpSet(cl, url);
 
       HelpBroker hb = hs.createHelpBroker();
-      hb.setCurrentID("home");
+      try
+      {
+        hb.setCurrentID(id.toString());
+      } catch (BadIDException bad)
+      {
+        System.out.println("Bad help link: " + id.toString()
+                + ": must match a target in help.jhm");
+        throw bad;
+      }
       hb.setDisplayed(true);
     }
   }
+
+  public static void showHelpWindow() throws HelpSetException
+  {
+    showHelpWindow(HelpId.Home);
+  }
 }
index 1c7be46..9976471 100644 (file)
@@ -25,6 +25,7 @@ import jalview.analysis.AlignmentAnnotationUtils;
 import jalview.analysis.Conservation;
 import jalview.commands.ChangeCaseCommand;
 import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.DBRefEntry;
@@ -372,12 +373,12 @@ public class PopupMenu extends JPopupMenu
       {
         AlignmentAnnotation[] aa = ap.av.getAlignment()
                 .getAlignmentAnnotation();
-        for (int i = 0; i < aa.length; i++)
+        for (int i = 0; aa != null && i < aa.length; i++)
         {
-          if (aa[i].getRNAStruc() != null)
+          if (aa[i].isValidStruc() && aa[i].sequenceRef == null)
           {
             final String rnastruc = aa[i].getRNAStruc();
-            final String structureLine = aa[i].label;
+            final String structureLine = aa[i].label + " (alignment)";
             menuItem = new JMenuItem();
             menuItem.setText(MessageManager.formatMessage(
                     "label.2d_rna_structure_line", new String[]
@@ -387,15 +388,15 @@ public class PopupMenu extends JPopupMenu
               @Override
               public void actionPerformed(ActionEvent e)
               {
-                // System.out.println("1:"+structureLine);
-                System.out.println("1:sname" + seq.getName());
-                System.out.println("2:seq" + seq);
-
-                // System.out.println("3:"+seq.getSequenceAsString());
-                System.out.println("3:strucseq" + rnastruc);
-                // System.out.println("4:struc"+seq.getRNA());
-                System.out.println("5:name" + seq.getName());
-                System.out.println("6:ap" + ap);
+                // // System.out.println("1:"+structureLine);
+                // System.out.println("1:sname" + seq.getName());
+                // System.out.println("2:seq" + seq);
+                //
+                // // System.out.println("3:"+seq.getSequenceAsString());
+                // System.out.println("3:strucseq" + rnastruc);
+                // // System.out.println("4:struc"+seq.getRNA());
+                // System.out.println("5:name" + seq.getName());
+                // System.out.println("6:ap" + ap);
                 new AppVarna(structureLine, seq, seq.getSequenceAsString(),
                         rnastruc, seq.getName(), ap);
                 // new AppVarna(seq.getName(),seq,rnastruc,seq.getRNA(),
@@ -414,7 +415,7 @@ public class PopupMenu extends JPopupMenu
           AlignmentAnnotation seqAnno[] = seq.getAnnotation();
           for (int i = 0; i < seqAnno.length; i++)
           {
-            if (seqAnno[i].getRNAStruc() != null)
+            if (seqAnno[i].isValidStruc())
             {
               final String rnastruc = seqAnno[i].getRNAStruc();
 
@@ -2707,7 +2708,7 @@ public class PopupMenu extends JPopupMenu
       {
         EditCommand editCommand = new EditCommand(
                 MessageManager.getString("label.edit_sequences"),
-                EditCommand.REPLACE, dialog.getName().replace(' ',
+                Action.REPLACE, dialog.getName().replace(' ',
                         ap.av.getGapCharacter()),
                 sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
                 sg.getStartRes(), sg.getEndRes() + 1, ap.av.getAlignment());
index ab4f94f..b082bc6 100755 (executable)
@@ -291,17 +291,7 @@ public class Preferences extends GPreferences
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        if (chimeraPath.getText().trim().length() > 0)
-        {
-          File f = new File(chimeraPath.getText());
-          if (!f.canExecute())
-          {
-            JOptionPane.showInternalMessageDialog(Desktop.desktop,
-                    MessageManager.getString("label.invalid_path"),
-                    MessageManager.getString("label.invalid_name"),
-                    JOptionPane.ERROR_MESSAGE);
-          }
-        }
+        validateChimeraPath();
       }
     });
 
@@ -376,6 +366,11 @@ public class Preferences extends GPreferences
    */
   public void ok_actionPerformed(ActionEvent e)
   {
+    if (!validateSettings())
+    {
+      return;
+    }
+
     /*
      * Save Visual settings
      */
@@ -590,9 +585,8 @@ public class Preferences extends GPreferences
 
     dasSource.saveProperties(Cache.applicationProperties);
     wsPrefs.updateAndRefreshWsMenuConfig(false);
-
     Cache.saveProperties();
-
+    Desktop.instance.doConfigureStructurePrefs();
     try
     {
       frame.setClosed(true);
@@ -602,6 +596,27 @@ public class Preferences extends GPreferences
   }
 
   /**
+   * Do any necessary validation before saving settings.
+   * 
+   * @return
+   */
+  private boolean validateSettings()
+  {
+    if (!validateStructure())
+    {
+      structureTab.requestFocusInWindow();
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  protected boolean validateStructure()
+  {
+    return validateChimeraPath();
+
+  }
+  /**
    * DOCUMENT ME!
    */
   public void startupFileTextfield_mouseClicked()
@@ -843,4 +858,25 @@ public class Preferences extends GPreferences
     userIdWidthlabel.setEnabled(!autoIdWidth.isSelected());
   }
 
+  /**
+   * Returns true if chimera path is to a valid executable, else show an error
+   * dialog.
+   */
+  private boolean validateChimeraPath()
+  {
+    if (chimeraPath.getText().trim().length() > 0)
+    {
+      File f = new File(chimeraPath.getText());
+      if (!f.canExecute())
+      {
+        JOptionPane.showInternalMessageDialog(Desktop.desktop,
+                MessageManager.getString("label.invalid_chimera_path"),
+                MessageManager.getString("label.invalid_name"),
+                JOptionPane.ERROR_MESSAGE);
+        return false;
+      }
+    }
+    return true;
+  }
+
 }
index 0e55cf8..ab0a0b8 100755 (executable)
  */
 package jalview.gui;
 
-import java.util.*;
-
-import java.awt.event.*;
-import javax.swing.*;
-import javax.swing.event.*;
-
 import jalview.analysis.AlignSeq;
-import jalview.commands.*;
-import jalview.datamodel.*;
-import jalview.jbgui.*;
+import jalview.commands.CommandI;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.jbgui.GSliderPanel;
 import jalview.util.MessageManager;
 
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import javax.swing.JInternalFrame;
+import javax.swing.JProgressBar;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
 /**
  * DOCUMENT ME!
  * 
@@ -44,7 +54,9 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
 
   AlignmentPanel ap;
 
-  Stack historyList = new Stack(); // simpler than synching with alignFrame.
+  Stack<CommandI> historyList = new Stack<CommandI>();
+
+  // simpler than synching with alignFrame.
 
   float[] redundancy;
 
@@ -229,7 +241,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
       }
 
       EditCommand cut = new EditCommand(MessageManager.getString("action.remove_redundancy"),
-              EditCommand.CUT, deleted, 0, width, ap.av.getAlignment());
+              Action.CUT, deleted, 0, width, ap.av.getAlignment());
 
       for (int i = 0; i < del.size(); i++)
       {
@@ -263,7 +275,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
        return;
     }
     
-    CommandI command = (CommandI) historyList.pop();
+    CommandI command = historyList.pop();
     if (ap.av.historyList.contains(command))
     {
       command.undoCommand(af.getViewAlignments());
diff --git a/src/jalview/gui/SVGOptions.java b/src/jalview/gui/SVGOptions.java
new file mode 100644 (file)
index 0000000..b5e194b
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
+ * Copyright (C) 2014 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.gui;
+
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+
+public class SVGOptions extends JPanel
+{
+  JDialog dialog;
+
+  public boolean cancelled = false;
+
+  String value;
+
+  public SVGOptions()
+  {
+    try
+    {
+      jbInit();
+    } catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+
+    ButtonGroup bg = new ButtonGroup();
+    bg.add(lineart);
+    bg.add(text);
+
+    JOptionPane pane = new JOptionPane(null, JOptionPane.DEFAULT_OPTION,
+            JOptionPane.DEFAULT_OPTION, null, new Object[]
+            { this });
+
+    dialog = pane.createDialog(Desktop.desktop, "SVG Rendering options");
+    dialog.setVisible(true);
+
+  }
+
+  private void jbInit() throws Exception
+  {
+    lineart.setFont(JvSwingUtils.getLabelFont());
+    lineart.setText(MessageManager.getString("label.lineart"));
+    text.setFont(JvSwingUtils.getLabelFont());
+    text.setText(MessageManager.getString("action.text"));
+    text.setSelected(true);
+    askAgain.setFont(JvSwingUtils.getLabelFont());
+    askAgain.setText(MessageManager.getString("label.dont_ask_me_again"));
+    ok.setText(MessageManager.getString("action.ok"));
+    ok.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        ok_actionPerformed(e);
+      }
+    });
+    cancel.setText(MessageManager.getString("action.cancel"));
+    cancel.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        cancel_actionPerformed(e);
+      }
+    });
+    jLabel1.setFont(JvSwingUtils.getLabelFont());
+    jLabel1.setText("Select SVG character rendering style");
+    this.setLayout(borderLayout1);
+    jPanel3.setBorder(BorderFactory.createEtchedBorder());
+    jPanel2.add(text);
+    jPanel2.add(lineart);
+    jPanel2.add(askAgain);
+    jPanel1.add(ok);
+    jPanel1.add(cancel);
+    jPanel3.add(jLabel1);
+    jPanel3.add(jPanel2);
+    this.add(jPanel3, java.awt.BorderLayout.CENTER);
+    this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+  }
+
+  JRadioButton lineart = new JRadioButton();
+
+  JRadioButton text = new JRadioButton();
+
+  JCheckBox askAgain = new JCheckBox();
+
+  JButton ok = new JButton();
+
+  JButton cancel = new JButton();
+
+  JPanel jPanel1 = new JPanel();
+
+  JLabel jLabel1 = new JLabel();
+
+  JPanel jPanel2 = new JPanel();
+
+  JPanel jPanel3 = new JPanel();
+
+  BorderLayout borderLayout1 = new BorderLayout();
+
+  public void ok_actionPerformed(ActionEvent e)
+  {
+    if (lineart.isSelected())
+    {
+      value = "Lineart";
+    }
+    else
+    {
+      value = "Text";
+    }
+
+    if (!askAgain.isSelected())
+    {
+      jalview.bin.Cache.applicationProperties.remove("SVG_RENDERING");
+    }
+    else
+    {
+      jalview.bin.Cache.setProperty("SVG_RENDERING", value);
+    }
+
+    dialog.setVisible(false);
+  }
+
+  public void cancel_actionPerformed(ActionEvent e)
+  {
+    cancelled = true;
+    dialog.setVisible(false);
+  }
+
+  public String getValue()
+  {
+    return value;
+  }
+}
index d5b81f1..d73ee70 100755 (executable)
  */
 package jalview.gui;
 
-import java.awt.*;
-import java.awt.image.*;
-import javax.swing.*;
-
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+import java.awt.BasicStroke;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.image.BufferedImage;
+
+import javax.swing.JComponent;
 
 /**
  * DOCUMENT ME!
@@ -247,16 +258,11 @@ public class SeqCanvas extends JComponent
    */
   public void fastPaint(int horizontal, int vertical)
   {
-    if (fastpainting)
+    if (fastpainting || gg == null)
     {
       return;
     }
     fastpainting = true;
-    if (gg == null)
-    {
-      return;
-    }
-
     fastPaint = true;
 
     gg.copyArea(horizontal * av.charWidth, vertical * av.charHeight,
@@ -575,7 +581,7 @@ public class SeqCanvas extends JComponent
           annotations = new AnnotationPanel(av);
         }
 
-        annotations.renderer.drawComponent(annotations, av, (Graphics2D) g,
+        annotations.renderer.drawComponent(annotations, av, g,
                 -1, startRes, endx + 1);
         g.translate(0, -cHeight - ypos - 3);
       }
@@ -763,7 +769,7 @@ public class SeqCanvas extends JComponent
 
     if ((group == null) && (av.getAlignment().getGroups().size() > 0))
     {
-      group = (SequenceGroup) av.getAlignment().getGroups().get(0);
+      group = av.getAlignment().getGroups().get(0);
       groupIndex = 0;
     }
 
@@ -924,7 +930,7 @@ public class SeqCanvas extends JComponent
           break;
         }
 
-        group = (SequenceGroup) av.getAlignment().getGroups()
+        group = av.getAlignment().getGroups()
                 .get(groupIndex);
 
       } while (groupIndex < av.getAlignment().getGroups().size());
index 48800c3..c10a4a9 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.gui;
 
 import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.Sequence;
@@ -1186,7 +1187,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, groupSeqs,
+          editCommand.appendEdit(Action.INSERT_GAP, groupSeqs,
                   startres, startres - lastres, av.getAlignment(), true);
         }
       }
@@ -1202,7 +1203,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.DELETE_GAP, groupSeqs,
+          editCommand.appendEdit(Action.DELETE_GAP, groupSeqs,
                   startres, lastres - startres, av.getAlignment(), true);
         }
 
@@ -1224,7 +1225,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
         else
         {
-          editCommand.appendEdit(EditCommand.INSERT_GAP, new SequenceI[]
+          editCommand.appendEdit(Action.INSERT_GAP, new SequenceI[]
           { seq }, lastres, startres - lastres, av.getAlignment(), true);
         }
       }
@@ -1261,7 +1262,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
             if (max > 0)
             {
-              editCommand.appendEdit(EditCommand.DELETE_GAP,
+              editCommand.appendEdit(Action.DELETE_GAP,
                       new SequenceI[]
                       { seq }, startres, max, av.getAlignment(), true);
             }
@@ -1279,7 +1280,7 @@ public class SeqPanel extends JPanel implements MouseListener,
           }
           else
           {
-            editCommand.appendEdit(EditCommand.INSERT_NUC, new SequenceI[]
+            editCommand.appendEdit(Action.INSERT_NUC, new SequenceI[]
             { seq }, lastres, startres - lastres, av.getAlignment(), true);
           }
         }
@@ -1315,10 +1316,10 @@ public class SeqPanel extends JPanel implements MouseListener,
       }
     }
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, blankColumn, 1,
+    editCommand.appendEdit(Action.DELETE_GAP, seq, blankColumn, 1,
             av.getAlignment(), true);
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, j, 1,
+    editCommand.appendEdit(Action.INSERT_GAP, seq, j, 1,
             av.getAlignment(), true);
 
   }
@@ -1326,10 +1327,10 @@ public class SeqPanel extends JPanel implements MouseListener,
   void deleteChar(int j, SequenceI[] seq, int fixedColumn)
   {
 
-    editCommand.appendEdit(EditCommand.DELETE_GAP, seq, j, 1,
+    editCommand.appendEdit(Action.DELETE_GAP, seq, j, 1,
             av.getAlignment(), true);
 
-    editCommand.appendEdit(EditCommand.INSERT_GAP, seq, fixedColumn, 1,
+    editCommand.appendEdit(Action.INSERT_GAP, seq, fixedColumn, 1,
             av.getAlignment(), true);
   }
 
index 8c889c9..4a74c9c 100644 (file)
@@ -436,7 +436,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
   protected void revert_actionPerformed(ActionEvent e)
   {
     reInitDialog(lastParmSet);
-
+    updateWebServiceMenus();
   }
 
   protected void update_actionPerformed(ActionEvent e)
@@ -465,6 +465,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
       _deleteUserPreset(lastParmSet);
     }
     reInitDialog(null); // service default
+    updateWebServiceMenus();
   }
 
   protected void create_actionPerformed(ActionEvent e)
@@ -475,7 +476,9 @@ public class WsJobParameters extends JPanel implements ItemListener,
       _storeCurrentPreset(curname);
       lastParmSet = curname;
       isUserPreset = true;
+      reInitDialog(curname);
       initArgSetModified();
+      updateWebServiceMenus();
     }
     else
     {
@@ -953,7 +956,7 @@ public class WsJobParameters extends JPanel implements ItemListener,
     {
       Vector<String> services = new Vector<String>();
       services.addElement(args[p++]);
-      Jws2Discoverer.setServiceUrls(services);
+      Jws2Discoverer.getDiscoverer().setServiceUrls(services);
     }
     try
     {
@@ -1295,7 +1298,18 @@ public class WsJobParameters extends JPanel implements ItemListener,
     SetNamePanel.validate();
     validate();
     settingDialog = false;
+  }
 
+  /**
+   * Rebuild the AlignFrame web service menus (after add/delete of a preset
+   * option).
+   */
+  protected void updateWebServiceMenus()
+  {
+    for (AlignFrame alignFrame : Desktop.getAlignframes())
+    {
+      alignFrame.BuildWebServiceMenu();
+    }
   }
 
   String curSetName = null;
index 0674352..527750c 100644 (file)
@@ -33,6 +33,7 @@ import java.awt.Dimension;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.net.URL;
+import java.util.List;
 import java.util.Vector;
 
 import javax.swing.JLabel;
@@ -52,7 +53,9 @@ public class WsPreferences extends GWsPreferences
     initFromPreferences();
   }
 
-  Vector<String> wsUrls, oldUrls, rsbsUrls, oldRsbsUrls;
+  List<String> wsUrls;
+
+  Vector<String> oldUrls, rsbsUrls, oldRsbsUrls;
 
   private boolean needWsMenuUpdate;
 
@@ -62,8 +65,8 @@ public class WsPreferences extends GWsPreferences
   private void initFromPreferences()
   {
 
-    wsUrls = jalview.ws.jws2.Jws2Discoverer.getServiceUrls();
-    if (wsUrls != null)
+    wsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
+    if (!wsUrls.isEmpty())
     {
       oldUrls = new Vector<String>(wsUrls);
     }
@@ -235,7 +238,7 @@ public class WsPreferences extends GWsPreferences
 
   private void updateServiceList()
   {
-    jalview.ws.jws2.Jws2Discoverer.setServiceUrls(wsUrls);
+    Jws2Discoverer.getDiscoverer().setServiceUrls(wsUrls);
   }
 
   private void updateRsbsServiceList()
@@ -256,7 +259,7 @@ public class WsPreferences extends GWsPreferences
     int sel = wsList.getSelectedRow();
     if (sel > -1)
     {
-      wsUrls.removeElementAt(sel);
+      wsUrls.remove(sel);
       update++;
       updateList();
     }
@@ -274,21 +277,22 @@ public class WsPreferences extends GWsPreferences
     int sel = wsList.getSelectedRow();
     if (sel > -1)
     {
-      String url = editUrl(wsUrls.elementAt(sel), MessageManager.getString("label.edit_jabaws_url"));
+      String url = editUrl(wsUrls.get(sel),
+              MessageManager.getString("label.edit_jabaws_url"));
       if (url != null)
       {
         int present = wsUrls.indexOf(url);
         if (present == -1)
         {
           update++;
-          wsUrls.setElementAt(url, sel);
+          wsUrls.set(sel, url);
           updateList();
         }
         else
         {
           if (present != sel)
           {
-            wsUrls.removeElementAt(sel);
+            wsUrls.remove(sel);
             updateList();
           }
         }
@@ -406,8 +410,8 @@ public class WsPreferences extends GWsPreferences
     if (p > -1 && p < wsUrls.size() - 1)
     {
       String t = wsUrls.get(p + 1);
-      wsUrls.setElementAt(wsUrls.elementAt(p), p + 1);
-      wsUrls.setElementAt(t, p);
+      wsUrls.set(p + 1, wsUrls.get(p));
+      wsUrls.set(p, t);
       updateList();
       wsList.getSelectionModel().setSelectionInterval(p + 1, p + 1);
       update++;
@@ -428,8 +432,8 @@ public class WsPreferences extends GWsPreferences
     if (p > 0)
     {
       String t = wsUrls.get(p - 1);
-      wsUrls.setElementAt(wsUrls.elementAt(p), p - 1);
-      wsUrls.setElementAt(t, p);
+      wsUrls.set(p - 1, wsUrls.get(p));
+      wsUrls.set(p, t);
       updateList();
       wsList.getSelectionModel().setSelectionInterval(p - 1, p - 1);
       update++;
@@ -487,7 +491,7 @@ public class WsPreferences extends GWsPreferences
 
       if (validate == JOptionPane.OK_OPTION)
       {
-        if (jalview.ws.jws2.Jws2Discoverer.testServiceUrl(foo))
+        if (Jws2Discoverer.testServiceUrl(foo))
         {
           return foo.toString();
         }
@@ -544,11 +548,11 @@ public class WsPreferences extends GWsPreferences
         int selind = wsList.getSelectedRow();
         if (selind > -1)
         {
-          wsUrls.insertElementAt(url, selind);
+          wsUrls.add(selind, url);
         }
         else
         {
-          wsUrls.addElement(url);
+          wsUrls.add(url);
         }
         update++;
         updateList();
@@ -651,8 +655,8 @@ public class WsPreferences extends GWsPreferences
   @Override
   protected void resetWs_actionPerformed(ActionEvent e)
   {
-    jalview.ws.jws2.Jws2Discoverer.setServiceUrls(null);
-    Vector nwsUrls = jalview.ws.jws2.Jws2Discoverer.getServiceUrls();
+    Jws2Discoverer.getDiscoverer().setServiceUrls(null);
+    List<String> nwsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
     if (!wsUrls.equals(nwsUrls))
     {
       update++;
index 5366cb4..d3b19fa 100755 (executable)
@@ -123,6 +123,21 @@ public class AppletFormatAdapter
 
   public static String CLASSLOADER = "ClassLoader";
 
+  /**
+   * add jalview-derived non-secondary structure annotation from PDB structure
+   */
+  boolean annotFromStructure = false;
+
+  /**
+   * add secondary structure from PDB data with built-in algorithms
+   */
+  boolean localSecondaryStruct = false;
+
+  /**
+   * process PDB data with web services
+   */
+  boolean serviceSecondaryStruct = false;
+
   AlignFile afile = null;
 
   String inFile;
@@ -236,7 +251,8 @@ public class AppletFormatAdapter
       }
       else if (format.equals("PDB"))
       {
-        afile = new MCview.PDBfile(true,true,inFile, type);
+        afile = new MCview.PDBfile(annotFromStructure,
+                localSecondaryStruct, serviceSecondaryStruct, inFile, type);
         // Uncomment to test Jmol data based PDB processing: JAL-1213
         // afile = new jalview.ext.jmol.PDBFileWithJmol(inFile, type);
       }
@@ -357,7 +373,8 @@ public class AppletFormatAdapter
       }
       else if (format.equals("PDB"))
       {
-        afile = new MCview.PDBfile(true,true,source);
+        afile = new MCview.PDBfile(annotFromStructure,
+                localSecondaryStruct, serviceSecondaryStruct, source);
       }
       else if (format.equals("STH"))
       {
index c2a317a..8ca0c35 100755 (executable)
 package jalview.io;
 
 import jalview.api.AlignViewportI;
-import jalview.datamodel.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
 
 /**
  * Additional formatting methods used by the application in a number of places.
@@ -32,6 +38,26 @@ import jalview.datamodel.*;
 public class FormatAdapter extends AppletFormatAdapter
 {
 
+  public FormatAdapter()
+  {
+    super();
+    if (jalview.bin.Cache.getDefault("STRUCT_FROM_PDB", true))
+    {
+      annotFromStructure = jalview.bin.Cache.getDefault("ADD_TEMPFACT_ANN",
+              true);
+      localSecondaryStruct = jalview.bin.Cache.getDefault("ADD_SS_ANN",
+            true);
+    serviceSecondaryStruct = jalview.bin.Cache.getDefault("USE_RNAVIEW",
+            true);
+    }
+    else
+    {
+      // disable all PDB annotation options
+      annotFromStructure = false;
+      localSecondaryStruct = false;
+      serviceSecondaryStruct = false;
+    }
+  }
   public String formatSequences(String format, SequenceI[] seqs,
           String[] omitHiddenColumns)
   {
@@ -154,8 +180,10 @@ public class FormatAdapter extends AppletFormatAdapter
   public boolean getCacheSuffixDefault(String format)
   {
     if (isValidFormat(format))
+    {
       return jalview.bin.Cache.getDefault(format.toUpperCase()
               + "_JVSUFFIX", true);
+    }
     return false;
   }
 
index d366edc..c075fda 100644 (file)
  */
 package jalview.io;
 
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-
 import jalview.analysis.SecStrConsensus.SimpleBP;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
@@ -33,6 +27,14 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.util.MessageManager;
 
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.stevesoft.pat.Regex;
+
 import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
 import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
 import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
@@ -139,6 +141,14 @@ public class RnamlFile extends AlignFile
       int end = seq.length();
 
       id = current.getName();
+      if (id == null || id.trim().length() == 0)
+      {
+        id = safeName(getDataName());
+        if (result.size() > 1)
+        {
+          id += "." + i;
+        }
+      }
       seqs[i] = new Sequence(id, seq, begin, end);
 
       seqs[i].setEnd(seqs[i].findPosition(seqs[i].getLength()));
@@ -157,8 +167,11 @@ public class RnamlFile extends AlignFile
                         annot[k]).charAt(0), 0f);
       }
 
-      AlignmentAnnotation align = new AlignmentAnnotation("Sec. str.",
-              current.getID(), ann);
+      AlignmentAnnotation align = new AlignmentAnnotation(
+              "Secondary Structure",
+              current.getID().trim().length() > 0 ? "Secondary Structure for "
+                      + current.getID()
+                      : "", ann);
 
       seqs[i].addAlignmentAnnotation(align);
       seqs[i].setRNA(result.get(i));
@@ -204,13 +217,18 @@ public class RnamlFile extends AlignFile
   private String safeName(String dataName)
   {
     int b = 0;
-    while ((b = dataName.indexOf("/")) > -1 && b < dataName.length())
+    if ((b = dataName.lastIndexOf(".")) > 0)
     {
-      dataName = dataName.substring(b + 1).trim();
-
+      dataName = dataName.substring(0, b - 1);
+    }
+    b = 0;
+    Regex m = new Regex("[\\/]?([-A-Za-z0-9]+)\\.?");
+    String mm = dataName;
+    while (m.searchFrom(dataName, b))
+    {
+      mm = m.stringMatched();
+      b = m.matchedTo();
     }
-    int e = (dataName.length() - dataName.indexOf(".")) + 1;
-    dataName = dataName.substring(1, e).trim();
-    return dataName;
+    return mm;
   }
 }
index 0a18be0..96c462c 100644 (file)
@@ -23,7 +23,6 @@
  */
 package jalview.io;
 
-import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
@@ -41,7 +40,9 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
@@ -186,7 +187,7 @@ public class StockholmFile extends AlignFile
     String version;
     // String id;
     Hashtable seqAnn = new Hashtable(); // Sequence related annotations
-    Hashtable seqs = new Hashtable();
+    LinkedHashMap<String, String> seqs = new LinkedHashMap<String, String>();
     Regex p, r, rend, s, x;
     // Temporary line for processing RNA annotation
     // String RNAannot = "";
@@ -198,7 +199,9 @@ public class StockholmFile extends AlignFile
     r = new Regex("# STOCKHOLM ([\\d\\.]+)");
     if (!r.search(nextLine()))
     {
-      throw new IOException(MessageManager.getString("exception.stockholm_invalid_format"));
+      throw new IOException(
+              MessageManager
+                      .getString("exception.stockholm_invalid_format"));
     }
     else
     {
@@ -258,12 +261,11 @@ public class StockholmFile extends AlignFile
           }
         }
         // logger.debug("Number of sequences: " + this.noSeqs);
-        Enumeration accs = seqs.keys();
-        while (accs.hasMoreElements())
+        for (Map.Entry<String, String> skey : seqs.entrySet())
         {
-          String acc = (String) accs.nextElement();
           // logger.debug("Processing sequence " + acc);
-          String seq = (String) seqs.remove(acc);
+          String acc = skey.getKey();
+          String seq = skey.getValue();
           if (maxLength < seq.length())
           {
             maxLength = seq.length();
@@ -367,6 +369,7 @@ public class StockholmFile extends AlignFile
                     AlignmentAnnotation an = (AlignmentAnnotation) vv
                             .elementAt(ii);
                     seqO.addAlignmentAnnotation(an);
+                    annotations.add(an);
                   }
                 }
               }
@@ -416,9 +419,11 @@ public class StockholmFile extends AlignFile
         if (!x.search(line))
         {
           // logger.error("Could not parse sequence line: " + line);
-          throw new IOException(MessageManager.formatMessage("exception.couldnt_parse_sequence_line", new String[]{line}));
+          throw new IOException(MessageManager.formatMessage(
+                  "exception.couldnt_parse_sequence_line", new String[]
+                  { line }));
         }
-        String ns = (String) seqs.get(x.stringMatched(1));
+        String ns = seqs.get(x.stringMatched(1));
         if (ns == null)
         {
           ns = "";
@@ -528,7 +533,9 @@ public class StockholmFile extends AlignFile
           }
           else
           {
-            throw new IOException(MessageManager.formatMessage("exception.error_parsing_line", new String[]{line}));
+            throw new IOException(MessageManager.formatMessage(
+                    "exception.error_parsing_line", new String[]
+                    { line }));
           }
         }
         else if (annType.equals("GC"))
@@ -636,9 +643,13 @@ public class StockholmFile extends AlignFile
               strucAnn = new Hashtable();
             }
 
-            Vector newStruc = new Vector();
+            Vector<AlignmentAnnotation> newStruc = new Vector<AlignmentAnnotation>();
             parseAnnotationRow(newStruc, type, ns);
-
+            for (AlignmentAnnotation alan : newStruc)
+            {
+              alan.visible = false;
+            }
+            // annotations.addAll(newStruc);
             strucAnn.put(type, newStruc);
             seqAnn.put(acc, strucAnn);
           }
@@ -653,7 +664,9 @@ public class StockholmFile extends AlignFile
         }
         else
         {
-          throw new IOException(MessageManager.formatMessage("exception.unknown_annotation_detected", new String[]{annType,annContent}));
+          throw new IOException(MessageManager.formatMessage(
+                  "exception.unknown_annotation_detected", new String[]
+                  { annType, annContent }));
         }
       }
     }
@@ -813,25 +826,29 @@ public class StockholmFile extends AlignFile
       // be written out
       if (ss)
       {
-        if (detectbrackets.search(pos))
-        {
-          ann.secondaryStructure = jalview.schemes.ResidueProperties
-                  .getRNASecStrucState(pos).charAt(0);
-        }
-        else
+        //if (" .-_".indexOf(pos) == -1)
         {
-          ann.secondaryStructure = jalview.schemes.ResidueProperties
-                  .getDssp3state(pos).charAt(0);
-        }
+          if (detectbrackets.search(pos))
+          {
+            ann.secondaryStructure = jalview.schemes.ResidueProperties
+                    .getRNASecStrucState(pos).charAt(0);
+          }
+          else
+          {
+            ann.secondaryStructure = jalview.schemes.ResidueProperties
+                    .getDssp3state(pos).charAt(0);
+          }
 
-        if (ann.secondaryStructure == pos.charAt(0) || pos.charAt(0) == 'C')
-        {
-          ann.displayCharacter = ""; // null; // " ";
-        }
-        else
-        {
-          ann.displayCharacter = " " + ann.displayCharacter;
+          if (ann.secondaryStructure == pos.charAt(0))
+          {
+            ann.displayCharacter = ""; // null; // " ";
+          }
+          else
+          {
+            ann.displayCharacter = " " + ann.displayCharacter;
+          }
         }
+        
       }
 
       els[i] = ann;
@@ -842,7 +859,9 @@ public class StockholmFile extends AlignFile
     {
       annot = (AlignmentAnnotation) e.nextElement();
       if (annot.label.equals(type))
+      {
         break;
+      }
       annot = null;
     }
     if (annot == null)
@@ -887,7 +906,9 @@ public class StockholmFile extends AlignFile
         for (int idb = 0; idb < s[in].getDBRef().length; idb++)
         {
           if (dataRef == null)
+          {
             dataRef = new Hashtable();
+          }
 
           String datAs1 = s[in].getDBRef()[idb].getSource().toString()
                   + " ; "
@@ -960,39 +981,19 @@ public class StockholmFile extends AlignFile
             String key = type2id(feature);
 
             if (key == null)
+            {
               continue;
+            }
 
             // out.append("#=GR ");
             out.append(new Format("%-" + maxid + "s").form("#=GR "
                     + printId(s[i]) + " " + key + " "));
             ann = alAnot[j].annotations;
+            boolean isrna = alAnot[j].isValidStruc();
             String seq = "";
             for (int k = 0; k < ann.length; k++)
             {
-              annot = ann[k];
-              String ch = (annot == null) ? Character.toString(s[i]
-                      .getCharAt(k)) : annot.displayCharacter;
-              if (ch.length() == 0)
-              {
-                if (key.equals("SS"))
-                {
-                  char ll = annot.secondaryStructure;
-                  seq = (Character.toString(ll).equals(" ")) ? seq + "C"
-                          : seq + ll;
-                }
-                else
-                {
-                  seq += ".";
-                }
-              }
-              else if (ch.length() == 1)
-              {
-                seq += ch;
-              }
-              else if (ch.length() > 1)
-              {
-                seq += ch.charAt(1);
-              }
+              seq += outputCharacter(key, k, isrna, ann, s[i]);
             }
             out.append(seq);
             out.append(newline);
@@ -1013,43 +1014,33 @@ public class StockholmFile extends AlignFile
       for (int ia = 0; ia < al.getAlignmentAnnotation().length; ia++)
       {
         aa = al.getAlignmentAnnotation()[ia];
-        if (aa.autoCalculated || !aa.visible)
+        if (aa.autoCalculated || !aa.visible || aa.sequenceRef != null)
         {
           continue;
         }
         String seq = "";
         String label;
-
+        String key = "";
         if (aa.label.equals("seq"))
+        {
           label = "seq_cons";
+        }
         else
-          label = type2id(aa.label.toLowerCase()) + "_cons";
+        {
+          label = (key = type2id(aa.label.toLowerCase())) + "_cons";
+        }
 
         if (label == null)
+        {
           label = aa.label;
+        }
 
         out.append(new Format("%-" + maxid + "s").form("#=GC " + label
                 + " "));
+        boolean isrna = aa.isValidStruc();
         for (int j = 0; j < aa.annotations.length; j++)
         {
-          String ch = (aa.annotations[j] == null) ? "-"
-                  : aa.annotations[j].displayCharacter;
-          if (ch.length() == 0)
-          {
-            char ll = aa.annotations[j].secondaryStructure;
-            if (Character.toString(ll).equals(" "))
-              seq += "C";
-            else
-              seq += ll;
-          }
-          else if (ch.length() == 1)
-          {
-            seq += ch;
-          }
-          else if (ch.length() > 1)
-          {
-            seq += ch.charAt(1);
-          }
+          seq += outputCharacter(key, j, isrna, aa.annotations, null);
         }
         out.append(seq);
         out.append(newline);
@@ -1058,6 +1049,57 @@ public class StockholmFile extends AlignFile
     return out.toString();
   }
 
+  /**
+   * add an annotation character to the output row
+   * 
+   * @param seq
+   * @param key
+   * @param k
+   * @param isrna
+   * @param ann
+   * @param sequenceI
+   */
+  private char outputCharacter(String key, int k,
+          boolean isrna, Annotation[] ann, SequenceI sequenceI)
+  {
+    char seq = ' ';
+    Annotation annot = ann[k];
+    String ch = (annot == null) ? ((sequenceI == null) ? "-" : Character
+            .toString(sequenceI.getCharAt(k)))
+            : annot.displayCharacter;
+    if (key.equals("SS"))
+    {
+      if (annot == null)
+      {
+        // sensible gap character if one is available or make one up
+        return sequenceI == null ? '-' : sequenceI
+                .getCharAt(k);
+      }
+      else
+      {
+        // valid secondary structure AND no alternative label (e.g. ' B')
+        if (annot.secondaryStructure > ' ' && ch.length() < 2)
+        {
+          return annot.secondaryStructure;
+        }
+      }
+    }
+
+    if (ch.length() == 0)
+    {
+      seq = '.';
+    }
+    else if (ch.length() == 1)
+    {
+      seq = ch.charAt(0);
+    }
+    else if (ch.length() > 1)
+    {
+      seq = ch.charAt(1);
+    }
+    return seq;
+  }
+
   public String print()
   {
     out = new StringBuffer();
@@ -1121,7 +1163,7 @@ public class StockholmFile extends AlignFile
     }
     if (key != null)
     {
-      return (String) key;
+      return key;
     }
     System.err.println("Warning : Unknown Stockholm annotation type: "
             + type);
index 77af496..387bb7f 100755 (executable)
@@ -1753,7 +1753,7 @@ public class GAlignFrame extends JInternalFrame
     sortByAnnotScore.setText(MessageManager
             .getString("label.sort_by_score"));
     sort.add(sortByAnnotScore);
-    sortByAnnotScore.addMenuListener(new javax.swing.event.MenuListener()
+    sort.addMenuListener(new javax.swing.event.MenuListener()
     {
 
       @Override
index a232377..5569c24 100755 (executable)
@@ -26,6 +26,7 @@ import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
 import java.awt.Font;
@@ -36,6 +37,7 @@ import java.awt.Insets;
 import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
@@ -45,6 +47,7 @@ import javax.swing.DefaultListCellRenderer;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
 import javax.swing.JLabel;
 import javax.swing.JList;
 import javax.swing.JPanel;
@@ -56,6 +59,8 @@ import javax.swing.SwingConstants;
 import javax.swing.border.Border;
 import javax.swing.border.EmptyBorder;
 import javax.swing.border.TitledBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 
@@ -128,8 +133,10 @@ public class GPreferences extends JPanel
   protected JCheckBox showNpTooltip = new JCheckBox();
 
   /*
-   * Annotations tab components
+   * Structure tab and components
    */
+  protected JPanel structureTab;
+
   protected JCheckBox structFromPdb = new JCheckBox();
 
   protected JCheckBox useRnaView = new JCheckBox();
@@ -239,7 +246,7 @@ public class GPreferences extends JPanel
    */
   private void jbInit() throws Exception
   {
-    JTabbedPane tabbedPane = new JTabbedPane();
+    final JTabbedPane tabbedPane = new JTabbedPane();
     this.setLayout(new BorderLayout());
     JPanel okCancelPanel = initOkCancelPanel();
     this.add(tabbedPane, BorderLayout.CENTER);
@@ -273,6 +280,31 @@ public class GPreferences extends JPanel
      */
     wsTab.setLayout(new BorderLayout());
     tabbedPane.add(wsTab, MessageManager.getString("label.web_services"));
+
+    /*
+     * Handler to validate a tab before leaving it - currently only for
+     * Structure.
+     */
+    tabbedPane.addChangeListener(new ChangeListener()
+    {
+      private Component lastTab;
+
+      @Override
+      public void stateChanged(ChangeEvent e)
+      {
+        if (lastTab == structureTab
+                && tabbedPane.getSelectedComponent() != structureTab)
+        {
+          if (!validateStructure())
+          {
+            tabbedPane.setSelectedComponent(structureTab);
+            return;
+          }
+        }
+        lastTab = tabbedPane.getSelectedComponent();
+      }
+
+    });
   }
 
   /**
@@ -691,7 +723,8 @@ public class GPreferences extends JPanel
    */
   private JPanel initStructureTab()
   {
-    JPanel structureTab = new JPanel();
+    structureTab = new JPanel();
+
     structureTab.setBorder(new TitledBorder(MessageManager
             .getString("label.structure_options")));
     structureTab.setLayout(null);
@@ -756,20 +789,81 @@ public class GPreferences extends JPanel
     pathLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
     pathLabel.setHorizontalAlignment(SwingConstants.LEFT);
     pathLabel.setText(MessageManager.getString("label.chimera_path"));
-    pathLabel.setToolTipText(MessageManager
-            .getString("label.chimera_path_tip"));
+    final String tooltip = JvSwingUtils.wrapTooltip(true,
+            MessageManager.getString("label.chimera_path_tip"));
+    pathLabel.setToolTipText(tooltip);
     pathLabel.setBounds(new Rectangle(10, ypos, 140, height));
     structureTab.add(pathLabel);
 
     chimeraPath.setFont(verdana11);
     chimeraPath.setText("");
     chimeraPath.setBounds(new Rectangle(160, ypos, 300, height));
+    chimeraPath.addMouseListener(new MouseAdapter()
+    {
+      @Override
+      public void mouseClicked(MouseEvent e)
+      {
+        if (e.getClickCount() == 2)
+        {
+          String chosen = openFileChooser();
+          if (chosen != null)
+          {
+            chimeraPath.setText(chosen);
+          }
+        }
+      }
+    });
     structureTab.add(chimeraPath);
 
     return structureTab;
   }
 
   /**
+   * Show a dialog for the user to choose a file. Returns the chosen path, or
+   * null on Cancel.
+   * 
+   * @return
+   */
+  protected String openFileChooser()
+  {
+    String choice = null;
+    JFileChooser chooser = new JFileChooser();
+
+    // chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle(MessageManager
+            .getString("label.open_local_file"));
+    chooser.setToolTipText(MessageManager.getString("action.open"));
+
+    int value = chooser.showOpenDialog(this);
+
+    if (value == JFileChooser.APPROVE_OPTION)
+    {
+      choice = chooser.getSelectedFile().getPath();
+    }
+    return choice;
+  }
+
+  /**
+   * Validate the structure tab preferences; if invalid, set focus on this tab.
+   * 
+   * @param e
+   */
+  protected boolean validateStructure(FocusEvent e)
+  {
+    if (!validateStructure())
+    {
+      e.getComponent().requestFocusInWindow();
+      return false;
+    }
+    return true;
+  }
+
+  protected boolean validateStructure()
+  {
+    return false;
+  }
+
+  /**
    * Initialises the Visual tabbed panel.
    * 
    * @return
index e731910..d5b2f49 100644 (file)
@@ -27,6 +27,7 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
 import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ResidueProperties;
 
 import java.awt.BasicStroke;
 import java.awt.Color;
@@ -77,17 +78,17 @@ public class AnnotationRenderer
     int x2 = (x * charWidth);
     Regex closeparen = new Regex("(\\))");
 
-    String dc = (column == 0 || row_annotations[column - 1] == null) ? ""
-            : row_annotations[column - 1].displayCharacter;
+    char dc = (column == 0 || row_annotations[column - 1] == null) ? ' '
+            : row_annotations[column - 1].secondaryStructure;
 
     boolean diffupstream = sCol == 0 || row_annotations[sCol - 1] == null
-            || !dc.equals(row_annotations[sCol - 1].displayCharacter);
+            || dc != row_annotations[sCol - 1].secondaryStructure;
     boolean diffdownstream = !validRes || !validEnd
             || row_annotations[column] == null
-            || !dc.equals(row_annotations[column].displayCharacter);
+            || dc != row_annotations[column].secondaryStructure;
     // System.out.println("Column "+column+" diff up: "+diffupstream+" down:"+diffdownstream);
     // If a closing base pair half of the stem, display a backward arrow
-    if (column > 0 && closeparen.search(dc))
+    if (column > 0 && ResidueProperties.isCloseParenRNA(dc))
     {
 
       if (diffupstream)
@@ -574,11 +575,15 @@ public class AnnotationRenderer
                 }
               }
             }
-            if (!row.isValidStruc())
+            if (row.getInvalidStrucPos() > x)
             {
               g.setColor(Color.orange);
-              g.fillRect((int) row.getInvalidStrucPos() * charWidth, y,
-                      charWidth, charHeight);
+              g.fillRect(x * charWidth, y, charWidth, charHeight);
+            }
+            else if (row.getInvalidStrucPos() == x)
+            {
+              g.setColor(Color.orange.darker());
+              g.fillRect(x * charWidth, y, charWidth, charHeight);
             }
             if (validCharWidth
                     && validRes
@@ -617,9 +622,13 @@ public class AnnotationRenderer
               charOffset = (int) ((charWidth - fmWidth) / 2f);
 
               if (row_annotations[column].colour == null)
+              {
                 g.setColor(Color.black);
+              }
               else
+              {
                 g.setColor(row_annotations[column].colour);
+              }
 
               if (column == 0 || row.graph > 0)
               {
@@ -1190,9 +1199,13 @@ public class AnnotationRenderer
       }
 
       if (aa_annotations[column].colour == null)
+      {
         g.setColor(Color.black);
+      }
       else
+      {
         g.setColor(aa_annotations[column].colour);
+      }
 
       y1 = y
               - (int) (((aa_annotations[column - 1].value - min) / range) * graphHeight);
@@ -1264,9 +1277,13 @@ public class AnnotationRenderer
         continue;
       }
       if (aa_annotations[column].colour == null)
+      {
         g.setColor(Color.black);
+      }
       else
+      {
         g.setColor(aa_annotations[column].colour);
+      }
 
       y1 = y
               - (int) (((aa_annotations[column].value - min) / (range)) * _aa.graphHeight);
@@ -1384,9 +1401,13 @@ public class AnnotationRenderer
       if (aa_annotations[j] != null)
       {
         if (aa_annotations[j].colour == null)
+        {
           g.setColor(Color.black);
+        }
         else
+        {
           g.setColor(aa_annotations[j].colour);
+        }
 
         height = (int) ((aa_annotations[j].value / _aa.graphMax) * y);
         if (height > y)
index 713e55d..3cada8b 100755 (executable)
@@ -53,7 +53,6 @@ public class AnnotationColourGradient extends FollowerColourScheme
   private boolean predefinedColours = false;
 
   private boolean seqAssociated = false;
-
   /**
    * false if the scheme was constructed without a minColour and maxColour used
    * to decide if existing colours should be taken from annotation elements when
@@ -141,6 +140,12 @@ public class AnnotationColourGradient extends FollowerColourScheme
     bb = maxColour.getBlue() - b1;
 
     noGradient = false;
+    aamax = annotation.graphMax;
+    aamin = annotation.graphMin;
+    if (annotation.isRNA())
+    {
+      ColourSchemeProperty.initRnaHelicesShading(1 + (int) aamax);
+    }
   }
 
   @Override
@@ -162,6 +167,7 @@ public class AnnotationColourGradient extends FollowerColourScheme
       // resolve the context containing all the annotation for the sequence
       AnnotatedCollectionI alcontext = alignment instanceof AlignmentI ? alignment
               : alignment.getContext();
+      boolean f = true,rna=false;
       for (AlignmentAnnotation alan : alcontext.findAnnotation(annotation
               .getCalcId()))
       {
@@ -169,12 +175,30 @@ public class AnnotationColourGradient extends FollowerColourScheme
                 && (alan.label != null && annotation != null && alan.label
                         .equals(annotation.label)))
         {
+          if (!rna && alan.isRNA())
+          {
+            rna = true;
+          }
           seqannot.put(alan.sequenceRef, alan);
+          if (f || alan.graphMax > aamax)
+          {
+            aamax = alan.graphMax;
+          }
+          if (f || alan.graphMin < aamin)
+          {
+            aamin = alan.graphMin;
+          }
+          f = false;
         }
       }
+      if (rna)
+      {
+        ColourSchemeProperty.initRnaHelicesShading(1 + (int) aamax);
+      }
     }
   }
 
+  float aamin = 0f, aamax = 0f;
   public String getAnnotation()
   {
     return annotation.label;
@@ -278,9 +302,16 @@ public class AnnotationColourGradient extends FollowerColourScheme
               }
               else
               {
-              currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
-                      : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
-                              : jalview.renderer.AnnotationRenderer.STEM_COLOUR;
+                if (annotation.isRNA())
+                {
+                  currentColour = ColourSchemeProperty.rnaHelices[(int) aj.value];
+                }
+                else
+                {
+                  currentColour = annotation.annotations[j].secondaryStructure == 'H' ? jalview.renderer.AnnotationRenderer.HELIX_COLOUR
+                          : annotation.annotations[j].secondaryStructure == 'E' ? jalview.renderer.AnnotationRenderer.SHEET_COLOUR
+                                  : jalview.renderer.AnnotationRenderer.STEM_COLOUR;
+                }
               }
             }
             else
@@ -305,35 +336,7 @@ public class AnnotationColourGradient extends FollowerColourScheme
           }
           else
           {
-            // calculate a shade
-            float range = 1f;
-            if (thresholdIsMinMax
-                    && annotation.threshold != null
-                    && aboveAnnotationThreshold == ABOVE_THRESHOLD
-                    && annotation.annotations[j].value >= annotation.threshold.value)
-            {
-              range = (annotation.annotations[j].value - annotation.threshold.value)
-                      / (annotation.graphMax - annotation.threshold.value);
-            }
-            else if (thresholdIsMinMax
-                    && annotation.threshold != null
-                    && aboveAnnotationThreshold == BELOW_THRESHOLD
-                    && annotation.annotations[j].value >= annotation.graphMin)
-            {
-              range = (annotation.annotations[j].value - annotation.graphMin)
-                      / (annotation.threshold.value - annotation.graphMin);
-            }
-            else
-            {
-              range = (annotation.annotations[j].value - annotation.graphMin)
-                      / (annotation.graphMax - annotation.graphMin);
-            }
-
-            int dr = (int) (rr * range + r1), dg = (int) (gg * range + g1), db = (int) (bb
-                    * range + b1);
-
-            currentColour = new Color(dr, dg, db);
-
+            currentColour = shadeCalculation(annotation, j);
           }
         }
         if (conservationColouring)
@@ -345,6 +348,45 @@ public class AnnotationColourGradient extends FollowerColourScheme
     return currentColour;
   }
 
+  private Color shadeCalculation(AlignmentAnnotation annotation, int j)
+  {
+
+    // calculate a shade
+    float range = 1f;
+    if (thresholdIsMinMax
+            && annotation.threshold != null
+            && aboveAnnotationThreshold == ABOVE_THRESHOLD
+            && annotation.annotations[j].value >= annotation.threshold.value)
+    {
+      range = (annotation.annotations[j].value - annotation.threshold.value)
+              / (annotation.graphMax - annotation.threshold.value);
+    }
+    else if (thresholdIsMinMax && annotation.threshold != null
+            && aboveAnnotationThreshold == BELOW_THRESHOLD
+            && annotation.annotations[j].value >= annotation.graphMin)
+    {
+      range = (annotation.annotations[j].value - annotation.graphMin)
+              / (annotation.threshold.value - annotation.graphMin);
+    }
+    else
+    {
+      if (annotation.graphMax != annotation.graphMin)
+      {
+        range = (annotation.annotations[j].value - annotation.graphMin)
+                / (annotation.graphMax - annotation.graphMin);
+      }
+      else
+      {
+        range = 0f;
+      }
+    }
+
+    int dr = (int) (rr * range + r1), dg = (int) (gg * range + g1), db = (int) (bb
+            * range + b1);
+
+    return new Color(dr, dg, db);
+
+  }
   public boolean isPredefinedColours()
   {
     return predefinedColours;
index cc303d6..57a2dd9 100755 (executable)
@@ -597,4 +597,33 @@ public class ColourSchemeProperty
 
     return col;
   }
+
+  public static Color rnaHelices[] = null;
+
+  public static void initRnaHelicesShading(int n)
+  {
+    int j = 0;
+    if (rnaHelices == null)
+    {
+      rnaHelices = new Color[n + 1];
+    }
+    else if (rnaHelices != null && rnaHelices.length <= n)
+    {
+      Color[] t = new Color[n + 1];
+      System.arraycopy(rnaHelices, 0, t, 0, rnaHelices.length);
+      j = rnaHelices.length;
+      rnaHelices = t;
+    }
+    else
+    {
+      return;
+    }
+    // Generate random colors and store
+    for (; j <= n; j++)
+    {
+      rnaHelices[j] = jalview.util.ColorUtils
+              .generateRandomColor(Color.white);
+    }
+  }
+
 }
index 7ec9e1c..8acf1f2 100755 (executable)
@@ -23,9 +23,13 @@ package jalview.schemes;
 import jalview.analysis.scoremodels.PIDScoreModel;
 import jalview.api.analysis.ScoreModelI;
 
-import java.util.*;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
 import java.util.List;
-import java.awt.*;
+import java.util.Map;
+import java.util.Vector;
 
 public class ResidueProperties
 {
@@ -1451,7 +1455,7 @@ public class ResidueProperties
         propMatrixF[i][j] = 0;
         propMatrixPos[i][j] = 0;
         propMatrixEpos[i][j] = 0;
-        for (Enumeration<String> en = (Enumeration<String>) propHash.keys(); en
+        for (Enumeration<String> en = propHash.keys(); en
                 .hasMoreElements();)
         {
           String ph = en.nextElement();
@@ -1695,7 +1699,9 @@ public class ResidueProperties
    * Used by getRNASecStrucState
    * 
    */
-  public static Hashtable toRNAssState;
+  public static Hashtable<String, String> toRNAssState;
+
+  public static boolean RNAcloseParen[] = new boolean[255];
   static
   {
     toRNAssState = new Hashtable<String, String>();
@@ -1759,7 +1765,15 @@ public class ResidueProperties
     toRNAssState.put("y", "Y");
     toRNAssState.put("Z", "Z");
     toRNAssState.put("z", "Z");
-
+    for (int p = 0; p < RNAcloseParen.length; p++)
+    {
+      RNAcloseParen[p] = false;
+    }
+    for (String k : toRNAssState.keySet())
+    {
+      RNAcloseParen[k.charAt(0)] = k.charAt(0) != toRNAssState.get(k)
+              .charAt(0);
+    }
   }
 
   /**
@@ -1780,7 +1794,8 @@ public class ResidueProperties
       String ssc = ssstring.substring(i, i + 1);
       if (toRNAssState.containsKey(ssc))
       {
-        ss.append((String) toRNAssState.get(ssc));
+        // valid ss character - so return it
+        ss.append(ssc); // (String) toRNAssState.get(ssc));
       }
       else
       {
@@ -1790,6 +1805,11 @@ public class ResidueProperties
     return ss.toString();
   }
 
+  public static boolean isCloseParenRNA(char dc)
+  {
+    return RNAcloseParen[dc];
+  }
+
   // main method generates perl representation of residue property hash
   // / cut here
   public static void main(String[] args)
@@ -1839,4 +1859,5 @@ public class ResidueProperties
     System.out.println("};");
   }
   // to here
+
 }
index ac2897d..4359879 100644 (file)
@@ -46,6 +46,70 @@ public class StructureSelectionManager
 
   StructureMapping[] mappings;
 
+  private boolean processSecondaryStructure = false,
+          secStructServices = false, addTempFacAnnot = false;
+
+  /**
+   * @return true if will try to use external services for processing secondary
+   *         structure
+   */
+  public boolean isSecStructServices()
+  {
+    return secStructServices;
+  }
+
+  /**
+   * control use of external services for processing secondary structure
+   * 
+   * @param secStructServices
+   */
+  public void setSecStructServices(boolean secStructServices)
+  {
+    this.secStructServices = secStructServices;
+  }
+
+  /**
+   * flag controlling addition of any kind of structural annotation
+   * 
+   * @return true if temperature factor annotation will be added
+   */
+  public boolean isAddTempFacAnnot()
+  {
+    return addTempFacAnnot;
+  }
+
+  /**
+   * set flag controlling addition of structural annotation
+   * 
+   * @param addTempFacAnnot
+   */
+  public void setAddTempFacAnnot(boolean addTempFacAnnot)
+  {
+    this.addTempFacAnnot = addTempFacAnnot;
+  }
+
+  /**
+   * 
+   * @return if true, the structure manager will attempt to add secondary
+   *         structure lines for unannotated sequences
+   */
+
+  public boolean isProcessSecondaryStructure()
+  {
+    return processSecondaryStructure;
+  }
+
+  /**
+   * Control whether structure manager will try to annotate mapped sequences
+   * with secondary structure from PDB data.
+   * 
+   * @param enable
+   */
+  public void setProcessSecondaryStructure(boolean enable)
+  {
+    processSecondaryStructure = enable;
+  }
+
   /**
    * debug function - write all mappings to stdout
    */
@@ -245,7 +309,7 @@ public class StructureSelectionManager
      * the tried and tested MCview pdb mapping
      */
     MCview.PDBfile pdb = null;
-    boolean parseSecStr=true;
+    boolean parseSecStr = processSecondaryStructure;
     if (isPDBFileRegistered(pdbFile))
     {
       for (SequenceI sq : sequence)
@@ -274,7 +338,8 @@ public class StructureSelectionManager
     }
     try
     {
-      pdb = new MCview.PDBfile(true, parseSecStr, pdbFile, protocol);
+      pdb = new MCview.PDBfile(addTempFacAnnot, parseSecStr,
+              secStructServices, pdbFile, protocol);
       if (pdb.id != null && pdb.id.trim().length() > 0
               && AppletFormatAdapter.FILE.equals(protocol))
       {
index 61ef34f..b410be6 100755 (executable)
@@ -21,6 +21,7 @@
 package jalview.util;
 
 import jalview.gui.EPSOptions;
+import jalview.gui.SVGOptions;
 import jalview.io.JalviewFileChooser;
 
 import java.awt.Component;
@@ -34,6 +35,7 @@ import java.io.FileOutputStream;
 import javax.imageio.ImageIO;
 
 import org.jfree.graphics2d.svg.SVGGraphics2D;
+import org.jfree.graphics2d.svg.SVGHints;
 import org.jibble.epsgraphics.EpsGraphics2D;
 
 public class ImageMaker
@@ -219,11 +221,39 @@ public class ImageMaker
     Graphics2D ig2 = (Graphics2D) graphics;
     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
             RenderingHints.VALUE_ANTIALIAS_ON);
+
   }
 
   void setupSVG(int width, int height, String title)
   {
+
     g2 = new SVGGraphics2D(width, height);
+    Graphics2D ig2 = g2;
+
+    String renderStyle = jalview.bin.Cache.getDefault("SVG_RENDERING",
+            "Prompt each time");
+
+    // If we need to prompt, and if the GUI is visible then
+    // Prompt for EPS rendering style
+    if (renderStyle.equalsIgnoreCase("Prompt each time")
+            && !(System.getProperty("java.awt.headless") != null && System
+                    .getProperty("java.awt.headless").equals("true")))
+    {
+      SVGOptions svgOption = new SVGOptions();
+      renderStyle = svgOption.getValue();
+
+      if (renderStyle == null || svgOption.cancelled)
+      {
+        return;
+      }
+    }
+
+    if (renderStyle.equalsIgnoreCase("lineart"))
+    {
+      ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
+              SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
+    }
+
     graphics = g2;
   }
 
index 0fa4a3c..1b42faf 100644 (file)
@@ -20,7 +20,6 @@
  */
 package jalview.viewmodel;
 
-import jalview.analysis.AAFrequency;
 import jalview.analysis.Conservation;
 import jalview.api.AlignCalcManagerI;
 import jalview.api.AlignViewportI;
@@ -35,7 +34,6 @@ import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.Blosum62ColourScheme;
-import jalview.schemes.ClustalxColourScheme;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.PIDColourScheme;
 import jalview.schemes.ResidueProperties;
@@ -447,7 +445,9 @@ public abstract class AlignmentViewport implements AlignViewportI
           AlignmentAnnotation alignmentAnnotation)
   {
     if (!alignmentAnnotation.autoCalculated)
+    {
       return false;
+    }
     if (calculator.workingInvolvedWith(alignmentAnnotation))
     {
       // System.err.println("grey out ("+alignmentAnnotation.label+")");
@@ -899,11 +899,12 @@ public abstract class AlignmentViewport implements AlignViewportI
         selectionGroup = new SequenceGroup();
         selectionGroup.setEndRes(alignment.getWidth() - 1);
       }
-      Vector tmp = alignment.getHiddenSequences().showAll(
+      List<SequenceI> tmp = alignment.getHiddenSequences().showAll(
               hiddenRepSequences);
-      for (int t = 0; t < tmp.size(); t++)
+      for (SequenceI seq : tmp)
       {
-        selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
+        selectionGroup.addSequence(seq, false);
+        setSequenceAnnotationsVisible(seq, true);
       }
 
       hasHiddenRows = false;
@@ -918,7 +919,8 @@ public abstract class AlignmentViewport implements AlignViewportI
 
   public void showSequence(int index)
   {
-    Vector tmp = alignment.getHiddenSequences().showSequence(index,
+    List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(
+            index,
             hiddenRepSequences);
     if (tmp.size() > 0)
     {
@@ -928,9 +930,10 @@ public abstract class AlignmentViewport implements AlignViewportI
         selectionGroup.setEndRes(alignment.getWidth() - 1);
       }
 
-      for (int t = 0; t < tmp.size(); t++)
+      for (SequenceI seq : tmp)
       {
-        selectionGroup.addSequence((SequenceI) tmp.elementAt(t), false);
+        selectionGroup.addSequence(seq, false);
+        setSequenceAnnotationsVisible(seq, true);
       }
       // JBPNote: refactor: only update flag if we modified visiblity (used to
       // do this regardless)
@@ -964,12 +967,30 @@ public abstract class AlignmentViewport implements AlignViewportI
       for (int i = 0; i < seq.length; i++)
       {
         alignment.getHiddenSequences().hideSequence(seq[i]);
+        setSequenceAnnotationsVisible(seq[i], false);
       }
       hasHiddenRows = true;
       firePropertyChange("alignment", null, alignment.getSequences());
     }
   }
 
+  /**
+   * Set visibility for any annotations for the given sequence.
+   * 
+   * @param sequenceI
+   */
+  protected void setSequenceAnnotationsVisible(SequenceI sequenceI,
+          boolean visible)
+  {
+    for (AlignmentAnnotation ann : alignment.getAlignmentAnnotation())
+    {
+      if (ann.sequenceRef == sequenceI)
+      {
+        ann.visible = visible;
+      }
+    }
+  }
+
   public void hideRepSequences(SequenceI repSequence, SequenceGroup sg)
   {
     int sSize = sg.getSize();
index 85969fc..4e95b14 100644 (file)
  */
 package jalview.ws.jws1;
 
-import java.util.*;
-
-import jalview.analysis.*;
-import jalview.bin.*;
-import jalview.datamodel.*;
-import jalview.gui.*;
-import jalview.io.*;
-import jalview.util.*;
+import jalview.analysis.AlignSeq;
+import jalview.bin.Cache;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.WebserviceInfo;
+import jalview.io.FormatAdapter;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
 import jalview.ws.AWsJob;
 import jalview.ws.JobStateSummary;
 import jalview.ws.WSClientI;
+
+import java.util.Hashtable;
+import java.util.List;
+
 import vamsas.objects.simple.JpredResult;
 
 class JPredThread extends JWS1Thread implements WSClientI
@@ -138,14 +147,21 @@ class JPredThread extends JWS1Thread implements WSClientI
               sqs[i] = al.getSequenceAt(i);
             }
             if (!jalview.analysis.SeqsetUtils.deuniquify(
-                    (Hashtable) SequenceInfo, sqs))
+                    SequenceInfo, sqs))
             {
               throw (new Exception(MessageManager.getString("exception.couldnt_recover_sequence_properties_for_alignment")));
             }
           }
           FirstSeq = 0;
-          al.setDataset(null);
+          if (currentView.getDataset() != null)
+          {
+            al.setDataset(currentView.getDataset());
 
+          }
+          else
+          {
+            al.setDataset(null);
+          }
           jalview.io.JnetAnnotationMaker.add_annotation(prediction, al,
                   FirstSeq, false, predMap);
 
@@ -162,8 +178,8 @@ class JPredThread extends JWS1Thread implements WSClientI
         if (predMap != null)
         {
           char gc = getGapChar();
-          SequenceI[] sqs = (SequenceI[]) ((java.lang.Object[]) input
-                  .getAlignmentAndColumnSelection(gc))[0];
+          SequenceI[] sqs = (SequenceI[]) input
+                  .getAlignmentAndColumnSelection(gc)[0];
           if (this.msaIndex >= sqs.length)
           {
             throw new Error(MessageManager.getString("error.implementation_error_invalid_msa_index_for_job"));
@@ -187,7 +203,15 @@ class JPredThread extends JWS1Thread implements WSClientI
         }
         else
         {
-          al.setDataset(null);
+          if (currentView.getDataset() != null)
+          {
+            al.setDataset(currentView.getDataset());
+
+          }
+          else
+          {
+            al.setDataset(null);
+          }
           jalview.io.JnetAnnotationMaker.add_annotation(prediction, al,
                   FirstSeq, true, predMap);
           SequenceI profileseq = al.getSequenceAt(0); // this includes any gaps.
@@ -201,11 +225,53 @@ class JPredThread extends JWS1Thread implements WSClientI
           }
         }
       }
+      // transfer to dataset
+      for (AlignmentAnnotation alant : al.getAlignmentAnnotation())
+      {
+        if (alant.sequenceRef != null)
+        {
+          replaceAnnotationOnAlignmentWith(alant, alant.label,
+                  "jalview.jws1.Jpred" + (this.msa == null ? "" : "MSA"),
+                  alant.sequenceRef);
+        }
+      }
       return new Object[]
       { al, alcsel }; // , FirstSeq, noMsa};
     }
 
     /**
+     * copied from JabawsCalcWorker
+     * 
+     * @param newAnnot
+     * @param typeName
+     * @param calcId
+     * @param aSeq
+     */
+    protected void replaceAnnotationOnAlignmentWith(
+            AlignmentAnnotation newAnnot, String typeName, String calcId,
+            SequenceI aSeq)
+    {
+      SequenceI dsseq = aSeq.getDatasetSequence();
+      while (dsseq.getDatasetSequence() != null)
+      {
+        dsseq = dsseq.getDatasetSequence();
+      }
+      // look for same annotation on dataset and lift this one over
+      List<AlignmentAnnotation> dsan = dsseq.getAlignmentAnnotations(
+              calcId, typeName);
+      if (dsan != null && dsan.size() > 0)
+      {
+        for (AlignmentAnnotation dssan : dsan)
+        {
+          dsseq.removeAlignmentAnnotation(dssan);
+        }
+      }
+      AlignmentAnnotation dssan = new AlignmentAnnotation(newAnnot);
+      dsseq.addAlignmentAnnotation(dssan);
+      dssan.adjustForAlignment();
+    }
+
+    /**
      * Given an alignment where all other sequences except profileseq are
      * aligned to the ungapped profileseq, insert gaps in the other sequences to
      * realign them with the residues in profileseq
@@ -372,7 +438,7 @@ class JPredThread extends JWS1Thread implements WSClientI
       {
         if (job.getJobId().startsWith("Broken"))
         {
-          job.result = (vamsas.objects.simple.Result) new JpredResult();
+          job.result = new JpredResult();
           job.result.setInvalid(true);
           job.result.setStatus(MessageManager.formatMessage("label.submission_params", new String[]{job.getJobId().toString()}));
           throw new Exception(job.getJobId());
index 83eebdf..6c438be 100644 (file)
@@ -279,10 +279,13 @@ public class AADisorderClient extends JabawsCalcWorker implements
               {
                 continue;
               }
+              String typename, calcName;
               AlignmentAnnotation annot = createAnnotationRowsForScores(
                       ourAnnot,
-                      service.serviceType + " (" + scr.getMethod() + ")",
-                      service.getServiceTypeURI() + "/" + scr.getMethod(),
+                      typename = service.serviceType + " ("
+                              + scr.getMethod() + ")",
+                      calcName = service.getServiceTypeURI() + "/"
+                              + scr.getMethod(),
                       aseq, base + 1, scr);
               annot.graph = AlignmentAnnotation.LINE_GRAPH;
 
@@ -333,6 +336,9 @@ public class AADisorderClient extends JabawsCalcWorker implements
                 }
               }
               annot._linecolour = col;
+              // finally, update any dataset annotation
+              replaceAnnotationOnAlignmentWith(annot, typename, calcName,
+                      aseq);
             }
           }
         }
index a08a233..74dce4d 100644 (file)
@@ -27,6 +27,9 @@ import jalview.bin.Cache;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.jws2.jabaws2.Jws2InstanceFactory;
 
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -44,7 +47,7 @@ public class JabaWsServerQuery implements Runnable
 
   Jws2Discoverer jws2Discoverer = null;
 
-  String jwsservers = null;
+  String jwsserver = null;
 
   boolean quit = false, running = false;
 
@@ -65,10 +68,10 @@ public class JabaWsServerQuery implements Runnable
     this.quit = quit;
   }
 
-  public JabaWsServerQuery(Jws2Discoverer jws2Discoverer, String jwsservers)
+  public JabaWsServerQuery(Jws2Discoverer jws2Discoverer, String server)
   {
     this.jws2Discoverer = jws2Discoverer;
-    this.jwsservers = jwsservers;
+    this.jwsserver = server;
   }
 
   Services[] JABAWS1SERVERS = new Services[]
@@ -92,7 +95,9 @@ public class JabaWsServerQuery implements Runnable
     running = true;
     try
     {
-      if (Jws2Client.validURL(jwsservers))
+      // TODO this test doesn't seem to attempt a connection - should it?
+      // would save a lot of failed tries with UnknownHostException
+      if (isValidUrl(jwsserver))
       {
         compbio.data.msa.RegistryWS registry = null;
         Set svccategories = null;
@@ -109,7 +114,7 @@ public class JabaWsServerQuery implements Runnable
         try
         {
           // JBPNote: why is RegistryWS in compbio.data.msa ?
-          registry = Jws2Client.connectToRegistry(jwsservers);
+          registry = Jws2Client.connectToRegistry(jwsserver);
           if (registry != null)
           {
             // System.err.println("Test Services Output\n"
@@ -137,7 +142,7 @@ public class JabaWsServerQuery implements Runnable
           ex.printStackTrace();
           // if that failed, then we are probably working with a JABAWS1 server.
           // in that case, look for each service endpoint
-          System.err.println("JWS2 Discoverer: " + jwsservers
+          System.err.println("JWS2 Discoverer: " + jwsserver
                   + " is a JABAWS1 server. Using hardwired list.");
           for (Services srv : JABAWS1SERVERS)
           {
@@ -161,18 +166,18 @@ public class JabaWsServerQuery implements Runnable
             JABAService service = null;
             try
             {
-              service = Jws2Client.connect(jwsservers, srv);
+              service = Jws2Client.connect(jwsserver, srv);
             } catch (Exception e)
             {
               System.err.println("Jws2 Discoverer: Problem on "
-                      + jwsservers + " with service " + srv + ":\n"
+                      + jwsserver + " with service " + srv + ":\n"
                       + e.getMessage());
               if (!(e instanceof javax.xml.ws.WebServiceException))
               {
                 e.printStackTrace();
               }
               // For moment, report service as a problem.
-              jws2Discoverer.addInvalidServiceUrl(jwsservers);
+              jws2Discoverer.addInvalidServiceUrl(jwsserver);
             }
             ;
             if (service != null)
@@ -184,16 +189,16 @@ public class JabaWsServerQuery implements Runnable
 
                 String description = registry.getServiceDescription(srv);
 
-                svc = Jws2InstanceFactory.newJws2Instance(jwsservers,
+                svc = Jws2InstanceFactory.newJws2Instance(jwsserver,
                         srv.toString(), cat.name, description, service);
               }
               if (svc == null)
               {
-                svc = Jws2InstanceFactory.newJws2Instance(jwsservers,
+                svc = Jws2InstanceFactory.newJws2Instance(jwsserver,
                         srv.toString(), cat.name,
                         "JABAWS 1 Alignment Service", service);
               }
-              jws2Discoverer.addService(jwsservers, svc);
+              jws2Discoverer.addService(jwsserver, svc);
             }
 
           }
@@ -201,25 +206,53 @@ public class JabaWsServerQuery implements Runnable
 
         if (noservices)
         {
-          jws2Discoverer.addUrlwithnoservices(jwsservers);
+          jws2Discoverer.addUrlwithnoservices(jwsserver);
         }
       }
       else
       {
-        jws2Discoverer.addInvalidServiceUrl(jwsservers);
-        Cache.log.info("Ignoring invalid Jws2 service url " + jwsservers);
+        jws2Discoverer.addInvalidServiceUrl(jwsserver);
+        Cache.log.info("Ignoring invalid Jws2 service url " + jwsserver);
       }
     } catch (Exception e)
     {
       e.printStackTrace();
       Cache.log.warn("Exception when discovering Jws2 services.", e);
-      jws2Discoverer.addInvalidServiceUrl(jwsservers);
+      jws2Discoverer.addInvalidServiceUrl(jwsserver);
     } catch (Error e)
     {
       Cache.log.error("Exception when discovering Jws2 services.", e);
-      jws2Discoverer.addInvalidServiceUrl(jwsservers);
+      jws2Discoverer.addInvalidServiceUrl(jwsserver);
     }
     running = false;
   }
 
+  /**
+   * Check if the URL is valid and responding.
+   * 
+   * @return
+   */
+  private boolean isValidUrl(String server)
+  {
+    // return Jws2Client.validURL(jwsserver); // checks syntax only
+    boolean result = false;
+    if (server != null) {
+      try {
+        URL url = new URL(server);
+        url.openStream().close();
+        result = true;
+      } catch (MalformedURLException e)
+      {
+        System.err.println("Invalid server URL: " + server);
+        result = false;
+      } catch (IOException e)
+      {
+        System.err.println("Error connecting to server: " + server + ": "
+                + e.toString());
+        result = false;
+      }
+    }
+    return result;
+  }
+
 }
index e966886..e01c648 100644 (file)
@@ -158,6 +158,30 @@ public abstract class JabawsCalcWorker extends AbstractJabaCalcWorker
     return annotation;
   }
 
+  protected void replaceAnnotationOnAlignmentWith(
+          AlignmentAnnotation newAnnot, String typeName, String calcId,
+          SequenceI aSeq)
+  {
+    SequenceI dsseq = aSeq.getDatasetSequence();
+    while (dsseq.getDatasetSequence() != null)
+    {
+      dsseq = dsseq.getDatasetSequence();
+    }
+    // look for same annotation on dataset and lift this one over
+    List<AlignmentAnnotation> dsan = dsseq.getAlignmentAnnotations(calcId,
+            typeName);
+    if (dsan != null && dsan.size() > 0)
+    {
+      for (AlignmentAnnotation dssan : dsan)
+      {
+        dsseq.removeAlignmentAnnotation(dssan);
+      }
+    }
+    AlignmentAnnotation dssan = new AlignmentAnnotation(newAnnot);
+    dsseq.addAlignmentAnnotation(dssan);
+    dssan.adjustForAlignment();
+  }
+
   private void constructAnnotationFromScore(AlignmentAnnotation annotation,
           int base, int alWidth, Score scr)
   {
index 910b749..a111d68 100644 (file)
@@ -34,6 +34,8 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -60,9 +62,48 @@ import compbio.ws.client.Services;
  */
 public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
 {
-  private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
+  public static final String COMPBIO_JABAWS = "http://www.compbio.dundee.ac.uk/jabaws";
+
+  /*
+   * the .jalview_properties entry for JWS2 URLS
+   */
+  final static String JWS2HOSTURLS = "JWS2HOSTURLS";
+
+  /*
+   * Singleton instance
+   */
+  private static Jws2Discoverer discoverer;
+
+  /*
+   * Override for testing only
+   */
+  private static List<String> testUrls = null;
+
+  // preferred url has precedence over others
+  private String preferredUrl;
+
+  private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
           this);
 
+  Vector<String> invalidServiceUrls = null, urlsWithoutServices = null,
+          validServiceUrls = null;
+
+  boolean running = false, aborted = false;
+
+  Thread oldthread = null;
+
+  /**
+   * holds list of services.
+   */
+  protected Vector<Jws2Instance> services;
+
+  /**
+   * Private constructor enforces use of singleton via getDiscoverer()
+   */
+  private Jws2Discoverer()
+  {
+  }
+
   /**
    * change listeners are notified of "services" property changes
    * 
@@ -87,8 +128,6 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     changeSupport.removePropertyChangeListener(listener);
   }
 
-  boolean running = false, aborted = false;
-
   /**
    * @return the aborted
    */
@@ -104,10 +143,8 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   public void setAborted(boolean aborted)
   {
     this.aborted = aborted;
-  }
-
-  Thread oldthread = null;
 
+  }
   public void run()
   {
 
@@ -135,7 +172,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
 
     // first set up exclusion list if needed
     final Set<String> ignoredServices = new HashSet<String>();
-    for (String ignored : jalview.bin.Cache.getDefault(
+    for (String ignored : Cache.getDefault(
             "IGNORED_JABAWS_SERVICETYPES", "")
             .split("\\|"))
     {
@@ -176,9 +213,9 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     ArrayList<String> svctypes = new ArrayList<String>();
 
     List<JabaWsServerQuery> qrys = new ArrayList<JabaWsServerQuery>();
-    for (final String jwsservers : getServiceUrls())
+    for (final String jwsserver : getServiceUrls())
     {
-      JabaWsServerQuery squery = new JabaWsServerQuery(this, jwsservers);
+      JabaWsServerQuery squery = new JabaWsServerQuery(this, jwsserver);
       if (svctypes.size() == 0)
       {
         // TODO: remove this ugly hack to get Canonical JABA service ordering
@@ -233,7 +270,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
         Jws2Instance[] svcs = new Jws2Instance[services.size()];
         int[] spos = new int[services.size()];
         int ipos = 0;
-        Vector svcUrls = getServiceUrls();
+        List<String> svcUrls = getServiceUrls();
         for (Jws2Instance svc : services)
         {
           svcs[ipos] = svc;
@@ -290,11 +327,6 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   }
 
   /**
-   * holds list of services.
-   */
-  protected Vector<Jws2Instance> services;
-
-  /**
    * attach all available web services to the appropriate submenu in the given
    * JMenu
    */
@@ -545,7 +577,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   {
     if (args.length > 0)
     {
-      testUrls = new Vector<String>();
+      testUrls = new ArrayList<String>();
       for (String url : args)
       {
         testUrls.add(url);
@@ -592,8 +624,11 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     }
   }
 
-  private static Jws2Discoverer discoverer;
-
+  /**
+   * Returns the singleton instance of this class.
+   * 
+   * @return
+   */
   public static Jws2Discoverer getDiscoverer()
   {
     if (discoverer == null)
@@ -605,7 +640,6 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
 
   public boolean hasServices()
   {
-    // TODO Auto-generated method stub
     return !running && services != null && services.size() > 0;
   }
 
@@ -614,24 +648,19 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     return running;
   }
 
-  /**
-   * the jalview .properties entry for JWS2 URLS
-   */
-  final static String JWS2HOSTURLS = "JWS2HOSTURLS";
-
-  public static void setServiceUrls(Vector<String> urls)
+  public void setServiceUrls(List<String> wsUrls)
   {
-    if (urls != null)
+    if (wsUrls != null && !wsUrls.isEmpty())
     {
-      StringBuffer urlbuffer = new StringBuffer();
+      StringBuilder urls = new StringBuilder(128);
       String sep = "";
-      for (String url : urls)
+      for (String url : wsUrls)
       {
-        urlbuffer.append(sep);
-        urlbuffer.append(url);
+        urls.append(sep);
+        urls.append(url);
         sep = ",";
       }
-      Cache.setProperty(JWS2HOSTURLS, urlbuffer.toString());
+      Cache.setProperty(JWS2HOSTURLS, urls.toString());
     }
     else
     {
@@ -639,18 +668,27 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     }
   }
 
-  private static Vector<String> testUrls = null;
-
-  public static Vector<String> getServiceUrls()
+  /**
+   * Returns web service URLs, in the order in which they should be tried (or an
+   * empty list).
+   * 
+   * @return
+   */
+  public List<String> getServiceUrls()
   {
     if (testUrls != null)
     {
       // return test urls, if there are any, instead of touching cache
       return testUrls;
     }
-    String surls = Cache.getDefault(JWS2HOSTURLS,
-            "http://www.compbio.dundee.ac.uk/jabaws");
-    Vector<String> urls = new Vector<String>();
+    List<String> urls = new ArrayList<String>();
+
+    if (this.preferredUrl != null)
+    {
+      urls.add(preferredUrl);
+    }
+
+    String surls = Cache.getDefault(JWS2HOSTURLS, COMPBIO_JABAWS);
     try
     {
       StringTokenizer st = new StringTokenizer(surls, ",");
@@ -659,40 +697,37 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
         String url = null;
         try
         {
-          java.net.URL u = new java.net.URL(url = st.nextToken());
+          url = st.nextToken();
+          new URL(url);
           if (!urls.contains(url))
           {
             urls.add(url);
           }
           else
           {
-            jalview.bin.Cache.log.info("Ignoring duplicate url in "
+            Cache.log.info("Ignoring duplicate url " + url + " in "
                     + JWS2HOSTURLS + " list");
           }
-        } catch (Exception ex)
+        } catch (MalformedURLException ex)
         {
-          jalview.bin.Cache.log
+          Cache.log
                   .warn("Problem whilst trying to make a URL from '"
                           + ((url != null) ? url : "<null>") + "'");
-          jalview.bin.Cache.log
+          Cache.log
                   .warn("This was probably due to a malformed comma separated list"
                           + " in the "
                           + JWS2HOSTURLS
                           + " entry of $(HOME)/.jalview_properties)");
-          jalview.bin.Cache.log.debug("Exception was ", ex);
+          Cache.log.debug("Exception was ", ex);
         }
       }
     } catch (Exception ex)
     {
-      jalview.bin.Cache.log.warn(
+      Cache.log.warn(
               "Error parsing comma separated list of urls in "
                       + JWS2HOSTURLS + " preference.", ex);
     }
-    if (urls.size() >= 0)
-    {
-      return urls;
-    }
-    return null;
+    return urls;
   }
 
   public Vector<Jws2Instance> getServices()
@@ -750,9 +785,6 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
     return thr;
   }
 
-  Vector<String> invalidServiceUrls = null, urlsWithoutServices = null,
-          validServiceUrls = null;
-
   /**
    * @return the invalidServiceUrls
    */
@@ -865,7 +897,9 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
       return 1;
     }
     if (urlsWithoutServices != null && urlsWithoutServices.contains(url))
+    {
       return 0;
+    }
     if (invalidServiceUrls != null && invalidServiceUrls.contains(url))
     {
       return -1;
@@ -979,4 +1013,21 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
   {
     setPreferredServiceFor(null, serviceType, serviceAction, selectedServer);
   }
+
+  /**
+   * Set a URL to try before any others. For use with command-line parameter to
+   * configure a local Jabaws installation without the need to add to property
+   * files.
+   * 
+   * @param value
+   * @throws MalformedURLException
+   */
+  public void setPreferredUrl(String value) throws MalformedURLException
+  {
+    if (value != null && value.trim().length() > 0)
+    {
+      new URL(value);
+      preferredUrl = value;
+    }
+  }
 }
index 9ddc69a..09a6d8d 100644 (file)
  */
 package jalview.ws.jws2;
 
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentView;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
+import jalview.gui.JvSwingUtils;
+import jalview.util.MessageManager;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.WsParamSetI;
+
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 import java.util.List;
 
-import javax.swing.*;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.ToolTipManager;
 
-import jalview.datamodel.*;
-import jalview.gui.*;
 import compbio.data.msa.MsaWS;
 import compbio.metadata.Argument;
-import jalview.util.MessageManager;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
-import jalview.ws.params.WsParamSetI;
 
 /**
  * DOCUMENT ME!
@@ -98,20 +107,23 @@ public class MsaWSClient extends Jws2Client
     if (!(sh.service instanceof MsaWS))
     {
       // redundant at mo - but may change
-      JOptionPane
-              .showMessageDialog(
-                      Desktop.desktop,
-                      MessageManager.formatMessage("label.service_called_is_not_msa_service", new String[]{sh.serviceType}),
-                      MessageManager.getString("label.internal_jalview_error"), JOptionPane.WARNING_MESSAGE);
+      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+              .formatMessage("label.service_called_is_not_msa_service",
+                      new String[]
+                      { sh.serviceType }), MessageManager
+              .getString("label.internal_jalview_error"),
+              JOptionPane.WARNING_MESSAGE);
 
       return;
     }
     server = (MsaWS) sh.service;
     if ((wsInfo = setWebService(sh, false)) == null)
     {
-      JOptionPane.showMessageDialog(Desktop.desktop,
-                 MessageManager.formatMessage("label.msa_service_is_unknown", new String[]{sh.serviceType}),
-                 MessageManager.getString("label.internal_jalview_error"), JOptionPane.WARNING_MESSAGE);
+      JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+              .formatMessage("label.msa_service_is_unknown", new String[]
+              { sh.serviceType }), MessageManager
+              .getString("label.internal_jalview_error"),
+              JOptionPane.WARNING_MESSAGE);
 
       return;
     }
@@ -273,13 +285,39 @@ public class MsaWSClient extends Jws2Client
                   "label.run_with_preset_params", new String[]
                   { calcName }));
 
+          final int showToolTipFor = ToolTipManager.sharedInstance()
+                  .getDismissDelay();
           for (final WsParamSetI preset : presets)
           {
             final JMenuItem methodR = new JMenuItem(preset.getName());
-            methodR.setToolTipText(JvSwingUtils.wrapTooltip(true, "<p><strong>"
-                            + (preset.isModifiable() ? MessageManager.getString("label.user_preset")
-                                    : MessageManager.getString("label.service_preset")) + "</strong><br/>"
-                            + preset.getDescription() + "</p>"));
+            final int QUICK_TOOLTIP = 1500;
+            // JAL-1582 shorten tooltip display time in these menu items as
+            // they can obscure other options
+            methodR.addMouseListener(new MouseAdapter()
+            {
+              @Override
+              public void mouseEntered(MouseEvent e)
+              {
+                ToolTipManager.sharedInstance().setDismissDelay(
+                        QUICK_TOOLTIP);
+              }
+
+              @Override
+              public void mouseExited(MouseEvent e)
+              {
+                ToolTipManager.sharedInstance().setDismissDelay(showToolTipFor);
+              }
+
+            });
+            methodR.setToolTipText(JvSwingUtils.wrapTooltip(
+                    true,
+                    "<p><strong>"
+                            + (preset.isModifiable() ? MessageManager
+                                    .getString("label.user_preset")
+                                    : MessageManager
+                                            .getString("label.service_preset"))
+                            + "</strong><br/>" + preset.getDescription()
+                            + "</p>"));
             methodR.addActionListener(new ActionListener()
             {
               public void actionPerformed(ActionEvent e)
diff --git a/test/jalview/commands/EditCommandTest.java b/test/jalview/commands/EditCommandTest.java
new file mode 100644 (file)
index 0000000..fc821b9
--- /dev/null
@@ -0,0 +1,232 @@
+package jalview.commands;
+
+import static org.junit.Assert.assertEquals;
+import jalview.commands.EditCommand.Action;
+import jalview.commands.EditCommand.Edit;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Unit tests for EditCommand
+ * 
+ * @author gmcarstairs
+ *
+ */
+public class EditCommandTest
+{
+
+  private EditCommand testee;
+
+  private SequenceI[] seqs;
+
+  private Alignment al;
+
+  @Before
+  public void setUp()
+  {
+    testee = new EditCommand();
+    seqs = new SequenceI[4];
+    seqs[0] = new Sequence("seq0", "abcdefghjk");
+    seqs[1] = new Sequence("seq1", "fghjklmnopq");
+    seqs[2] = new Sequence("seq2", "qrstuvwxyz");
+    seqs[3] = new Sequence("seq3", "1234567890");
+    al = new Alignment(seqs);
+    al.setGapCharacter('?');
+  }
+
+  /**
+   * Test inserting gap characters
+   */
+  @Test
+  public void testAppendEdit_insertGap()
+  {
+    // set a non-standard gap character to prove it is actually used
+    testee.appendEdit(Action.INSERT_GAP, seqs, 4, 3, al, true);
+    assertEquals("abcd???efghjk", seqs[0].getSequenceAsString());
+    assertEquals("fghj???klmnopq", seqs[1].getSequenceAsString());
+    assertEquals("qrst???uvwxyz", seqs[2].getSequenceAsString());
+    assertEquals("1234???567890", seqs[3].getSequenceAsString());
+
+    // todo: test for handling out of range positions?
+  }
+
+  /**
+   * Test deleting characters from sequences. Note the deleteGap() action does
+   * not check that only gap characters are being removed.
+   */
+  @Test
+  public void testAppendEdit_deleteGap()
+  {
+    testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
+    assertEquals("abcdhjk", seqs[0].getSequenceAsString());
+    assertEquals("fghjnopq", seqs[1].getSequenceAsString());
+    assertEquals("qrstxyz", seqs[2].getSequenceAsString());
+    assertEquals("1234890", seqs[3].getSequenceAsString());
+  }
+
+  /**
+   * Test a cut action. The command should store the cut characters to support
+   * undo.
+   */
+  @Test
+  public void testCut()
+  {
+    Edit ec = testee.new Edit(Action.CUT, seqs, 4, 3, al);
+    testee.cut(ec, new AlignmentI[]
+    { al });
+    assertEquals("abcdhjk", seqs[0].getSequenceAsString());
+    assertEquals("fghjnopq", seqs[1].getSequenceAsString());
+    assertEquals("qrstxyz", seqs[2].getSequenceAsString());
+    assertEquals("1234890", seqs[3].getSequenceAsString());
+
+    assertEquals("efg", new String(ec.string[0]));
+    assertEquals("klm", new String(ec.string[1]));
+    assertEquals("uvw", new String(ec.string[2]));
+    assertEquals("567", new String(ec.string[3]));
+    // TODO: case where whole sequence is deleted as nothing left; etc
+  }
+
+  /**
+   * Test a Paste action, where this adds sequences to an alignment.
+   */
+  @Test
+  @Ignore
+  // TODO fix so it works
+  public void testPaste_addToAlignment()
+  {
+    SequenceI[] newSeqs = new SequenceI[2];
+    newSeqs[0] = new Sequence("newseq0", "ACEFKL");
+    newSeqs[1] = new Sequence("newseq1", "JWMPDH");
+
+    Edit ec = testee.new Edit(Action.PASTE, newSeqs, 0, al.getWidth(), al);
+    testee.paste(ec, new AlignmentI[]
+    { al });
+    assertEquals(6, al.getSequences().size());
+    assertEquals("1234567890", seqs[3].getSequenceAsString());
+    assertEquals("ACEFKL", seqs[4].getSequenceAsString());
+    assertEquals("JWMPDH", seqs[5].getSequenceAsString());
+  }
+
+  /**
+   * Test insertGap followed by undo command
+   */
+  @Test
+  public void testUndo_insertGap()
+  {
+    // Edit ec = testee.new Edit(Action.INSERT_GAP, seqs, 4, 3, '?');
+    testee.appendEdit(Action.INSERT_GAP, seqs, 4, 3, al, true);
+    // check something changed
+    assertEquals("abcd???efghjk", seqs[0].getSequenceAsString());
+    testee.undoCommand(new AlignmentI[]
+    { al });
+    assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
+    assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
+    assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
+    assertEquals("1234567890", seqs[3].getSequenceAsString());
+  }
+
+  /**
+   * Test deleteGap followed by undo command
+   */
+  @Test
+  public void testUndo_deleteGap()
+  {
+    testee.appendEdit(Action.DELETE_GAP, seqs, 4, 3, al, true);
+    // check something changed
+    assertEquals("abcdhjk", seqs[0].getSequenceAsString());
+    testee.undoCommand(new AlignmentI[]
+    { al });
+    // deleteGap doesn't 'remember' deleted characters, only gaps get put back
+    assertEquals("abcd???hjk", seqs[0].getSequenceAsString());
+    assertEquals("fghj???nopq", seqs[1].getSequenceAsString());
+    assertEquals("qrst???xyz", seqs[2].getSequenceAsString());
+    assertEquals("1234???890", seqs[3].getSequenceAsString());
+  }
+
+  /**
+   * Test several commands followed by an undo command
+   */
+  @Test
+  public void testUndo_multipleCommands()
+  {
+    // delete positions 3/4/5 (counting from 1)
+    testee.appendEdit(Action.DELETE_GAP, seqs, 2, 3, al, true);
+    assertEquals("abfghjk", seqs[0].getSequenceAsString());
+    assertEquals("1267890", seqs[3].getSequenceAsString());
+
+    // insert 2 gaps after the second residue
+    testee.appendEdit(Action.INSERT_GAP, seqs, 2, 2, al, true);
+    assertEquals("ab??fghjk", seqs[0].getSequenceAsString());
+    assertEquals("12??67890", seqs[3].getSequenceAsString());
+
+    // delete positions 4/5/6
+    testee.appendEdit(Action.DELETE_GAP, seqs, 3, 3, al, true);
+    assertEquals("ab?hjk", seqs[0].getSequenceAsString());
+    assertEquals("12?890", seqs[3].getSequenceAsString());
+
+    // undo edit commands
+    testee.undoCommand(new AlignmentI[]
+    { al });
+    assertEquals("ab?????hjk", seqs[0].getSequenceAsString());
+    assertEquals("12?????890", seqs[3].getSequenceAsString());
+  }
+
+  /**
+   * Unit test for JAL-1594 bug: click and drag sequence right to insert gaps -
+   * undo did not remove them all.
+   */
+  @Test
+  public void testUndo_multipleInsertGaps()
+  {
+    testee.appendEdit(Action.INSERT_GAP, seqs, 4, 1, al, true);
+    testee.appendEdit(Action.INSERT_GAP, seqs, 5, 1, al, true);
+    testee.appendEdit(Action.INSERT_GAP, seqs, 6, 1, al, true);
+
+    // undo edit commands
+    testee.undoCommand(new AlignmentI[]
+    { al });
+    assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
+    assertEquals("1234567890", seqs[3].getSequenceAsString());
+
+  }
+
+  /**
+   * Test cut followed by undo command
+   */
+  @Test
+  public void testUndo_cut()
+  {
+    testee.appendEdit(Action.CUT, seqs, 4, 3, al, true);
+    // check something changed
+    assertEquals("abcdhjk", seqs[0].getSequenceAsString());
+    testee.undoCommand(new AlignmentI[]
+    { al });
+    assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
+    assertEquals("fghjklmnopq", seqs[1].getSequenceAsString());
+    assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
+    assertEquals("1234567890", seqs[3].getSequenceAsString());
+  }
+
+  /**
+   * Test the replace command (used to manually edit a sequence)
+   */
+  @Test
+  public void testReplace()
+  {
+    // seem to need a dataset sequence on the edited sequence here
+    seqs[1].setDatasetSequence(seqs[1]);
+    new EditCommand("", Action.REPLACE, "ZXY", new SequenceI[]
+    { seqs[1] }, 4, 8, al);
+    assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
+    assertEquals("qrstuvwxyz", seqs[2].getSequenceAsString());
+    assertEquals("1234567890", seqs[3].getSequenceAsString());
+    seqs[1] = new Sequence("seq1", "fghjZXYnopq");
+
+  }
+}
index 79e3eae..7bcf902 100644 (file)
@@ -64,7 +64,7 @@ public class PDBFileWithJmolTest
   {
     for (String pdbStr : testFile)
     {
-      PDBfile mctest = new PDBfile(false, false, pdbStr,
+      PDBfile mctest = new PDBfile(false, false, false, pdbStr,
               AppletFormatAdapter.FILE);
       PDBFileWithJmol jtest = new PDBFileWithJmol(pdbStr,
               jalview.io.AppletFormatAdapter.FILE);
index d2322ef..a7c439f 100644 (file)
 package jalview.ext.paradise;
 
 import static org.junit.Assert.assertTrue;
-
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
-import jalview.ext.paradise.Annotate3D;
 import jalview.io.FastaFile;
 import jalview.io.FormatAdapter;
 
@@ -72,9 +70,13 @@ public class TestAnnotate3D
         iline = id.readLine();
         fline = file.readLine();
         if (iline != null)
+        {
           System.out.println(iline);
+        }
         if (fline != null)
+        {
           System.out.println(fline);
+        }
         // next assert fails for latest RNAview - because the XMLID entries
         // change between file and ID based RNAML generation.
         assertTrue(
@@ -96,7 +98,8 @@ public class TestAnnotate3D
   @Test
   public void testPDBfileVsRNAML() throws Exception
   {
-    PDBfile pdbf = new PDBfile(true,true,"examples/2GIS.pdb", FormatAdapter.FILE);
+    PDBfile pdbf = new PDBfile(true, false, true, "examples/2GIS.pdb",
+            FormatAdapter.FILE);
     Assert.assertTrue(pdbf.isValid());
     // Comment - should add new FileParse constructor like new FileParse(Reader
     // ..). for direct reading
diff --git a/test/jalview/gui/HelpTest.java b/test/jalview/gui/HelpTest.java
new file mode 100644 (file)
index 0000000..e4068d7
--- /dev/null
@@ -0,0 +1,32 @@
+package jalview.gui;
+
+import static org.junit.Assert.assertTrue;
+import jalview.gui.Help.HelpId;
+
+import java.net.URL;
+
+import javax.help.HelpSet;
+import javax.help.HelpSetException;
+import javax.help.Map;
+
+import org.junit.Test;
+
+public class HelpTest
+{
+  @Test
+  public void checkHelpTargets() throws HelpSetException
+  {
+    ClassLoader cl = Desktop.class.getClassLoader();
+    URL url = HelpSet.findHelpSet(cl, "help/help"); // $NON-NLS-$
+    HelpSet hs = new HelpSet(cl, url);
+    Map targets = hs.getLocalMap();
+
+    for (HelpId id : HelpId.values())
+    {
+      String target = id.toString();
+      assertTrue("Unmatched target enum: " + target,
+              targets.isValidID(target, hs));
+    }
+
+  }
+}
index 5839761..f5b0258 100644 (file)
@@ -20,8 +20,6 @@
  */
 package jalview.io;
 
-import static org.junit.Assert.*;
-
 import java.io.File;
 
 import org.junit.AfterClass;
@@ -45,7 +43,7 @@ public class RNAMLfileTest
   public void testRnamlToStockholmIO()
   {
     StockholmFileTest.testFileIOwithFormat(new File(
-            "examples/rna-alignment.xml"), "STH");
+            "examples/rna-alignment.xml"), "STH", -1, -1);
 
   }
 
index 8fece9d..cf61e6e 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.io;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import jalview.datamodel.Alignment;
@@ -45,7 +46,7 @@ public class StockholmFileTest
   @Test
   public void pfamFileIO() throws Exception
   {
-    testFileIOwithFormat(new File(PfamFile), "STH");
+    testFileIOwithFormat(new File(PfamFile), "STH", -1, 0);
   }
 
   @Test
@@ -70,7 +71,7 @@ public class StockholmFileTest
   @Test
   public void rfamFileIO() throws Exception
   {
-    testFileIOwithFormat(new File(RfamFile), "STH");
+    testFileIOwithFormat(new File(RfamFile), "STH", 2, 1);
   }
 
   /**
@@ -83,7 +84,8 @@ public class StockholmFileTest
    *          - label for IO class used to write and read back in the data from
    *          f
    */
-  public static void testFileIOwithFormat(File f, String ioformat)
+  public static void testFileIOwithFormat(File f, String ioformat,
+          int naliannot, int nminseqann)
   {
     System.out.println("Reading file: " + f);
     String ff = f.getPath();
@@ -118,6 +120,28 @@ public class StockholmFileTest
                       + ioformat + "' writer",
               ioformat.equals(identifyoutput));
       testAlignmentEquivalence(al, al_input);
+      int numaliannot = 0, numsqswithali = 0;
+      for (AlignmentAnnotation ala : al_input.getAlignmentAnnotation())
+      {
+        if (ala.sequenceRef == null)
+        {
+          numaliannot++;
+        }
+        else
+        {
+          numsqswithali++;
+        }
+      }
+      if (naliannot > -1)
+      {
+        assertEquals("Number of alignment annotations", naliannot,
+              numaliannot);
+      }
+
+      assertTrue(
+              "Number of sequence associated annotations wasn't at least "
+                      + nminseqann, numsqswithali >= nminseqann);
+
     } catch (Exception e)
     {
       e.printStackTrace();
index 295c3bf..c206323 100644 (file)
@@ -20,7 +20,8 @@
  */
 package jalview.ws.jabaws;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import jalview.ws.jws2.Jws2Discoverer;
 
 import java.util.Vector;
@@ -73,7 +74,7 @@ public class JalviewJabawsTestUtils
         services.add(url);
       }
       ;
-      Jws2Discoverer.setServiceUrls(services);
+      Jws2Discoverer.getDiscoverer().setServiceUrls(services);
     }
     try
     {