From: Jim Procter Date: Tue, 31 May 2016 15:33:21 +0000 (+0100) Subject: Merge branch 'develop' into features/JAL-2113_emblXml1.2 X-Git-Tag: Release_2_10_0~196^2~2^2 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=18e78fa415a301cf4423037a713b2b088b9fc656;hp=d734217a33aa6bfa39a4ac207592b4696ffdc48d;p=jalview.git Merge branch 'develop' into features/JAL-2113_emblXml1.2 JAL-2113 JAL-1919 mmcif/pdb configurable retrieval from EBI/PDBe - verfied as working --- diff --git a/build.xml b/build.xml index 57cd9d2..a8b8928 100755 --- a/build.xml +++ b/build.xml @@ -27,7 +27,9 @@ - + + + @@ -88,6 +90,9 @@ + + + @@ -374,7 +379,7 @@ - @@ -382,7 +387,7 @@ - + diff --git a/doc/building.html b/doc/building.html index 3a39691..ecde4d8 100755 --- a/doc/building.html +++ b/doc/building.html @@ -26,13 +26,12 @@

You will need the following (hopefully):

    -
  • Java development kit (JDK1.6 is the recommended platform for developing with Jalview, although JDK1.7 seems to work too!).
  • -
  • Ant (we think 1.5.4 is quite sufficient to use the simple build -file supplied, and it seems to work with later versions e.g. 1.7).
  • +
  • Java development kit (JDK1.8 is now the recommended platform for developing with Jalview.
  • +
  • Ant (1.7 or later will be needed for some of the jarsigning tools).
With any luck, after setting your paths and JAVA_HOME correctly, you just need to change to the Jalview directory and run ant (this works -from JBuilder and eclipse too, but NetBeans is a bit trickier). +from eclipse too, but NetBeans is a bit trickier).
    ant
 
@@ -46,23 +45,24 @@ build target in ant to make the signed jar files in a directory called dist. But first you need to make your own key:

Making your own key

-

The ant 'makefulldist' target assumes that a keystore exists in a -directory 'keys'. To make a key accessible using the default settings -in the build.xml file then make the keys directory and add the -jarsigner key with the following : -

-
-mkdir keys
-keytool -genkey -keystore keys/.keystore -keypass alignmentisfun
--storepass alignmentisfun -alias jalview
- (you will have to answer some personal questions here)
-ant makedist
- (should eventually generate a Jalview.jnlp file
-  in ./dist along with a set of signed jars using the jalview
-  key)
-
- -

+

The ant 'makefulldist' target assumes that a keystore exists in + a directory 'keys'. To make a key accessible using the default + settings in the build.xml file then make the keys directory and add + the jarsigner key with the following :

+
mkdir keys
+
keytool -genkey -keystore keys/.keystore -keypass alignmentisfun
+  -storepass alignmentisfun -sigalg SHA1withRSA -keyalg RSA -alias jalview
+ (you will have to answer some personal questions here) +
ant makedist -DWebStartLocation="file://.pathtojalviewsource./dist" -Dapplication.codebase="*"
+

This should eventually generate a jalview.jnlp file in ./dist + along with a set of signed jars using the jalview key). In order to + test locally via webstart you'll now need to add 'file:/' to your + java webstart security exception list. Then:

+
javaws file://.pathtojalviewsource./dist/jalview.jnlp
+

Please remember to remove that entry afterwards, since it will leave + your system vulnerable to malicious code. +

+

Building the JalviewLite applet
The JalviewLite applet is compiled using a subset of the packages in the src directory (specifically: MCView, and jalview.{datamodel, diff --git a/examples/exampleFeatures.txt b/examples/exampleFeatures.txt index 2dc4b6d..c0098a9 100755 --- a/examples/exampleFeatures.txt +++ b/examples/exampleFeatures.txt @@ -26,73 +26,74 @@ BETA-TURN-IIL 8b5b50 ST-MOTIF ac25a1 STARTGROUP uniprot +Pfam family FER_CAPAA -1 0 0 Pfam Iron-sulfur (2Fe-2S) FER_CAPAA -1 39 39 METAL Iron-sulfur (2Fe-2S) FER_CAPAA -1 44 44 METAL Iron-sulfur (2Fe-2S) FER_CAPAA -1 47 47 METAL Iron-sulfur (2Fe-2S) FER_CAPAA -1 77 77 METAL -Fer2 Status: True Positive Pfam 8_8 FER_CAPAA -1 8 83 Pfam +Fer2 Status: True Positive Pfam 8_8 FER_CAPAA -1 8 83 Pfam Ferredoxin_fold Status: True Positive FER_CAPAA -1 3 93 Cath Iron-sulfur (2Fe-2S) FER_CAPAN -1 86 86 METAL Iron-sulfur (2Fe-2S) FER_CAPAN -1 91 91 METAL Iron-sulfur (2Fe-2S) FER_CAPAN -1 94 94 METAL Iron-sulfur (2Fe-2S) FER_CAPAN -1 124 124 METAL -Fer2 Status: True Positive Pfam 55_13 FER_CAPAN -1 55 130 Pfam +Fer2 Status: True Positive Pfam 55_13 FER_CAPAN -1 55 130 Pfam Ferredoxin_fold Status: True Positive FER_CAPAN -1 45 140 Cath Iron-sulfur (2Fe-2S) FER1_SOLLC -1 86 86 METAL Iron-sulfur (2Fe-2S) FER1_SOLLC -1 91 91 METAL Iron-sulfur (2Fe-2S) FER1_SOLLC -1 94 94 METAL Iron-sulfur (2Fe-2S) FER1_SOLLC -1 124 124 METAL -Fer2 Status: True Positive Pfam 55_13 FER1_SOLLC -1 55 130 Pfam +Fer2 Status: True Positive Pfam 55_13 FER1_SOLLC -1 55 130 Pfam Ferredoxin_fold Status: True Positive FER1_SOLLC -1 45 140 Cath -Fer2 Status: True Positive Pfam 55_13 Q93XJ9_SOLTU -1 55 130 Pfam +Fer2 Status: True Positive Pfam 55_13 Q93XJ9_SOLTU -1 55 130 Pfam Ferredoxin_fold Status: True Positive Q93XJ9_SOLTU -1 45 140 Cath Iron-sulfur (2Fe-2S) FER1_PEA -1 91 91 METAL Iron-sulfur (2Fe-2S) FER1_PEA -1 96 96 METAL Iron-sulfur (2Fe-2S) FER1_PEA -1 99 99 METAL Iron-sulfur (2Fe-2S) FER1_PEA -1 129 129 METAL -Fer2 Status: True Positive Pfam 60_13 FER1_PEA -1 60 135 Pfam +Fer2 Status: True Positive Pfam 60_13 FER1_PEA -1 60 135 Pfam Ferredoxin_fold Status: True Positive FER1_PEA -1 50 145 Cath -Fer2 Status: True Positive Pfam 63_13 Q7XA98_TRIPR -1 63 138 Pfam +Fer2 Status: True Positive Pfam 63_13 Q7XA98_TRIPR -1 63 138 Pfam Ferredoxin_fold Status: True Positive Q7XA98_TRIPR -1 53 148 Cath Iron-sulfur (2Fe-2S) FER1_MESCR -1 90 90 METAL Iron-sulfur (2Fe-2S) FER1_MESCR -1 95 95 METAL Iron-sulfur (2Fe-2S) FER1_MESCR -1 98 98 METAL Iron-sulfur (2Fe-2S) FER1_MESCR -1 128 128 METAL -Fer2 Status: True Positive Pfam 59_13 FER1_MESCR -1 59 134 Pfam +Fer2 Status: True Positive Pfam 59_13 FER1_MESCR -1 59 134 Pfam Ferredoxin_fold Status: True Positive FER1_MESCR -1 49 144 Cath Iron-sulfur (2Fe-2S) FER1_SPIOL -1 89 89 METAL Iron-sulfur (2Fe-2S) FER1_SPIOL -1 94 94 METAL Iron-sulfur (2Fe-2S) FER1_SPIOL -1 97 97 METAL Iron-sulfur (2Fe-2S) FER1_SPIOL -1 127 127 METAL -Fer2 Status: True Positive Pfam 58_13 FER1_SPIOL -1 58 133 Pfam +Fer2 Status: True Positive Pfam 58_13 FER1_SPIOL -1 58 133 Pfam Ferredoxin_fold Status: True Positive FER1_SPIOL -1 48 143 Cath Iron-sulfur (2Fe-2S) FER3_RAPSA -1 39 39 METAL Iron-sulfur (2Fe-2S) FER3_RAPSA -1 44 44 METAL Iron-sulfur (2Fe-2S) FER3_RAPSA -1 47 47 METAL Iron-sulfur (2Fe-2S) FER3_RAPSA -1 77 77 METAL -Fer2 Status: True Positive Pfam 8_8 FER3_RAPSA -1 8 83 Pfam +Fer2 Status: True Positive Pfam 8_8 FER3_RAPSA -1 8 83 Pfam Ferredoxin_fold Status: True Positive FER3_RAPSA -1 3 93 Cath Iron-sulfur (2Fe-2S) FER_BRANA -1 39 39 METAL Iron-sulfur (2Fe-2S) FER_BRANA -1 44 44 METAL Iron-sulfur (2Fe-2S) FER_BRANA -1 47 47 METAL Iron-sulfur (2Fe-2S) FER_BRANA -1 77 77 METAL -Fer2 Status: True Positive Pfam 8_8 FER_BRANA -1 8 83 Pfam +Fer2 Status: True Positive Pfam 8_8 FER_BRANA -1 8 83 Pfam Ferredoxin_fold Status: True Positive FER_BRANA -1 2 96 Cath Iron-sulfur (2Fe-2S) FER2_ARATH -1 91 91 METAL Iron-sulfur (2Fe-2S) FER2_ARATH -1 96 96 METAL Iron-sulfur (2Fe-2S) FER2_ARATH -1 99 99 METAL Iron-sulfur (2Fe-2S) FER2_ARATH -1 129 129 METAL -Fer2 Status: True Positive Pfam 60_13 FER2_ARATH -1 60 135 Pfam +Fer2 Status: True Positive Pfam 60_13 FER2_ARATH -1 60 135 Pfam Ferredoxin_fold Status: True Positive FER2_ARATH -1 50 145 Cath -Fer2 Status: True Positive Pfam 60_11 Q93Z60_ARATH -1 60 118 Pfam +Fer2 Status: True Positive Pfam 60_11 Q93Z60_ARATH -1 60 118 Pfam Ferredoxin_fold Status: True Positive Q93Z60_ARATH -1 52 118 Cath Iron-sulfur (2Fe-2S) FER1_MAIZE -1 91 91 METAL Iron-sulfur (2Fe-2S) FER1_MAIZE -1 96 96 METAL Iron-sulfur (2Fe-2S) FER1_MAIZE -1 99 99 METAL Iron-sulfur (2Fe-2S) FER1_MAIZE -1 129 129 METAL -Fer2 Status: True Positive Pfam 60_13 FER1_MAIZE -1 60 135 Pfam +Fer2 Status: True Positive Pfam 60_13 FER1_MAIZE -1 60 135 Pfam Ferredoxin_fold Status: True Positive FER1_MAIZE -1 50 145 Cath -Fer2 Status: True Positive Pfam 52_12 O80429_MAIZE -1 52 127 Pfam +Fer2 Status: True Positive Pfam 52_12 O80429_MAIZE -1 52 127 Pfam Ferredoxin_fold Status: True Positive O80429_MAIZE -1 42 137 Cath ENDGROUP uniprot diff --git a/examples/plantfdx.features b/examples/plantfdx.features index a23d152..872dadc 100644 --- a/examples/plantfdx.features +++ b/examples/plantfdx.features @@ -14,22 +14,22 @@ Iron-sulfur (2Fe-2S) FER_CAPAA -1 39 39 METAL Iron-sulfur (2Fe-2S) FER_CAPAA -1 44 44 METAL Iron-sulfur (2Fe-2S) FER_CAPAA -1 47 47 METAL Iron-sulfur (2Fe-2S) FER_CAPAA -1 77 77 METAL -Description: Fer2 Status: True Positive Pfam 8_83 FER_CAPAA -1 8 83 Pfam +Description: Fer2 Status: True Positive Pfam 8_83 FER_CAPAA -1 8 83 Pfam Chloroplast FER_CAPAN -1 1 47 TRANSIT Iron-sulfur (2Fe-2S) FER_CAPAN -1 86 86 METAL Iron-sulfur (2Fe-2S) FER_CAPAN -1 91 91 METAL Iron-sulfur (2Fe-2S) FER_CAPAN -1 94 94 METAL Iron-sulfur (2Fe-2S) FER_CAPAN -1 124 124 METAL Phosphothreonine FER_CAPAN -1 136 136 MOD_RES -Description: Fer2 Status: True Positive Pfam 55_130 FER_CAPAN -1 55 130 Pfam +Description: Fer2 Status: True Positive Pfam 55_130 FER_CAPAN -1 55 130 Pfam Chloroplast FER1_SOLLC -1 1 47 TRANSIT Iron-sulfur (2Fe-2S) FER1_SOLLC -1 86 86 METAL Iron-sulfur (2Fe-2S) FER1_SOLLC -1 91 91 METAL Iron-sulfur (2Fe-2S) FER1_SOLLC -1 94 94 METAL Iron-sulfur (2Fe-2S) FER1_SOLLC -1 124 124 METAL -Description: Fer2 Status: True Positive Pfam 55_130 FER1_SOLLC -1 55 130 Pfam +Description: Fer2 Status: True Positive Pfam 55_130 FER1_SOLLC -1 55 130 Pfam Evidence: EI4 Q93XJ9_SOLTU -1 1 48 SIGNAL -Description: Fer2 Status: True Positive Pfam 55_130 Q93XJ9_SOLTU -1 55 130 Pfam +Description: Fer2 Status: True Positive Pfam 55_130 Q93XJ9_SOLTU -1 55 130 Pfam Chloroplast FER1_PEA -1 1 52 TRANSIT L -> I (in strain: cv. Onward) FER1_PEA -1 59 59 VARIANT I -> L (in strain: cv. Onward) FER1_PEA -1 85 85 VARIANT @@ -38,14 +38,14 @@ Iron-sulfur (2Fe-2S) FER1_PEA -1 96 96 METAL Iron-sulfur (2Fe-2S) FER1_PEA -1 99 99 METAL Iron-sulfur (2Fe-2S) FER1_PEA -1 129 129 METAL YPTS -> PPPA (in Ref. 2) FER1_PEA -1 132 135 CONFLICT -Description: Fer2 Status: True Positive Pfam 60_135 FER1_PEA -1 60 135 Pfam -Description: Fer2 Status: True Positive Pfam 63_138 Q7XA98_TRIPR -1 63 138 Pfam +Description: Fer2 Status: True Positive Pfam 60_135 FER1_PEA -1 60 135 Pfam +Description: Fer2 Status: True Positive Pfam 63_138 Q7XA98_TRIPR -1 63 138 Pfam Chloroplast FER1_MESCR -1 1 51 TRANSIT Iron-sulfur (2Fe-2S) FER1_MESCR -1 90 90 METAL Iron-sulfur (2Fe-2S) FER1_MESCR -1 95 95 METAL Iron-sulfur (2Fe-2S) FER1_MESCR -1 98 98 METAL Iron-sulfur (2Fe-2S) FER1_MESCR -1 128 128 METAL -Description: Fer2 Status: True Positive Pfam 59_134 FER1_MESCR -1 59 134 Pfam +Description: Fer2 Status: True Positive Pfam 59_134 FER1_MESCR -1 59 134 Pfam Chloroplast FER1_SPIOL -1 1 50 TRANSIT STRAND FER1_SPIOL -1 52 59 STRAND TURN FER1_SPIOL -1 60 61 TURN @@ -68,7 +68,7 @@ Iron-sulfur (2Fe-2S) FER1_SPIOL -1 127 127 METAL STRAND FER1_SPIOL -1 130 133 STRAND STRAND FER1_SPIOL -1 135 138 STRAND HELIX FER1_SPIOL -1 142 144 HELIX -Description: Fer2 Status: True Positive Pfam 58_133 FER1_SPIOL -1 58 133 Pfam +Description: Fer2 Status: True Positive Pfam 58_133 FER1_SPIOL -1 58 133 Pfam I -> V FER3_RAPSA -1 8 8 VARIANT Iron-sulfur (2Fe-2S) FER3_RAPSA -1 39 39 METAL Iron-sulfur (2Fe-2S) FER3_RAPSA -1 44 44 METAL @@ -77,25 +77,25 @@ S -> T FER3_RAPSA -1 55 55 VARIANT Iron-sulfur (2Fe-2S) FER3_RAPSA -1 77 77 METAL R -> K FER3_RAPSA -1 91 91 VARIANT M -> V FER3_RAPSA -1 95 95 VARIANT -Description: Fer2 Status: True Positive Pfam 8_83 FER3_RAPSA -1 8 83 Pfam +Description: Fer2 Status: True Positive Pfam 8_83 FER3_RAPSA -1 8 83 Pfam Chloroplast FER1_ARATH -1 1 52 TRANSIT Iron-sulfur (2Fe-2S) FER1_ARATH -1 91 91 METAL Iron-sulfur (2Fe-2S) FER1_ARATH -1 96 96 METAL Iron-sulfur (2Fe-2S) FER1_ARATH -1 99 99 METAL Iron-sulfur (2Fe-2S) FER1_ARATH -1 129 129 METAL -Description: Fer2 Status: True Positive Pfam 60_135 FER1_ARATH -1 60 135 Pfam +Description: Fer2 Status: True Positive Pfam 60_135 FER1_ARATH -1 60 135 Pfam Iron-sulfur (2Fe-2S) FER_BRANA -1 39 39 METAL Iron-sulfur (2Fe-2S) FER_BRANA -1 44 44 METAL Iron-sulfur (2Fe-2S) FER_BRANA -1 47 47 METAL Iron-sulfur (2Fe-2S) FER_BRANA -1 77 77 METAL -Description: Fer2 Status: True Positive Pfam 8_83 FER_BRANA -1 8 83 Pfam +Description: Fer2 Status: True Positive Pfam 8_83 FER_BRANA -1 8 83 Pfam Chloroplast FER2_ARATH -1 1 52 TRANSIT Iron-sulfur (2Fe-2S) FER2_ARATH -1 91 91 METAL Iron-sulfur (2Fe-2S) FER2_ARATH -1 96 96 METAL Iron-sulfur (2Fe-2S) FER2_ARATH -1 99 99 METAL Iron-sulfur (2Fe-2S) FER2_ARATH -1 129 129 METAL -Description: Fer2 Status: True Positive Pfam 60_135 FER2_ARATH -1 60 135 Pfam -Description: Fer2 Status: True Positive Pfam 60_118 Q93Z60_ARATH -1 60 118 Pfam +Description: Fer2 Status: True Positive Pfam 60_135 FER2_ARATH -1 60 135 Pfam +Description: Fer2 Status: True Positive Pfam 60_118 Q93Z60_ARATH -1 60 118 Pfam Chloroplast FER1_MAIZE -1 1 52 TRANSIT STRAND FER1_MAIZE -1 57 59 STRAND STRAND FER1_MAIZE -1 72 74 STRAND @@ -113,6 +113,6 @@ Iron-sulfur (2Fe-2S) FER1_MAIZE -1 129 129 METAL STRAND FER1_MAIZE -1 132 135 STRAND STRAND FER1_MAIZE -1 137 141 STRAND TURN FER1_MAIZE -1 142 142 TURN -Description: Fer2 Status: True Positive Pfam 60_135 FER1_MAIZE -1 60 135 Pfam -Description: Fer2 Status: True Positive Pfam 52_127 O80429_MAIZE -1 52 127 Pfam +Description: Fer2 Status: True Positive Pfam 60_135 FER1_MAIZE -1 60 135 Pfam +Description: Fer2 Status: True Positive Pfam 52_127 O80429_MAIZE -1 52 127 Pfam ENDGROUP uniprot diff --git a/help/html/features/annotationsFormat.html b/help/html/features/annotationsFormat.html index 545f0c1..744370b 100755 --- a/help/html/features/annotationsFormat.html +++ b/help/html/features/annotationsFormat.html @@ -110,7 +110,7 @@ followed by a description for the row, which is shown in a tooltip when the user mouses over the annotation row's label. Since Jalview 2.7, the description field may also contain HTML tags (in - the same way as a sequence feature's + the same way as a sequence feature's label), providing the text is enclosed in an <html/> tag.

    Please note: URL links embedded in HTML descriptions are diff --git a/help/html/features/featuresettings.html b/help/html/features/featuresettings.html index 9164afd..200fc8f 100755 --- a/help/html/features/featuresettings.html +++ b/help/html/features/featuresettings.html @@ -104,7 +104,7 @@ the bottom of the list is rendered below a feature higher up in the list.
    You can change the order of a feature by dragging it up and down the list with - the mouse. + the mouse (not applet)
    .

    The Optimise order button (currently only diff --git a/help/html/features/mmcif.html b/help/html/features/mmcif.html new file mode 100644 index 0000000..6df0fd4 --- /dev/null +++ b/help/html/features/mmcif.html @@ -0,0 +1,28 @@ + + + + +mmCIF File Format + + + mmCIF File Format +

    The mmCIF file format (macromolecular Crystallographic + Information) was developed under the auspices of the International Union of Crystallography (IUCr) to extend the Crystallographic Information + File (CIF) data representation used for describing small molecule + structures and associated diffraction experiments.

    + Merits of mmCIF file format +
      +
    • Large structures (containing >62 chains and/or 99999 ATOM + records) that cannot be fully represented in the PDB file format are + available in the PDB archive as single PDBx/mmCIF files.
    • +
    • PDBx/mmCIF file format provides richer data annotation
    • +
    • PDBx/mmCIF became the standard PDB archive format in 2014. + Since 2016 the PDB File Format is no longer being modified or + extended to support new content. +
    • +
    + + mmCIF file format support for importing 3D structure data from + flat file and EMBL-PDBe via mmCIF was added in Jalview 2.9.1 + + \ No newline at end of file diff --git a/help/html/features/seqmappings.html b/help/html/features/seqmappings.html index ac63c9e..60ac6ab 100644 --- a/help/html/features/seqmappings.html +++ b/help/html/features/seqmappings.html @@ -42,5 +42,7 @@ retrieved by the Sequence Fetcher, and allows sequence features to be mapped directly from Uniprot das sources to their coding region on EMBL sequence records. +

    +

    In Jalview 2.9.1 SIFTS Mapping was added as a better means for explicitly identifying the coordinates corresponding to a displayed sequence when viewing a PDB structure associated with a sequence

    diff --git a/help/html/features/sifts_mapping_output.png b/help/html/features/sifts_mapping_output.png new file mode 100644 index 0000000..3c28b81 Binary files /dev/null and b/help/html/features/sifts_mapping_output.png differ diff --git a/help/html/features/siftsmapping.html b/help/html/features/siftsmapping.html new file mode 100644 index 0000000..c344a20 --- /dev/null +++ b/help/html/features/siftsmapping.html @@ -0,0 +1,45 @@ + + + + +SIFTS Mapping + + + +

    SIFTS Mapping

    + +

    + SIFTS (Structure integration with function, taxonomy + and sequences) provides an up-to-date resource for residue-level + mapping between Uniprot and PDB entries. The information is updated and + released weekly simultaneously with the release of new PDB entries. + SIFTS Entries are published as XML files and made publicly available via an FTP + site hosted at the European Bioinformatics Institute. +

    + +

    + At the point of viewing a PDB structure, Jalview downloads a SIFTS file + for the target entry and uses it to accurately map the sequence residues with the + structure residue. Prior to SIFTS integration, Jalview uses Needleman and Wunsch + Alignment algorithm to map sequence residues to structure residues, and that may not + always result to a correct mapping since it is computational determined. +

    + +

    + The default method for 'Sequence ↔ Structure' mapping can be configured + in the Structure tab in the Tools → Preferences dialog box. When 'SIFTS' + is enabled as the default, all mappings between 'Sequence ↔ Structure' is + performed via SIFTS provided that there is a valid SIFTS entry for PDB structure. If no + valid SIFTS resource is available, then the 'Sequence ↔ Structure' mapping falls + back to Needleman and Wunsch Alignment algorithm. +

    + +

    To verify the mapping method used, you can view the mapping output via the structure viewer menu File → View mapping. A sample mapping output can be seen in the screenshot below. The highlighted position shows the method used.

    +

    + SIFTS mapping output +

    + +

    SIFTS Mapping integration was added in Jalview 2.9.1

    + + + \ No newline at end of file diff --git a/help/html/features/splitView.html b/help/html/features/splitView.html index ed5bef3..1c36abd 100644 --- a/help/html/features/splitView.html +++ b/help/html/features/splitView.html @@ -53,7 +53,7 @@
  • On selecting rows, columns or regions in one alignment, the corresponding selection is made in the other
  • Sequence ordering in one alignment (using the cursor, or "Calculate→Sort") is also applied to the other
  • Editing (gap insertion / deletion) in the protein alignment @@ -75,7 +75,7 @@ panels.
  • Panel heights are adjusted dragging the divider between them using the mouse
  • -
  • "View→New +
  • "View→New View / Expand Views / Gather Views" behave as for a normal alignment window, but always create new views as Split Frames
diff --git a/help/html/features/viewingpdbs.html b/help/html/features/viewingpdbs.html index 4d35516..d4819f1 100755 --- a/help/html/features/viewingpdbs.html +++ b/help/html/features/viewingpdbs.html @@ -121,6 +121,19 @@

+ Importing PDB Entries or files in mmCIF format
+ mmCIF file format provides an alternative means for + importing 3D structure data from flat file and EMBL-PDBe + web-service. To enable mmCIF as the default format for + importing PBD sequences from the PDB sequence fetcher, add or modify the + property + DEFAULT_STRUCTURE_FORMAT=mmCIF in Jalview properties file. + Once this is done, the steps followed in retrieving PDB format files above can + be followed to obtain the same data with mmCIF. mmCIF format file support was added in Jalview 2.9.1.

+ + + +

Associating a large number of PDB files to sequences in an alignment
It is often the case when working with structure alignments that you will have a directory of PDB diff --git a/help/html/keys.html b/help/html/keys.html index a477457..f129551 100755 --- a/help/html/keys.html +++ b/help/html/keys.html @@ -159,7 +159,7 @@ Both Cuts the (fully) selected sequences from the alignment. +columns are selected, you should use the Hide Regions feature instead.--> diff --git a/help/html/menus/popupMenu.html b/help/html/menus/popupMenu.html index 1eb2366..353fb41 100755 --- a/help/html/menus/popupMenu.html +++ b/help/html/menus/popupMenu.html @@ -144,9 +144,8 @@ 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. -

  • Add - Reference Annotations
    -
    When enabled, copies any available alignment +
  • Add Reference Annotations
    + When enabled, copies any available alignment annotation for this sequence to the current view.
  • Set as Reference or Unmark as Reference
    Sets or unsets the reference sequence for diff --git a/help/html/releases.html b/help/html/releases.html index 0bb5fb7..6f1c351 100755 --- a/help/html/releases.html +++ b/help/html/releases.html @@ -47,7 +47,7 @@
    - 2.9.1
    1/6/2016
    + 2.9.1
    14/6/2016
    General @@ -64,7 +64,7 @@
    General
      -
    • +
    • reinstate CTRL-click for opening pop-up menu on OSX
    Application
      @@ -1392,10 +1392,7 @@ between different screens.
    • New preference items for sequence ID tooltip and consensus annotation
    • -
    • Client to submit sequences and IDs to Envision2 - Workflows -
    • +
    • Client to submit sequences and IDs to Envision2 Workflows
    • Vamsas Capabilities
      • Improved VAMSAS synchronization (Jalview archive diff --git a/help/html/webServices/AACon.html b/help/html/webServices/AACon.html index 5dd4472..6d4a461 100644 --- a/help/html/webServices/AACon.html +++ b/help/html/webServices/AACon.html @@ -32,7 +32,7 @@ Function, and Genetics 43(2): 227-241. PubMed or available on the Valdar Group publications page), but the SMERFs score was developed later and described by Manning et al. in 2008 (REST web services exposing sequence alignment, analysis, and secondary structure prediction programs. Originally, Jalview 2's services were maintained by the Barton group at the University of - Dundee, and ran programs on the Life Sciences High-performace + Dundee, and ran programs on the Life Sciences High-performance Computing Cluster. With the advent of JABAWS, however, it is possible for anyone to host Jalview web diff --git a/help/html/webServices/urllinks.html b/help/html/webServices/urllinks.html index de0f8cd..7a23d58 100644 --- a/help/html/webServices/urllinks.html +++ b/help/html/webServices/urllinks.html @@ -83,7 +83,7 @@ Please Note:
        • The regular expressions supported by Jalview are those - provided by the Stevesoft + provided by the Stevesoft javaregex package.
        • Some characters must be escaped when specifying them as diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 8943860..b3da568 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -321,7 +321,7 @@ action.save_vamsas_session = Guardar Sesi label.select_vamsas_session_opened_as_new_vamsas_session= Selecciones una sesión vamsas para abrirla como una nueva sesión. label.open_saved_vamsas_session = Abrir una sesión VAMSAS guardada label.groovy_console = Consola Groovy -label.lineart = lineart +label.lineart = Lineart label.dont_ask_me_again = No volver a preguntar label.select_eps_character_rendering_style = Seleccionar el carácter EPS como estilo de visualización label.invert_selection = Invertir selección diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java index 4201f43..c0c7c46 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java @@ -199,8 +199,9 @@ public class ChimeraManager return null; } - List newModelList = getModelList(); - for (ChimeraModel newModel : newModelList) + // patch for Jalview - set model name in Chimera + // TODO: find a variant that works for sub-models + for (ChimeraModel newModel : getModelList()) { if (!modelList.contains(newModel)) { @@ -209,15 +210,12 @@ public class ChimeraManager "setattr M name " + modelName + " #" + newModel.getModelNumber(), false); modelList.add(newModel); - } } // assign color and residues to open models for (ChimeraModel chimeraModel : modelList) { - // // patch for Jalview - set model name in Chimera - // // TODO: find a variant that works for sub-models // get model color Color modelColor = getModelColor(chimeraModel); if (modelColor != null) @@ -731,7 +729,7 @@ public class ChimeraManager */ public List sendChimeraCommand(String command, boolean reply) { - // System.out.println("chimeradebug>> " + command); + // System.out.println("chimeradebug>> " + command); if (!isChimeraLaunched() || command == null || "".equals(command.trim())) { diff --git a/src/jalview/analysis/Conservation.java b/src/jalview/analysis/Conservation.java index d4ae57d..7b3ce25 100755 --- a/src/jalview/analysis/Conservation.java +++ b/src/jalview/analysis/Conservation.java @@ -235,10 +235,7 @@ public class Conservation c = '-'; } - if (!canonicaliseAa && 'a' <= c && c <= 'z') - { - c -= (32); // 32 = 'a' - 'A' - } + c = toUpperCase(c); } values[c]++; } @@ -326,6 +323,7 @@ public class Conservation } else { + c = toUpperCase(c); nres++; if (nres == 1) @@ -347,6 +345,22 @@ public class Conservation } /** + * Returns the upper-cased character if between 'a' and 'z', else the + * unchanged value + * + * @param c + * @return + */ + char toUpperCase(char c) + { + if ('a' <= c && c <= 'z') + { + c -= (32); // 32 = 'a' - 'A' + } + return c; + } + + /** * Calculates the conservation sequence * * @param consflag diff --git a/src/jalview/analysis/SequenceIdMatcher.java b/src/jalview/analysis/SequenceIdMatcher.java index 70defb0..f744ed1 100755 --- a/src/jalview/analysis/SequenceIdMatcher.java +++ b/src/jalview/analysis/SequenceIdMatcher.java @@ -290,7 +290,7 @@ public class SequenceIdMatcher { if (s != null) { - id = new String(s); + id = new String(s.toLowerCase()); } else { diff --git a/src/jalview/api/DBRefEntryI.java b/src/jalview/api/DBRefEntryI.java index 9415745..490b21a 100644 --- a/src/jalview/api/DBRefEntryI.java +++ b/src/jalview/api/DBRefEntryI.java @@ -2,6 +2,7 @@ package jalview.api; import jalview.datamodel.Mapping; +//JBPComment: this is a datamodel API - so it should be in datamodel (it's a peer of SequenceI) public interface DBRefEntryI { diff --git a/src/jalview/api/SiftsClientI.java b/src/jalview/api/SiftsClientI.java index e2fac14..527ae17 100644 --- a/src/jalview/api/SiftsClientI.java +++ b/src/jalview/api/SiftsClientI.java @@ -29,6 +29,8 @@ import jalview.xml.binding.sifts.Entry.Entity; import java.util.HashMap; import java.util.HashSet; +// JBPComment: this isn't a top-level Jalview API - should be in its own package api + public interface SiftsClientI { /** diff --git a/src/jalview/appletgui/AnnotationLabels.java b/src/jalview/appletgui/AnnotationLabels.java index 5727e9c..b28ccc7 100755 --- a/src/jalview/appletgui/AnnotationLabels.java +++ b/src/jalview/appletgui/AnnotationLabels.java @@ -162,6 +162,7 @@ public class AnnotationLabels extends Panel implements ActionListener, return row; } + @Override public void actionPerformed(ActionEvent evt) { AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); @@ -261,6 +262,7 @@ public class AnnotationLabels extends Panel implements ActionListener, boolean resizePanel = false; + @Override public void mouseMoved(MouseEvent evt) { resizePanel = evt.getY() < 10 && evt.getX() < 14; @@ -306,6 +308,7 @@ public class AnnotationLabels extends Panel implements ActionListener, dragCancelled = true; } + @Override public void mouseDragged(MouseEvent evt) { if (dragCancelled) @@ -365,10 +368,12 @@ public class AnnotationLabels extends Panel implements ActionListener, } } + @Override public void mouseClicked(MouseEvent evt) { } + @Override public void mouseReleased(MouseEvent evt) { if (!resizePanel && !dragCancelled) @@ -400,6 +405,7 @@ public class AnnotationLabels extends Panel implements ActionListener, ap.annotationPanel.repaint(); } + @Override public void mouseEntered(MouseEvent evt) { if (evt.getY() < 10 && evt.getX() < 14) @@ -409,6 +415,7 @@ public class AnnotationLabels extends Panel implements ActionListener, } } + @Override public void mouseExited(MouseEvent evt) { dragCancelled = false; @@ -427,6 +434,7 @@ public class AnnotationLabels extends Panel implements ActionListener, repaint(); } + @Override public void mousePressed(MouseEvent evt) { oldY = evt.getY(); @@ -522,6 +530,7 @@ public class AnnotationLabels extends Panel implements ActionListener, final AlignmentAnnotation aaa = aa[selectedRow]; cbmi.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { if (aaa.groupRef != null) @@ -545,6 +554,7 @@ public class AnnotationLabels extends Panel implements ActionListener, aa[selectedRow].groupRef.isShowConsensusHistogram()); chist.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { // TODO: pass on reference @@ -564,6 +574,7 @@ public class AnnotationLabels extends Panel implements ActionListener, aa[selectedRow].groupRef.isShowSequenceLogo()); cprofl.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { // TODO: pass on reference @@ -585,6 +596,7 @@ public class AnnotationLabels extends Panel implements ActionListener, aa[selectedRow].groupRef.isNormaliseSequenceLogo()); cprofn.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { // TODO: pass on reference @@ -608,6 +620,7 @@ public class AnnotationLabels extends Panel implements ActionListener, av.isShowConsensusHistogram()); chist.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { // TODO: pass on reference @@ -631,6 +644,7 @@ public class AnnotationLabels extends Panel implements ActionListener, av.isShowSequenceLogo()); cprof.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { // TODO: pass on reference @@ -655,6 +669,7 @@ public class AnnotationLabels extends Panel implements ActionListener, av.isNormaliseSequenceLogo()); cprofn.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { // TODO: pass on reference @@ -697,11 +712,47 @@ public class AnnotationLabels extends Panel implements ActionListener, // todo: make the ap scroll to the selection - not necessary, first // click highlights/scrolls, second selects ap.seqPanel.ap.idPanel.highlightSearchResults(null); - ap.av.setSelectionGroup(// new SequenceGroup( - aa[selectedRow].groupRef); // ); - ap.av.sendSelection(); + // process modifiers + SequenceGroup sg = ap.av.getSelectionGroup(); + if (sg == null + || sg == aa[selectedRow].groupRef + || !(jalview.util.Platform.isControlDown(evt) || evt + .isShiftDown())) + { + if (jalview.util.Platform.isControlDown(evt) + || evt.isShiftDown()) + { + // clone a new selection group from the associated group + ap.av.setSelectionGroup(new SequenceGroup( + aa[selectedRow].groupRef)); + } + else + { + // set selection to the associated group so it can be edited + ap.av.setSelectionGroup(aa[selectedRow].groupRef); + } + } + else + { + // modify current selection with associated group + int remainToAdd = aa[selectedRow].groupRef.getSize(); + for (SequenceI sgs : aa[selectedRow].groupRef.getSequences()) + { + if (jalview.util.Platform.isControlDown(evt)) + { + sg.addOrRemove(sgs, --remainToAdd == 0); + } + else + { + // notionally, we should also add intermediate sequences from + // last added sequence ? + sg.addSequence(sgs, --remainToAdd == 0); + } + } + } ap.paintAlignment(false); PaintRefresher.Refresh(ap, ap.av.getSequenceSetId()); + ap.av.sendSelection(); } else { @@ -728,7 +779,8 @@ public class AnnotationLabels extends Panel implements ActionListener, // we make a copy rather than edit the current selection if no // modifiers pressed // see Enhancement JAL-1557 - if (!(evt.isControlDown() || evt.isShiftDown())) + if (!(jalview.util.Platform.isControlDown(evt) || evt + .isShiftDown())) { sg = new SequenceGroup(sg); sg.clear(); @@ -736,7 +788,7 @@ public class AnnotationLabels extends Panel implements ActionListener, } else { - if (evt.isControlDown()) + if (jalview.util.Platform.isControlDown(evt)) { sg.addOrRemove(aa[selectedRow].sequenceRef, true); } @@ -794,11 +846,13 @@ public class AnnotationLabels extends Panel implements ActionListener, } } + @Override public void update(Graphics g) { paint(g); } + @Override public void paint(Graphics g) { int w = getSize().width; diff --git a/src/jalview/appletgui/IdPanel.java b/src/jalview/appletgui/IdPanel.java index 8f24f11..36c2199 100755 --- a/src/jalview/appletgui/IdPanel.java +++ b/src/jalview/appletgui/IdPanel.java @@ -100,6 +100,7 @@ public class IdPanel extends Panel implements MouseListener, Tooltip tooltip; + @Override public void mouseMoved(MouseEvent e) { int seq = alignPanel.seqPanel.findSeq(e); @@ -188,6 +189,7 @@ public class IdPanel extends Panel implements MouseListener, tooltiptext = null; } + @Override public void mouseDragged(MouseEvent e) { mouseDragging = true; @@ -207,6 +209,7 @@ public class IdPanel extends Panel implements MouseListener, alignPanel.paintAlignment(false); } + @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() < 2) @@ -270,6 +273,7 @@ public class IdPanel extends Panel implements MouseListener, } } + @Override public void mouseEntered(MouseEvent e) { if (scrollThread != null) @@ -278,6 +282,7 @@ public class IdPanel extends Panel implements MouseListener, } } + @Override public void mouseExited(MouseEvent e) { if (av.getWrapAlignment()) @@ -297,6 +302,7 @@ public class IdPanel extends Panel implements MouseListener, } } + @Override public void mousePressed(MouseEvent e) { if (e.getClickCount() > 1) @@ -345,7 +351,8 @@ public class IdPanel extends Panel implements MouseListener, } if ((av.getSelectionGroup() == null) - || ((!e.isControlDown() && !e.isShiftDown()) && av + || ((!jalview.util.Platform.isControlDown(e) && !e + .isShiftDown()) && av .getSelectionGroup() != null)) { av.setSelectionGroup(new SequenceGroup()); @@ -401,6 +408,7 @@ public class IdPanel extends Panel implements MouseListener, } + @Override public void mouseReleased(MouseEvent e) { if (scrollThread != null) @@ -455,6 +463,7 @@ public class IdPanel extends Panel implements MouseListener, running = false; } + @Override public void run() { running = true; diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java index 479b746..31bf6a4 100644 --- a/src/jalview/appletgui/SeqPanel.java +++ b/src/jalview/appletgui/SeqPanel.java @@ -1813,9 +1813,12 @@ public class SeqPanel extends Panel implements MouseMotionListener, // do we want to thread this ? (contention with seqsel and colsel locks, I // suspect) - // rules are: colsel is copied if there is a real intersection between - // sequence selection - boolean repaint = false, copycolsel = true; + /* + * only copy colsel if there is a real intersection between + * sequence selection and this panel's alignment + */ + boolean repaint = false; + boolean copycolsel = false; if (av.getSelectionGroup() == null || !av.isSelectionGroupChanged(true)) { SequenceGroup sgroup = null; @@ -1832,11 +1835,9 @@ public class SeqPanel extends Panel implements MouseMotionListener, } sgroup = seqsel.intersect(av.getAlignment(), (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null); - if ((sgroup == null || sgroup.getSize() == 0) - && (colsel == null || colsel.isEmpty())) + if ((sgroup != null && sgroup.getSize() > 0)) { - // don't copy columns if the region didn't intersect. - copycolsel = false; + copycolsel = true; } } if (sgroup != null && sgroup.getSize() > 0) @@ -1964,7 +1965,6 @@ public class SeqPanel extends Panel implements MouseMotionListener, ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv, av); av.setColumnSelection(cs); - av.isColSelChanged(true); ap.scalePanelHolder.repaint(); ap.repaint(); diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index 7911cd5..38aa55f 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -426,7 +426,7 @@ public class Cache System.out .println("Jalview Version: " + codeVersion + codeInstallation); - Pdb.setCurrentDefaultFomart(jalview.bin.Cache.getDefault( + Pdb.setCurrentDefaultFormat(jalview.bin.Cache.getDefault( "DEFAULT_STRUCTURE_FORMAT", DEFAULT_STRUCTURE_FORMAT)); // jnlpVersion will be null if we're using InstallAnywhere // Dont do this check if running in headless mode diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 6fd76b2..aaf70b8 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -32,10 +32,14 @@ import java.util.List; import java.util.Vector; /** - * NOTE: Columns are zero based. + * Data class holding the selected columns and hidden column ranges for a view. + * Ranges are base 1. */ public class ColumnSelection { + /** + * A class to hold an efficient representation of selected columns + */ private class IntList { /* @@ -205,9 +209,26 @@ public class ColumnSelection } return rlist; } + + @Override + public int hashCode() + { + // TODO Auto-generated method stub + return selected.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof IntList) + { + return ((IntList) obj).selected.equals(selected); + } + return false; + } } - IntList selected = new IntList(); + IntList selection = new IntList(); /* * list of hidden column [start, end] ranges; the list is maintained in @@ -223,7 +244,7 @@ public class ColumnSelection */ public void addElement(int col) { - selected.add(col); + selection.add(col); } /** @@ -231,7 +252,7 @@ public class ColumnSelection */ public void clear() { - selected.clear(); + selection.clear(); } /** @@ -242,7 +263,7 @@ public class ColumnSelection */ public void removeElement(int col) { - selected.remove(col); + selection.remove(col); } /** @@ -259,9 +280,9 @@ public class ColumnSelection for (int i = start; i < end; i++) { colInt = new Integer(i); - if (selected.contains(colInt)) + if (selection.contains(colInt)) { - selected.remove(colInt); + selection.remove(colInt); } } } @@ -273,7 +294,7 @@ public class ColumnSelection */ public List getSelected() { - return selected.getList(); + return selection.getList(); } /** @@ -282,7 +303,7 @@ public class ColumnSelection */ public List getSelectedRanges() { - return selected.getRanges(); + return selection.getRanges(); } /** @@ -294,7 +315,7 @@ public class ColumnSelection */ public boolean contains(int col) { - return (col > -1) ? selected.isSelected(col) : false; + return (col > -1) ? selection.isSelected(col) : false; } /** @@ -302,7 +323,7 @@ public class ColumnSelection */ public boolean isEmpty() { - return selected == null || selected.isEmpty(); + return selection == null || selection.isEmpty(); } /** @@ -312,11 +333,11 @@ public class ColumnSelection */ public int getMax() { - if (selected.isEmpty()) + if (selection.isEmpty()) { return -1; } - return selected.getMaxColumn(); + return selection.getMaxColumn(); } /** @@ -326,11 +347,11 @@ public class ColumnSelection */ public int getMin() { - if (selected.isEmpty()) + if (selection.isEmpty()) { return 1000000000; } - return selected.getMinColumn(); + return selection.getMinColumn(); } /** @@ -344,7 +365,7 @@ public class ColumnSelection public List compensateForEdit(int start, int change) { List deletedHiddenColumns = null; - selected.compensateForEdits(start, change); + selection.compensateForEdits(start, change); if (hiddenColumns != null) { @@ -394,7 +415,7 @@ public class ColumnSelection private void compensateForDelEdits(int start, int change) { - selected.compensateForEdits(start, change); + selection.compensateForEdits(start, change); if (hiddenColumns != null) { @@ -571,12 +592,12 @@ public class ColumnSelection hiddenColumns = null; } } - if (selected != null && selected.size() > 0) + if (selection != null && selection.size() > 0) { - selected.pruneColumnList(shifts); - if (selected != null && selected.size() == 0) + selection.pruneColumnList(shifts); + if (selection != null && selection.size() == 0) { - selected = null; + selection = null; } } // and shift the rest. @@ -743,13 +764,13 @@ public class ColumnSelection public void hideSelectedColumns() { - synchronized (selected) + synchronized (selection) { - for (int[] selregions : selected.getRanges()) + for (int[] selregions : selection.getRanges()) { hideColumns(selregions[0], selregions[1]); } - selected.clear(); + selection.clear(); } } @@ -927,12 +948,12 @@ public class ColumnSelection { if (copy != null) { - if (copy.selected != null) + if (copy.selection != null) { - selected = new IntList(); - for (int i = 0, j = copy.selected.size(); i < j; i++) + selection = new IntList(); + for (int i = 0, j = copy.selection.size(); i < j; i++) { - selected.add(copy.selected.elementAt(i)); + selection.add(copy.selection.elementAt(i)); } } if (copy.hiddenColumns != null) @@ -1307,7 +1328,7 @@ public class ColumnSelection { if (hiddenColumns != null && isVisible(col.intValue())) { - selected.add(col); + selection.add(col); } } } @@ -1321,8 +1342,8 @@ public class ColumnSelection */ public void setElementsFrom(ColumnSelection colsel) { - selected = new IntList(); - if (colsel.selected != null && colsel.selected.size() > 0) + selection = new IntList(); + if (colsel.selection != null && colsel.selection.size() > 0) { if (hiddenColumns != null && hiddenColumns.size() > 0) { @@ -1489,7 +1510,7 @@ public class ColumnSelection */ public boolean hasSelectedColumns() { - return (selected != null && selected.size() > 0); + return (selection != null && selection.size() > 0); } /** @@ -1612,4 +1633,74 @@ public class ColumnSelection return false; } + /** + * Returns a hashCode built from selected columns and hidden column ranges + */ + @Override + public int hashCode() + { + int hashCode = selection.hashCode(); + if (hiddenColumns != null) + { + for (int[] hidden : hiddenColumns) + { + hashCode = 31 * hashCode + hidden[0]; + hashCode = 31 * hashCode + hidden[1]; + } + } + return hashCode; + } + + /** + * Answers true if comparing to a ColumnSelection with the same selected + * columns and hidden columns, else false + */ + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof ColumnSelection)) + { + return false; + } + ColumnSelection that = (ColumnSelection) obj; + + /* + * check columns selected are either both null, or match + */ + if (this.selection == null) + { + if (that.selection != null) + { + return false; + } + } + if (!this.selection.equals(that.selection)) + { + return false; + } + + /* + * check hidden columns are either both null, or match + */ + if (this.hiddenColumns == null) + { + return (that.hiddenColumns == null); + } + if (that.hiddenColumns == null + || that.hiddenColumns.size() != this.hiddenColumns.size()) + { + return false; + } + int i = 0; + for (int[] thisRange : hiddenColumns) + { + int[] thatRange = that.hiddenColumns.get(i++); + if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1]) + { + return false; + } + } + return true; + } + } diff --git a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java index 1ce0d2b..944ef52 100644 --- a/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java +++ b/src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java @@ -101,17 +101,13 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel private String lastCommand; - private boolean loadedInline; - - /** + /* * current set of model filenames loaded */ String[] modelFileNames = null; String lastHighlightCommand; - private List lastReply; - /* * incremented every time a load notification is successfully handled - * lightweight mechanism for other threads to detect when they can start @@ -617,7 +613,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel if (lastCommand == null || !lastCommand.equals(command)) { // trim command or it may never find a match in the replyLog!! - lastReply = viewer.sendChimeraCommand(command.trim(), logResponse); + List lastReply = viewer.sendChimeraCommand(command.trim(), + logResponse); if (logResponse && debug) { log("Response from command ('" + command + "') was:\n" + lastReply); @@ -715,17 +712,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel // End StructureListener // ////////////////////////// - public Color getColour(int atomIndex, int pdbResNum, String chain, - String pdbfile) - { - if (getModelNum(pdbfile) < 0) - { - return null; - } - log("get model / residue colour attribute unimplemented"); - return null; - } - /** * returns the current featureRenderer that should be used to colour the * structures @@ -795,15 +781,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel } /** - * map from string to applet - */ - public Map getRegistryInfo() - { - // TODO Auto-generated method stub - return null; - } - - /** * returns the current sequenceRenderer that should be used to colour the * structures * @@ -815,20 +792,18 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel AlignmentViewPanel alignment); /** - * Construct and send a command to highlight zero, one or more atoms. - * - *
          -   * Done by generating a command like (to 'highlight' positions 44 and 46)
          -   *   show #0:44,46.C
          -   * 
          + * Construct and send a command to highlight zero, one or more atoms. We do + * this by sending an "rlabel" command to show the residue label at that + * position. */ @Override public void highlightAtoms(List atoms) { - if (atoms == null) + if (atoms == null || atoms.size() == 0) { return; } + StringBuilder cmd = new StringBuilder(128); boolean first = true; boolean found = false; @@ -843,7 +818,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel { if (first) { - cmd.append("show #").append(cms.get(0).getModelNumber()) + cmd.append("rlabel #").append(cms.get(0).getModelNumber()) .append(":"); } else @@ -851,7 +826,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel cmd.append(","); } first = false; - cmd.append(cms.get(0).getModelNumber()).append(":"); cmd.append(pdbResNum); if (!chain.equals(" ")) { @@ -863,19 +837,24 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel String command = cmd.toString(); /* - * Avoid repeated commands for the same residue + * avoid repeated commands for the same residue */ if (command.equals(lastHighlightCommand)) { return; } - viewerCommandHistory(false); + /* + * unshow the label for the previous residue + */ + if (lastHighlightCommand != null) + { + viewer.sendChimeraCommand("~" + lastHighlightCommand, false); + } if (found) { - viewer.sendChimeraCommand(command.toString(), false); + viewer.sendChimeraCommand(command, false); } - viewerCommandHistory(true); this.lastHighlightCommand = command; } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 7e7bdd3..d9d5f27 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -113,7 +113,6 @@ import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; -import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; @@ -1327,15 +1326,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, alignmentToExport = viewport.getAlignment(); alignmentStartEnd = viewport.getAlignment() .getVisibleStartAndEndIndex( - viewport - .getColumnSelection().getHiddenColumns()); + viewport.getColumnSelection().getHiddenColumns()); } AlignmentExportData ed = new AlignmentExportData(alignmentToExport, omitHidden, alignmentStartEnd, settings); return ed; } - /** * DOCUMENT ME! * @@ -4845,15 +4842,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } catch (Exception e) { - Cache.log.error( - "Exception when finding crossreferences", e); + Cache.log.error("Exception when finding crossreferences", e); } catch (OutOfMemoryError e) { new OOMWarning("whilst fetching crossreferences", e); } catch (Throwable e) { - Cache.log.error("Error when finding crossreferences", - e); + Cache.log.error("Error when finding crossreferences", e); } finally { AlignFrame.this.setProgressBar(MessageManager.formatMessage( @@ -5030,49 +5025,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void drop(DropTargetDropEvent evt) { Transferable t = evt.getTransferable(); - java.util.List files = null; + java.util.List files = new ArrayList(), protocols = new ArrayList(); try { - DataFlavor uriListFlavor = new DataFlavor( - "text/uri-list;class=java.lang.String"); - if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) - { - // Works on Windows and MacOSX - evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - files = (java.util.List) t - .getTransferData(DataFlavor.javaFileListFlavor); - } - else if (t.isDataFlavorSupported(uriListFlavor)) - { - // This is used by Unix drag system - evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - String data = (String) t.getTransferData(uriListFlavor); - files = new java.util.ArrayList(1); - for (java.util.StringTokenizer st = new java.util.StringTokenizer( - data, "\r\n"); st.hasMoreTokens();) - { - String s = st.nextToken(); - if (s.startsWith("#")) - { - // the line is a comment (as per the RFC 2483) - continue; - } - - java.net.URI uri = new java.net.URI(s); - // check to see if we can handle this kind of URI - if (uri.getScheme().toLowerCase().startsWith("http")) - { - files.add(uri.toString()); - } - else - { - // otherwise preserve old behaviour: catch all for file objects - java.io.File file = new java.io.File(uri); - files.add(file.toString()); - } - } - } + Desktop.transferFromDropTarget(files, protocols, evt, t); } catch (Exception e) { e.printStackTrace(); @@ -5547,8 +5504,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, AlignFrame.this.setMenusForViewport(); } }); - dbRefFetcher - .fetchDBRefs(false); + dbRefFetcher.fetchDBRefs(false); } }).start(); @@ -6106,9 +6062,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, try { Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true)); - al = dna.reverseCdna(complement); viewport.addAlignment(al, ""); + addHistoryItem(new EditCommand( + MessageManager.getString("label.add_sequences"), + Action.PASTE, al.getSequencesArray(), 0, al.getWidth(), + viewport.getAlignment())); } catch (Exception ex) { System.err.println(ex.getMessage()); diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java index 68df498..e27b919 100755 --- a/src/jalview/gui/AnnotationLabels.java +++ b/src/jalview/gui/AnnotationLabels.java @@ -802,8 +802,45 @@ public class AnnotationLabels extends JPanel implements MouseListener, // todo: make the ap scroll to the selection - not necessary, first // click highlights/scrolls, second selects ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(null); - ap.av.setSelectionGroup(// new SequenceGroup( - aa[selectedRow].groupRef); // ); + // process modifiers + SequenceGroup sg = ap.av.getSelectionGroup(); + if (sg == null + || sg == aa[selectedRow].groupRef + || !(jalview.util.Platform.isControlDown(evt) || evt + .isShiftDown())) + { + if (jalview.util.Platform.isControlDown(evt) + || evt.isShiftDown()) + { + // clone a new selection group from the associated group + ap.av.setSelectionGroup(new SequenceGroup( + aa[selectedRow].groupRef)); + } + else + { + // set selection to the associated group so it can be edited + ap.av.setSelectionGroup(aa[selectedRow].groupRef); + } + } + else + { + // modify current selection with associated group + int remainToAdd = aa[selectedRow].groupRef.getSize(); + for (SequenceI sgs : aa[selectedRow].groupRef.getSequences()) + { + if (jalview.util.Platform.isControlDown(evt)) + { + sg.addOrRemove(sgs, --remainToAdd == 0); + } + else + { + // notionally, we should also add intermediate sequences from + // last added sequence ? + sg.addSequence(sgs, --remainToAdd == 0); + } + } + } + ap.paintAlignment(false); PaintRefresher.Refresh(ap, ap.av.getSequenceSetId()); ap.av.sendSelection(); @@ -833,7 +870,8 @@ public class AnnotationLabels extends JPanel implements MouseListener, // we make a copy rather than edit the current selection if no // modifiers pressed // see Enhancement JAL-1557 - if (!(evt.isControlDown() || evt.isShiftDown())) + if (!(jalview.util.Platform.isControlDown(evt) || evt + .isShiftDown())) { sg = new SequenceGroup(sg); sg.clear(); @@ -841,7 +879,7 @@ public class AnnotationLabels extends JPanel implements MouseListener, } else { - if (evt.isControlDown()) + if (jalview.util.Platform.isControlDown(evt)) { sg.addOrRemove(aa[selectedRow].sequenceRef, true); } @@ -861,9 +899,9 @@ public class AnnotationLabels extends JPanel implements MouseListener, sg.addSequence(aa[selectedRow].sequenceRef, false); } ap.av.setSelectionGroup(sg); - ap.av.sendSelection(); ap.paintAlignment(false); PaintRefresher.Refresh(ap, ap.av.getSequenceSetId()); + ap.av.sendSelection(); } } diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 7f36f7f..698b164 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -952,53 +952,15 @@ public class Desktop extends jalview.jbgui.GDesktop implements { boolean success = true; Transferable t = evt.getTransferable(); - java.util.List files = null; - java.util.List protocols = null; + java.util.List files = new ArrayList(); + java.util.List protocols = new ArrayList(); try { - DataFlavor uriListFlavor = new DataFlavor( - "text/uri-list;class=java.lang.String"); - if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) - { - // Works on Windows and MacOSX - evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - files = (java.util.List) t - .getTransferData(DataFlavor.javaFileListFlavor); - } - else if (t.isDataFlavorSupported(uriListFlavor)) - { - // This is used by Unix drag system - evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); - String data = (String) t.getTransferData(uriListFlavor); - files = new java.util.ArrayList(1); - protocols = new java.util.ArrayList(1); - for (java.util.StringTokenizer st = new java.util.StringTokenizer( - data, "\r\n"); st.hasMoreTokens();) - { - String s = st.nextToken(); - if (s.startsWith("#")) - { - // the line is a comment (as per the RFC 2483) - continue; - } - java.net.URI uri = new java.net.URI(s); - if (uri.getScheme().toLowerCase().startsWith("http")) - { - protocols.add(FormatAdapter.URL); - files.add(uri.toString()); - } - else - { - // otherwise preserve old behaviour: catch all for file objects - java.io.File file = new java.io.File(uri); - protocols.add(FormatAdapter.FILE); - files.add(file.toString()); - } - } - } + Desktop.transferFromDropTarget(files, protocols, evt, t); } catch (Exception e) { + e.printStackTrace(); success = false; } @@ -3190,4 +3152,102 @@ public class Desktop extends jalview.jbgui.GDesktop implements return groovyConsole; } + public static void transferFromDropTarget(List files, + List protocols, DropTargetDropEvent evt, Transferable t) + throws Exception + { + + DataFlavor uriListFlavor = new DataFlavor( + "text/uri-list;class=java.lang.String"); + if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) + { + // Works on Windows and MacOSX + Cache.log.debug("Drop handled as javaFileListFlavor"); + evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); + for (Object file : (List) t + .getTransferData(DataFlavor.javaFileListFlavor)) + { + files.add(((File)file).toString()); + protocols.add(FormatAdapter.FILE); + } + } + else + { + // Unix like behaviour + boolean added = false; + String data = null; + if (t.isDataFlavorSupported(uriListFlavor)) + { + Cache.log.debug("Drop handled as uriListFlavor"); + // This is used by Unix drag system + evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); + data = (String) t.getTransferData(uriListFlavor); + } + if (data == null) + { + // fallback to text: workaround - on OSX where there's a JVM bug + Cache.log.debug("standard URIListFlavor failed. Trying text"); + // try text fallback + data = (String) t.getTransferData(new DataFlavor( + "text/plain;class=java.lang.String")); + if (Cache.log.isDebugEnabled()) + { + Cache.log.debug("fallback returned " + data); + } + } + while (protocols.size() < files.size()) + { + Cache.log.debug("Adding missing FILE protocol for " + + files.get(protocols.size())); + protocols.add(FormatAdapter.FILE); + } + for (java.util.StringTokenizer st = new java.util.StringTokenizer( + data, "\r\n"); st.hasMoreTokens();) + { + added = true; + String s = st.nextToken(); + if (s.startsWith("#")) + { + // the line is a comment (as per the RFC 2483) + continue; + } + java.net.URI uri = new java.net.URI(s); + if (uri.getScheme().toLowerCase().startsWith("http")) + { + protocols.add(FormatAdapter.URL); + files.add(uri.toString()); + } + else + { + // otherwise preserve old behaviour: catch all for file objects + java.io.File file = new java.io.File(uri); + protocols.add(FormatAdapter.FILE); + files.add(file.toString()); + } + } + if (Cache.log.isDebugEnabled()) + { + if (data == null || !added) + { + Cache.log + .debug("Couldn't resolve drop data. Here are the supported flavors:"); + for (DataFlavor fl : t.getTransferDataFlavors()) + { + Cache.log.debug("Supported transfer dataflavor: " + + fl.toString()); + evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); + Object df = t.getTransferData(fl); + if (df != null) + { + Cache.log.debug("Retrieves: " + df); + } + else + { + Cache.log.debug("Retrieved nothing"); + } + } + } + } + } + } } diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index f250583..09204d1 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -1326,7 +1326,7 @@ public class FeatureSettings extends JPanel implements * * @return vector of selected das source nicknames */ - public Vector getSelectedSources() + public Vector getSelectedSources() { return dassourceBrowser.getSelectedSources(); } diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index c84505b..61ddafb 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -349,10 +349,9 @@ public class IdPanel extends JPanel implements MouseListener, return; } - if ((av.getSelectionGroup() == null) - || ((!e.isControlDown() && !e.isShiftDown()) && av - .getSelectionGroup() != null)) + || (!jalview.util.Platform.isControlDown(e) + && !e.isShiftDown() && av.getSelectionGroup() != null)) { av.setSelectionGroup(new SequenceGroup()); av.getSelectionGroup().setStartRes(0); diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 1e0772a..4b0ffad 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -60,6 +60,7 @@ import jalview.util.GroupUrlLink; import jalview.util.GroupUrlLink.UrlStringTooLongException; import jalview.util.MessageManager; import jalview.util.UrlLink; +import jalview.ws.DBRefFetcher; import java.awt.Color; import java.awt.event.ActionEvent; @@ -2389,11 +2390,11 @@ public class PopupMenu extends JPopupMenu @Override public void run() { - boolean isNuclueotide = ap.alignFrame.getViewport().getAlignment() + boolean isNucleotide = ap.alignFrame.getViewport().getAlignment() .isNucleotide(); - new jalview.ws.DBRefFetcher(sequences, ap.alignFrame, null, - ap.alignFrame.featureSettings, isNuclueotide) + new DBRefFetcher(sequences, ap.alignFrame, null, + ap.alignFrame.featureSettings, isNucleotide) .fetchDBRefs(false); } diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index 6b2d3c4..afc93e0 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -164,6 +164,16 @@ public class Preferences extends GPreferences private WsPreferences wsPrefs; + private OptionsParam promptEachTimeOpt = new OptionsParam( + MessageManager.getString("label.prompt_each_time"), + "Prompt each time"); + + private OptionsParam lineArtOpt = new OptionsParam( + MessageManager.getString("label.lineart"), "Lineart"); + + private OptionsParam textOpt = new OptionsParam( + MessageManager.getString("action.text"), "Text"); + /** * Creates a new Preferences object. */ @@ -359,12 +369,23 @@ public class Preferences extends GPreferences /* * Set Output tab defaults */ - epsRendering - .addItem(MessageManager.getString("label.prompt_each_time")); - epsRendering.addItem(MessageManager.getString("label.lineart")); - epsRendering.addItem(MessageManager.getString("action.text")); - epsRendering.setSelectedItem(Cache.getDefault("EPS_RENDERING", - "Prompt each time")); + epsRendering.addItem(promptEachTimeOpt); + epsRendering.addItem(lineArtOpt); + epsRendering.addItem(textOpt); + String defaultEPS = Cache.getDefault("EPS_RENDERING", + "Prompt each time"); + if (defaultEPS.equalsIgnoreCase("Text")) + { + epsRendering.setSelectedItem(textOpt); + } + else if (defaultEPS.equalsIgnoreCase("Lineart")) + { + epsRendering.setSelectedItem(lineArtOpt); + } + else + { + epsRendering.setSelectedItem(promptEachTimeOpt); + } autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false)); userIdWidth.setEnabled(!autoIdWidth.isSelected()); userIdWidthlabel.setEnabled(!autoIdWidth.isSelected()); @@ -515,15 +536,8 @@ public class Preferences extends GPreferences /* * Save Output settings */ - if (epsRendering.getSelectedItem().equals("Prompt each time")) - { - Cache.applicationProperties.remove("EPS_RENDERING"); - } - else - { - Cache.applicationProperties.setProperty("EPS_RENDERING", epsRendering - .getSelectedItem().toString()); - } + Cache.applicationProperties.setProperty("EPS_RENDERING", + ((OptionsParam) epsRendering.getSelectedItem()).getCode()); /* * Save Connections settings @@ -983,4 +997,57 @@ public class Preferences extends GPreferences } } + public class OptionsParam + { + private String name; + + private String code; + + public OptionsParam(String name, String code) + { + this.name = name; + this.code = code; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getCode() + { + return code; + } + + public void setCode(String code) + { + this.code = code; + } + + @Override + public String toString() + { + return name; + } + + @Override + public boolean equals(Object that) + { + if (!(that instanceof OptionsParam)) + { + return false; + } + return this.code.equalsIgnoreCase(((OptionsParam) that).code); + } + + @Override + public int hashCode(){ + return name.hashCode() + code.hashCode(); + } + } } diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java index f2cbf33..2165b2c 100755 --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@ -43,17 +43,14 @@ import javax.swing.JPopupMenu; import javax.swing.ToolTipManager; /** - * DOCUMENT ME! - * - * @author $author$ - * @version $Revision$ + * The panel containing the sequence ruler (when not in wrapped mode), and + * supports a range of mouse operations to select, hide or reveal columns. */ public class ScalePanel extends JPanel implements MouseMotionListener, MouseListener { protected int offy = 4; - /** DOCUMENT ME!! */ public int width; protected AlignViewport av; @@ -62,13 +59,26 @@ public class ScalePanel extends JPanel implements MouseMotionListener, boolean stretchingGroup = false; - int min; // used by mouseDragged to see if user + /* + * min, max hold the extent of a mouse drag action + */ + int min; - int max; // used by mouseDragged to see if user + int max; boolean mouseDragging = false; - // wants to delete columns + /* + * holds a hidden column range when the mouse is over an adjacent column + */ + int[] reveal; + + /** + * Constructor + * + * @param av + * @param ap + */ public ScalePanel(AlignViewport av, AlignmentPanel ap) { this.av = av; @@ -393,6 +403,8 @@ public class ScalePanel extends JPanel implements MouseMotionListener, @Override public void mouseMoved(MouseEvent evt) { + this.setToolTipText(null); + reveal = null; if (!av.hasHiddenColumns()) { return; @@ -402,7 +414,6 @@ public class ScalePanel extends JPanel implements MouseMotionListener, res = av.getColumnSelection().adjustForHiddenColumns(res); - reveal = null; if (av.getColumnSelection().getHiddenColumns() != null) { for (int[] region : av.getColumnSelection().getHiddenColumns()) @@ -415,17 +426,11 @@ public class ScalePanel extends JPanel implements MouseMotionListener, .getString("label.reveal_hidden_columns")); break; } - else - { - this.setToolTipText(null); - } } } repaint(); } - int[] reveal; - /** * DOCUMENT ME! * diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 3fbb809..2d44a0f 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -1947,10 +1947,12 @@ public class SeqPanel extends JPanel implements MouseListener, // do we want to thread this ? (contention with seqsel and colsel locks, I // suspect) - // rules are: colsel is copied if there is a real intersection between - // sequence selection + /* + * only copy colsel if there is a real intersection between + * sequence selection and this panel's alignment + */ boolean repaint = false; - boolean copycolsel = true; + boolean copycolsel = false; SequenceGroup sgroup = null; if (seqsel != null && seqsel.getSize() > 0) @@ -1964,11 +1966,9 @@ public class SeqPanel extends JPanel implements MouseListener, } sgroup = seqsel.intersect(av.getAlignment(), (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null); - if ((sgroup == null || sgroup.getSize() == 0) - || (colsel == null || colsel.isEmpty())) + if ((sgroup != null && sgroup.getSize() > 0)) { - // don't copy columns if the region didn't intersect. - copycolsel = false; + copycolsel = true; } } if (sgroup != null && sgroup.getSize() > 0) @@ -2061,7 +2061,6 @@ public class SeqPanel extends JPanel implements MouseListener, ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv, av); av.setColumnSelection(cs); - av.isColSelChanged(true); PaintRefresher.Refresh(this, av.getSequenceSetId()); diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java index e567d20..71c8a39 100755 --- a/src/jalview/gui/SequenceFetcher.java +++ b/src/jalview/gui/SequenceFetcher.java @@ -407,6 +407,10 @@ public class SequenceFetcher extends JPanel implements Runnable this.add(jPanel2, java.awt.BorderLayout.NORTH); jScrollPane1.getViewport().add(textArea); + /* + * open the database tree + */ + database.waitForInput(); } private void pdbSourceAction() diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java index d924e73..46731e9 100644 --- a/src/jalview/gui/StructureChooser.java +++ b/src/jalview/gui/StructureChooser.java @@ -35,6 +35,7 @@ import jalview.fts.service.pdb.PDBFTSRestClient; import jalview.jbgui.GStructureChooser; import jalview.structure.StructureSelectionManager; import jalview.util.MessageManager; +import jalview.ws.DBRefFetcher; import jalview.ws.sifts.SiftsSettings; import java.awt.event.ItemEvent; @@ -800,6 +801,10 @@ public class StructureChooser extends GStructureChooser implements if (pdbEntry == null) { pdbEntry = new PDBEntry(); + if (pdbIdStr.split(":").length > 1) + { + pdbEntry.setChainCode(pdbIdStr.split(":")[1]); + } pdbEntry.setId(pdbIdStr); pdbEntry.setType(PDBEntry.Type.PDB); selectedSequence.getDatasetSequence().addPDBId(pdbEntry); @@ -860,31 +865,30 @@ public class StructureChooser extends GStructureChooser implements { ssm.setProgressBar(null); ssm.setProgressBar("Fetching Database refs.."); - new jalview.ws.DBRefFetcher(sequences, null, null, null, false) - .fetchDBRefs(true); + new DBRefFetcher(sequences).fetchDBRefs(true); break; } } } - if (pdbEntriesToView.length > 1) - { - ArrayList seqsMap = new ArrayList(); - for (SequenceI seq : sequences) - { - seqsMap.add(new SequenceI[] { seq }); - } - SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]); + if (pdbEntriesToView.length > 1) + { + ArrayList seqsMap = new ArrayList(); + for (SequenceI seq : sequences) + { + seqsMap.add(new SequenceI[] { seq }); + } + SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]); ssm.setProgressBar(null); ssm.setProgressBar("Fetching PDB Structures for selected entries.."); - sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel); - } - else - { + sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel); + } + else + { ssm.setProgressBar(null); ssm.setProgressBar("Fetching PDB Structure for " + pdbEntriesToView[0].getId()); - sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel); - } + sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel); + } } /** @@ -943,6 +947,9 @@ public class StructureChooser extends GStructureChooser implements isValidPBDEntry = false; if (txt_search.getText().length() > 0) { + String searchTerm = txt_search.getText().toLowerCase(); + searchTerm = searchTerm.split(":")[0]; + System.out.println(">>>>> search term : " + searchTerm); List wantedFields = new ArrayList(); FTSRestRequest pdbRequest = new FTSRestRequest(); pdbRequest.setAllowEmptySeq(false); @@ -950,7 +957,7 @@ public class StructureChooser extends GStructureChooser implements pdbRequest.setFieldToSearchBy("(pdb_id:"); pdbRequest.setWantedFields(wantedFields); pdbRequest - .setSearchTerm(txt_search.getText().toLowerCase() + ")"); +.setSearchTerm(searchTerm + ")"); pdbRequest.setAssociatedSequence(selectedSequence); pdbRestCleint = PDBFTSRestClient.getInstance(); wantedFields.add(pdbRestCleint.getPrimaryKeyColumn()); diff --git a/src/jalview/gui/TreePanel.java b/src/jalview/gui/TreePanel.java index 9522144..d78350d 100755 --- a/src/jalview/gui/TreePanel.java +++ b/src/jalview/gui/TreePanel.java @@ -161,6 +161,7 @@ public class TreePanel extends GTreePanel av.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("alignment")) @@ -196,6 +197,7 @@ public class TreePanel extends GTreePanel } + @Override public void viewMenu_menuSelected() { buildAssociatedViewMenu(); @@ -231,6 +233,7 @@ public class TreePanel extends GTreePanel buttonGroup.add(item); item.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent evt) { treeCanvas.applyToAllViews = false; @@ -249,6 +252,7 @@ public class TreePanel extends GTreePanel itemf.setSelected(treeCanvas.applyToAllViews); itemf.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent evt) { treeCanvas.applyToAllViews = itemf.isSelected(); @@ -276,6 +280,7 @@ public class TreePanel extends GTreePanel } } + @Override public void run() { @@ -389,6 +394,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void textbox_actionPerformed(ActionEvent e) { CutAndPasteTransfer cap = new CutAndPasteTransfer(); @@ -434,6 +440,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void saveAsNewick_actionPerformed(ActionEvent e) { JalviewFileChooser chooser = new JalviewFileChooser( @@ -474,12 +481,14 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void printMenu_actionPerformed(ActionEvent e) { // Putting in a thread avoids Swing painting problems treeCanvas.startPrinting(); } + @Override public void originalSeqData_actionPerformed(ActionEvent e) { if (!tree.hasOriginalSequenceData()) @@ -547,6 +556,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void fitToWindow_actionPerformed(ActionEvent e) { treeCanvas.fitToWindow = fitToWindow.isSelected(); @@ -637,6 +647,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void font_actionPerformed(ActionEvent e) { if (treeCanvas == null) @@ -666,6 +677,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void distanceMenu_actionPerformed(ActionEvent e) { treeCanvas.setShowDistances(distanceMenu.isSelected()); @@ -677,6 +689,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void bootstrapMenu_actionPerformed(ActionEvent e) { treeCanvas.setShowBootstrap(bootstrapMenu.isSelected()); @@ -688,6 +701,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void placeholdersMenu_actionPerformed(ActionEvent e) { treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected()); @@ -699,6 +713,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void epsTree_actionPerformed(ActionEvent e) { boolean accurateText = true; @@ -772,6 +787,7 @@ public class TreePanel extends GTreePanel * @param e * DOCUMENT ME! */ + @Override public void pngTree_actionPerformed(ActionEvent e) { int width = treeCanvas.getWidth(); @@ -828,6 +844,7 @@ public class TreePanel extends GTreePanel tree.applyToNodes(new NodeTransformI() { + @Override public void transform(BinaryNode node) { if (node instanceof SequenceNode diff --git a/src/jalview/io/HtmlSvgOutput.java b/src/jalview/io/HtmlSvgOutput.java index e554b8e..00af242 100644 --- a/src/jalview/io/HtmlSvgOutput.java +++ b/src/jalview/io/HtmlSvgOutput.java @@ -124,7 +124,7 @@ public class HtmlSvgOutput } } - if (renderStyle.equalsIgnoreCase("lineart")) + if (renderStyle.equalsIgnoreCase("Lineart")) { g1.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index c4c737c..25727d0 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -201,7 +201,7 @@ public class GPreferences extends JPanel /* * Output tab components */ - protected JComboBox epsRendering = new JComboBox(); + protected JComboBox epsRendering = new JComboBox(); protected JLabel userIdWidthlabel = new JLabel(); diff --git a/src/jalview/util/ImageMaker.java b/src/jalview/util/ImageMaker.java index b7aa4ca..72fa605 100755 --- a/src/jalview/util/ImageMaker.java +++ b/src/jalview/util/ImageMaker.java @@ -272,7 +272,7 @@ MessageManager.formatMessage( } } - if (renderStyle.equalsIgnoreCase("lineart")) + if (renderStyle.equalsIgnoreCase("Lineart")) { ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); diff --git a/src/jalview/util/Platform.java b/src/jalview/util/Platform.java index b812feb..786f5bf 100644 --- a/src/jalview/util/Platform.java +++ b/src/jalview/util/Platform.java @@ -20,6 +20,9 @@ */ package jalview.util; +import java.awt.Toolkit; +import java.awt.event.MouseEvent; + /** * System platform information used by Applet and Application * @@ -74,4 +77,11 @@ public class Platform f.append(file.substring(lastp)); return f.toString(); } + + public static boolean isControlDown(MouseEvent e) + { + return (jalview.util.Platform.isAMac() ? (Toolkit.getDefaultToolkit() + .getMenuShortcutKeyMask() & e.getModifiers()) != 0 : e + .isControlDown()); + } } diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index fbd1622..c16fdce 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -1078,6 +1078,7 @@ public abstract class AlignmentViewport implements AlignViewportI, { updateHiddenColumns(); } + isColSelChanged(true); } /** @@ -1206,8 +1207,7 @@ public abstract class AlignmentViewport implements AlignViewportI, */ public boolean isColSelChanged(boolean b) { - int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel - .hashCode(); + int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode(); if (hc != -1 && hc != colselhash) { if (b) @@ -1308,7 +1308,7 @@ public abstract class AlignmentViewport implements AlignViewportI, colSel.hideSelectedColumns(); setSelectionGroup(null); - + isColSelChanged(true); } public void hideColumns(int start, int end) @@ -1321,17 +1321,19 @@ public abstract class AlignmentViewport implements AlignViewportI, { colSel.hideColumns(start, end); } + isColSelChanged(true); } public void showColumn(int col) { colSel.revealHiddenColumns(col); - + isColSelChanged(true); } public void showAllHiddenColumns() { colSel.revealAllHiddenColumns(); + isColSelChanged(true); } // common hide/show seq stuff diff --git a/src/jalview/ws/DBRefFetcher.java b/src/jalview/ws/DBRefFetcher.java index 40c88c1..3ba0e34 100644 --- a/src/jalview/ws/DBRefFetcher.java +++ b/src/jalview/ws/DBRefFetcher.java @@ -141,7 +141,7 @@ public class DBRefFetcher implements Runnable String[] defdb = null, otherdb = sfetcher .getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class); List selsources = new ArrayList(); - Vector dasselsrc = (featureSettings != null) ? featureSettings + Vector dasselsrc = (featureSettings != null) ? featureSettings .getSelectedSources() : new jalview.gui.DasSourceBrowser() .getSelectedSources(); Enumeration en = dasselsrc.elements(); @@ -190,6 +190,16 @@ public class DBRefFetcher implements Runnable } /** + * Constructor with only sequences provided + * + * @param sequences + */ + public DBRefFetcher(SequenceI[] sequences) + { + this(sequences, null, null, null, false); + } + + /** * Add a listener to be notified when sequence fetching is complete * * @param l diff --git a/src/jalview/ws/DasSequenceFeatureFetcher.java b/src/jalview/ws/DasSequenceFeatureFetcher.java index d7ba24d..5f9b2d9 100644 --- a/src/jalview/ws/DasSequenceFeatureFetcher.java +++ b/src/jalview/ws/DasSequenceFeatureFetcher.java @@ -22,11 +22,13 @@ package jalview.ws; import jalview.bin.Cache; import jalview.datamodel.DBRefEntry; +import jalview.datamodel.DBRefSource; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.Desktop; import jalview.gui.FeatureSettings; +import jalview.util.DBRefUtils; import jalview.util.MessageManager; import jalview.util.UrlLink; import jalview.ws.dbsources.das.api.DasSourceRegistryI; @@ -186,8 +188,7 @@ public class DasSequenceFeatureFetcher { for (int j = 0; j < dbref.length; j++) { - if (dbref[j].getSource().equals( - jalview.datamodel.DBRefSource.UNIPROT)) + if (dbref[j].getSource().equals(DBRefSource.UNIPROT)) { refCount++; break; @@ -252,10 +253,10 @@ public class DasSequenceFeatureFetcher public void run() { running = true; - boolean isNuclueotide = af.getViewport().getAlignment() + boolean isNucleotide = af.getViewport().getAlignment() .isNucleotide(); - new jalview.ws.DBRefFetcher(sequences, af, null, af.featureSettings, - isNuclueotide).fetchDBRefs(true); + new DBRefFetcher(sequences, af, null, af.featureSettings, + isNucleotide).fetchDBRefs(true); startFetching(); setGuiFetchComplete(); @@ -286,7 +287,7 @@ public class DasSequenceFeatureFetcher { jalviewSourceI[] sources = sourceRegistry.getSources().toArray( new jalviewSourceI[0]); - String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE", + String active = Cache.getDefault("DAS_ACTIVE_SOURCE", "uniprot"); StringTokenizer st = new StringTokenizer(active, "\t"); selectedSources = new Vector(); @@ -643,10 +644,10 @@ public class DasSequenceFeatureFetcher { return null; } - DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs( + DBRefEntry[] uprefs = DBRefUtils.selectRefs( seq.getDBRefs(), new String[] { // jalview.datamodel.DBRefSource.PDB, - jalview.datamodel.DBRefSource.UNIPROT, + DBRefSource.UNIPROT, // jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord // sys sources }); @@ -665,7 +666,7 @@ public class DasSequenceFeatureFetcher for (COORDINATES csys : dasSource.getVersion().getCOORDINATES()) { - if (jalview.util.DBRefUtils.isDasCoordinateSystem( + if (DBRefUtils.isDasCoordinateSystem( csys.getAuthority(), uprefs[j])) { debug("Launched fetcher for coordinate system " diff --git a/src/jalview/ws/dbsources/Pdb.java b/src/jalview/ws/dbsources/Pdb.java index 0d590b0..c87a111 100644 --- a/src/jalview/ws/dbsources/Pdb.java +++ b/src/jalview/ws/dbsources/Pdb.java @@ -1,3 +1,4 @@ + /* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors @@ -53,7 +54,7 @@ public class Pdb extends EbiFileRetrievedProxy public static final String FEATURE_RES_NUM = "RESNUM"; - private static String currentDefaultFomart = DBRefSource.PDB; + private static String currentDefaultFormat = DBRefSource.PDB; /* * (non-Javadoc) @@ -132,11 +133,11 @@ public class Pdb extends EbiFileRetrievedProxy stopQuery(); return null; } - String ext = getCurrentDefaultFomart().equalsIgnoreCase("mmcif") ? ".cif" + String ext = getCurrentDefaultFormat().equalsIgnoreCase("mmcif") ? ".cif" : ".xml"; EBIFetchClient ebi = new EBIFetchClient(); file = ebi.fetchDataAsFile("pdb:" + id, - getCurrentDefaultFomart().toLowerCase(), ext) + getCurrentDefaultFormat().toLowerCase(), ext) .getAbsolutePath(); stopQuery(); if (file == null) @@ -148,7 +149,7 @@ public class Pdb extends EbiFileRetrievedProxy pdbAlignment = new FormatAdapter().readFile(file, jalview.io.AppletFormatAdapter.FILE, - getCurrentDefaultFomart()); + getCurrentDefaultFormat()); if (pdbAlignment != null) { List toremove = new ArrayList(); @@ -263,14 +264,14 @@ public class Pdb extends EbiFileRetrievedProxy return 0; } - public static String getCurrentDefaultFomart() + public static String getCurrentDefaultFormat() { - return currentDefaultFomart; + return currentDefaultFormat; } - public static void setCurrentDefaultFomart(String currentDefaultFomart) + public static void setCurrentDefaultFormat(String currentDefaultFomart) { - Pdb.currentDefaultFomart = currentDefaultFomart; + Pdb.currentDefaultFormat = currentDefaultFomart; } /** diff --git a/test/jalview/datamodel/ColumnSelectionTest.java b/test/jalview/datamodel/ColumnSelectionTest.java index 86e7949..1a7ae32 100644 --- a/test/jalview/datamodel/ColumnSelectionTest.java +++ b/test/jalview/datamodel/ColumnSelectionTest.java @@ -478,4 +478,53 @@ public class ColumnSelectionTest cs.addElement(0); assertEquals(0, cs.getMin()); } + + @Test(groups = { "Functional" }) + public void testEquals() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(0); + cs.addElement(513); + cs.addElement(1); + cs.hideColumns(3); + cs.hideColumns(7); + cs.hideColumns(5,9); + + // same selections added in a different order + ColumnSelection cs2 = new ColumnSelection(); + cs2.addElement(1); + cs2.addElement(513); + cs2.addElement(0); + + // with no hidden columns + assertFalse(cs.equals(cs2)); + assertFalse(cs2.equals(cs)); + + // with hidden columns added in a different order + cs2.hideColumns(6, 9); + cs2.hideColumns(5, 8); + cs2.hideColumns(3); + + assertTrue(cs.equals(cs2)); + assertTrue(cs.equals(cs)); + assertTrue(cs2.equals(cs)); + assertTrue(cs2.equals(cs2)); + + cs2.addElement(12); + assertFalse(cs.equals(cs2)); + assertFalse(cs2.equals(cs)); + + cs2.removeElement(12); + assertTrue(cs.equals(cs2)); + + cs2.hideColumns(88); + assertFalse(cs.equals(cs2)); + /* + * unhiding a column adds it to selection! + */ + cs2.revealHiddenColumns(88); + assertFalse(cs.equals(cs2)); + cs.addElement(88); + assertTrue(cs.equals(cs2)); + } } diff --git a/test/jalview/io/FeaturesFileTest.java b/test/jalview/io/FeaturesFileTest.java index 81d5b05..29bd567 100644 --- a/test/jalview/io/FeaturesFileTest.java +++ b/test/jalview/io/FeaturesFileTest.java @@ -76,53 +76,63 @@ public class FeaturesFileTest */ SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence() .getSequenceFeatures(); // FER_CAPAA - assertEquals(7, sfs.length); + assertEquals(8, sfs.length); SequenceFeature sf = sfs[0]; + assertEquals("Pfam family%LINK%", sf.description); + assertEquals(0, sf.begin); + assertEquals(0, sf.end); + assertEquals("uniprot", sf.featureGroup); + assertEquals("Pfam", sf.type); + assertEquals(1, sf.links.size()); + assertEquals("Pfam family|http://pfam.xfam.org/family/PF00111", + sf.links.get(0)); + + sf = sfs[1]; assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(39, sf.begin); assertEquals(39, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[1]; + sf = sfs[2]; assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(44, sf.begin); assertEquals(44, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[2]; + sf = sfs[3]; assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(47, sf.begin); assertEquals(47, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[3]; + sf = sfs[4]; assertEquals("Iron-sulfur (2Fe-2S)", sf.description); assertEquals(77, sf.begin); assertEquals(77, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("METAL", sf.type); - sf = sfs[4]; + sf = sfs[5]; assertEquals("Fer2 Status: True Positive Pfam 8_8%LINK%", sf.description); - assertEquals("Pfam 8_8|http://pfam.sanger.ac.uk/family/PF00111", - sf.links.get(0).toString()); + assertEquals("Pfam 8_8|http://pfam.xfam.org/family/PF00111", + sf.links.get(0)); assertEquals(8, sf.begin); assertEquals(83, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("Pfam", sf.type); - sf = sfs[5]; + sf = sfs[6]; assertEquals("Ferredoxin_fold Status: True Positive ", sf.description); assertEquals(3, sf.begin); assertEquals(93, sf.end); assertEquals("uniprot", sf.featureGroup); assertEquals("Cath", sf.type); - sf = sfs[6]; + sf = sfs[7]; assertEquals( "High confidence server. Only hits with scores over 0.8 are reported. PHOSPHORYLATION (T) 89_8%LINK%", sf.description); assertEquals( "PHOSPHORYLATION (T) 89_8|http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P83527&service=NetPhos-2.0", - sf.links.get(0).toString()); + sf.links.get(0)); assertEquals(89, sf.begin); assertEquals(89, sf.end); assertEquals("netphos", sf.featureGroup); @@ -428,7 +438,7 @@ public class FeaturesFileTest + "STARTGROUP\tuniprot\n" + "Iron\tFER_CAPAA\t-1\t39\t39\tMETAL\n" + "Turn\tFER_CAPAA\t-1\t36\t38\tGAMMA-TURN\n" - + "Pfam domainPfam_3_4\tFER_CAPAA\t-1\t20\t20\tPfam\n" + + "Pfam domainPfam_3_4\tFER_CAPAA\t-1\t20\t20\tPfam\n" + "ENDGROUP\tuniprot\n"; FeaturesFile featuresFile = new FeaturesFile(features, FormatAdapter.PASTE); @@ -478,7 +488,7 @@ public class FeaturesFileTest + "\nSTARTGROUP\tuniprot\n" + "Iron\tFER_CAPAA\t-1\t39\t39\tMETAL\t0.0\n" + "Turn\tFER_CAPAA\t-1\t36\t38\tGAMMA-TURN\t0.0\n" - + "Pfam domainPfam_3_4\tFER_CAPAA\t-1\t20\t20\tPfam\t0.0\n" + + "Pfam domainPfam_3_4\tFER_CAPAA\t-1\t20\t20\tPfam\t0.0\n" + "ENDGROUP\tuniprot\n"; assertEquals(expected, exported); } diff --git a/utils/HelpLinksChecker.java b/utils/HelpLinksChecker.java new file mode 100644 index 0000000..1f666a4 --- /dev/null +++ b/utils/HelpLinksChecker.java @@ -0,0 +1,491 @@ + + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +/** + * A class to check help file cross-references, and external URLs if internet + * access is available + * + * @author gmcarstairs + * + */ +public class HelpLinksChecker +{ + private static final String HELP_HS = "help.hs"; + + private static final String HELP_TOC_XML = "helpTOC.xml"; + + private static final String HELP_JHM = "help.jhm"; + + private static boolean internetAvailable = true; + + private int targetCount = 0; + + private int mapCount = 0; + + private int internalHrefCount = 0; + + private int anchorRefCount = 0; + + private int externalHrefCount = 0; + + private int invalidMapUrlCount = 0; + + private int invalidTargetCount = 0; + + private int invalidImageCount = 0; + + private int invalidInternalHrefCount = 0; + + private int invalidExternalHrefCount = 0; + + /** + * The only parameter should be a path to the root of the help directory in + * the workspace + * + * @param args + * [0] path to the /html folder in the workspace + * @param args + * [1] (optional) -nointernet to suppress external link checking for + * a fast check of internal links only + * @throws IOException + */ + public static void main(String[] args) throws IOException + { + if (args.length == 0 || args.length > 2 + || (args.length == 2 && !args[1].equals("-nointernet"))) + { + System.out.println("Usage: [-nointernet]"); + return; + } + + if (args.length == 2) + { + internetAvailable = false; + } + + new HelpLinksChecker().checkLinks(args[0]); + } + + /** + * Checks help links and reports results + * + * @param helpDirectoryPath + * @throws IOException + */ + void checkLinks(String helpDirectoryPath) throws IOException + { + System.out.println("Checking help file links"); + File helpFolder = new File(helpDirectoryPath); + if (!helpFolder.exists()) + { + System.out.println("Can't find " + helpDirectoryPath); + return; + } + + internetAvailable &= connectToUrl("http://www.example.com"); + + Map tocTargets = checkHelpMappings(helpFolder); + + Map unusedTargets = new HashMap( + tocTargets); + + checkTableOfContents(helpFolder, tocTargets, unusedTargets); + + checkHelpSet(helpFolder, tocTargets, unusedTargets); + + checkHtmlFolder(new File(helpFolder, "html")); + + reportResults(unusedTargets); + } + + /** + * Checks all html files in the given directory or its sub-directories + * + * @param folder + * @throws IOException + */ + private void checkHtmlFolder(File folder) throws IOException + { + File[] files = folder.listFiles(); + for (File f : files) + { + if (f.isDirectory()) + { + checkHtmlFolder(f); + } + else + { + if (f.getAbsolutePath().endsWith(".html")) + { + checkHtmlFile(f, folder); + } + } + } + } + + /** + * Checks that any image attribute in help.hs is a valid target + * + * @param helpFolder + * @param tocTargets + * @param unusedTargets + * used targets are removed from here + */ + private void checkHelpSet(File helpFolder, + Map tocTargets, Map unusedTargets) + throws IOException + { + BufferedReader br = new BufferedReader(new FileReader(new File( + helpFolder, HELP_HS))); + String data = br.readLine(); + int lineNo = 0; + + while (data != null) + { + lineNo++; + String image = getAttribute(data, "image"); + if (image != null) + { + unusedTargets.remove(image); + if (!tocTargets.containsKey(image)) + { + System.out.println(String.format( + "Invalid image '%s' at line %d of %s", image, lineNo, + HELP_HS)); + invalidImageCount++; + } + } + data = br.readLine(); + } + br.close(); + } + + /** + * Print counts to sysout + * + * @param unusedTargets + */ + private void reportResults(Map unusedTargets) + { + System.out.println("\nResults:"); + System.out.println(targetCount + " distinct help targets"); + System.out.println(mapCount + " help mappings"); + System.out.println(invalidTargetCount + " invalid targets"); + System.out.println(unusedTargets.size() + " unused targets"); + for (String target : unusedTargets.keySet()) + { + System.out.println(String.format(" %s: %s", target, + unusedTargets.get(target))); + } + System.out.println(invalidMapUrlCount + " invalid map urls"); + System.out.println(invalidImageCount + " invalid image attributes"); + System.out.println(String.format( + "%d internal href links (%d with anchors - not checked)", + internalHrefCount, anchorRefCount)); + System.out.println(invalidInternalHrefCount + + " invalid internal href links"); + System.out.println(externalHrefCount + " external href links"); + if (internetAvailable) + { + System.out.println(invalidExternalHrefCount + + " invalid external href links"); + } + else + { + System.out + .println("External links not verified as internet not available"); + } + + } + + /** + * Reads the given html file and checks any href attibute values are either + *
            + *
          • a valid relative file path, or
          • + *
          • a valid absolute URL (if external link checking is enabled)
          • + *
          + * + * @param htmlFile + * @param htmlFolder + * the parent folder (for validation of relative paths) + */ + private void checkHtmlFile(File htmlFile, File htmlFolder) + throws IOException + { + BufferedReader br = new BufferedReader(new FileReader(htmlFile)); + String data = br.readLine(); + int lineNo = 0; + while (data != null) + { + lineNo++; + String href = getAttribute(data, "href"); + if (href != null) + { + String anchor = null; + int anchorPos = href.indexOf("#"); + if (anchorPos != -1) + { + anchor = href.substring(anchorPos + 1); + href = href.substring(0, anchorPos); + } + boolean badLink = false; + if (href.startsWith("http")) + { + externalHrefCount++; + if (internetAvailable) + { + if (!connectToUrl(href)) + { + badLink = true; + invalidExternalHrefCount++; + } + } + } + else + { + internalHrefCount++; + File hrefFile = href.equals("") ? htmlFile : new File(htmlFolder, + href); + if (!hrefFile.exists()) + { + badLink = true; + invalidInternalHrefCount++; + } + if (anchor != null) + { + anchorRefCount++; + if (!badLink) + { + if (!checkAnchorExists(hrefFile, anchor)) + { + System.out.println(String.format( + "Invalid anchor: %s at line %d of %s", anchor, + lineNo, getPath(htmlFile))); + } + } + } + } + if (badLink) + { + System.out.println(String.format( + "Invalid href %s at line %d of %s", href, lineNo, + getPath(htmlFile))); + } + } + data = br.readLine(); + } + br.close(); + } + + /** + * Reads the file and checks for the presence of the given html anchor + * + * @param hrefFile + * @param anchor + * @return true if anchor is found else false + */ + private boolean checkAnchorExists(File hrefFile, String anchor) + { + String nameAnchor = " + *
        • each target attribute is in tocTargets
        • + *
        • each url attribute is a valid relative file link
        • + * + * + * @param helpFolder + */ + private Map checkHelpMappings(File helpFolder) + throws IOException + { + Map targets = new HashMap(); + BufferedReader br = new BufferedReader(new FileReader(new File( + helpFolder, HELP_JHM))); + String data = br.readLine(); + int lineNo = 0; + while (data != null) + { + lineNo++; + + /* + * record target, check for duplicates + */ + String target = getAttribute(data, "target"); + if (target != null) + { + mapCount++; + if (targets.containsKey(target)) + { + System.out.println(String.format( + "Duplicate target mapping to %s at line %d of %s", + target, lineNo, HELP_JHM)); + } + else + { + targetCount++; + } + } + + /* + * validate url + */ + String url = getAttribute(data, "url"); + if (url != null) + { + targets.put(target, url); + int anchorPos = url.indexOf("#"); + if (anchorPos != -1) + { + url = url.substring(0, anchorPos); + } + if (!new File(helpFolder, url).exists()) + { + System.out.println(String.format( + "Invalid url path '%s' at line %d of %s", url, lineNo, + HELP_JHM)); + invalidMapUrlCount++; + } + } + data = br.readLine(); + } + br.close(); + return targets; + } + + /** + * Reads file helpTOC.xml and reports any invalid targets + * + * @param helpFolder + * @param tocTargets + * @param unusedTargets + * used targets are removed from this map + * + * @return + * @throws IOException + */ + private void checkTableOfContents(File helpFolder, + Map tocTargets, Map unusedTargets) + throws IOException + { + BufferedReader br = new BufferedReader(new FileReader(new File( + helpFolder, HELP_TOC_XML))); + String data = br.readLine(); + int lineNo = 0; + while (data != null) + { + lineNo++; + /* + * assuming no more than one "target" per line of file here + */ + String target = getAttribute(data, "target"); + if (target != null) + { + unusedTargets.remove(target); + if (!tocTargets.containsKey(target)) + { + System.out.println(String.format( + "Invalid target '%s' at line %d of %s", target, lineNo, + HELP_TOC_XML)); + invalidTargetCount++; + } + } + data = br.readLine(); + } + br.close(); + } + + /** + * Returns the value of an attribute if found in the data, else null + * + * @param data + * @param attName + * @return + */ + private static String getAttribute(String data, String attName) + { + /* + * make a partial attempt at ignoring within + * (doesn't work if multi-line) + */ + int commentStartPos = data.indexOf(""); + String value = null; + String match = attName + "=\""; + int attPos = data.indexOf(match); + if (attPos > 0 + && (commentStartPos == -1 || attPos < commentStartPos || attPos > commentEndPos)) + { + data = data.substring(attPos + match.length()); + value = data.substring(0, data.indexOf("\"")); + } + return value; + } +} diff --git a/utils/InstallAnywhere/Jalview.iap_xml b/utils/InstallAnywhere/Jalview.iap_xml index 428b998..fc799bb 100755 --- a/utils/InstallAnywhere/Jalview.iap_xml +++ b/utils/InstallAnywhere/Jalview.iap_xml @@ -2891,6 +2891,58 @@ and any path to a file to save to the file]]>
          + + + + false + + + true + + + true + + + + + + + + + + + + false + + + + + + true + + + true + + + true + + + + + + 16046 + + + false + + + 0 + + + + + +
          @@ -7360,6 +7412,7 @@ and any path to a file to read from that file]]>
          + @@ -7948,6 +8001,7 @@ and any path to a file to read from that file]]> +