From: gmungoc Date: Wed, 30 May 2018 11:23:18 +0000 (+0100) Subject: Update spike branch to latest (HMMSearch file chooser arg) X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=ac4a041c0706baca6fd04570bf37e8264457ea86;p=jalview.git Update spike branch to latest (HMMSearch file chooser arg) --- diff --git a/RELEASE b/RELEASE index 5ad87c8..c61d86c 100644 --- a/RELEASE +++ b/RELEASE @@ -1,2 +1,2 @@ jalview.release=releases/Release_2_10_4_Branch -jalview.version=2.10.4 +jalview.version=2.10.4b1 diff --git a/THIRDPARTYLIBS b/THIRDPARTYLIBS index e2baa85..d0d9125 100644 --- a/THIRDPARTYLIBS +++ b/THIRDPARTYLIBS @@ -9,6 +9,7 @@ ext.edu.ucsf.rbvi.strucviz2 includes sources originally developed by Scooter Mor jalview.ext.android includes code taken from the Android Open Source Project (https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util). The Apache 2.0 Licence (http://www.apache.org/licenses/LICENSE-2.0) is acknowledged in the source code. + org.stackoverflowusers.file.WindowsShortcuts was downloaded from http://github.com/codebling/WindowsShortcuts via https://stackoverflow.com/questions/309495/windows-shortcut-lnk-parser-in-java Licensing information for each library is given below: diff --git a/build.xml b/build.xml index 3bacc1c..d826d83 100755 --- a/build.xml +++ b/build.xml @@ -308,6 +308,13 @@ + + + + + + + diff --git a/examples/testdata/test.aln b/examples/testdata/test.aln index 08a7ac3..6582b12 100644 --- a/examples/testdata/test.aln +++ b/examples/testdata/test.aln @@ -1,53 +1,13 @@ CLUSTAL -FER_CAPAA/1-97 -----------------------------------------------------------A -FER_CAPAN/1-144 MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMA -FER1_SOLLC/1-144 MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA -Q93XJ9_SOLTU/1-144 MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA -FER1_PEA/1-149 MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMA -Q7XA98_TRIPR/1-152 MATT---PALYGTAVSTSFMRRQPVPMSV-ATTTTTKAFPSGFGLKSVSTKRGDLAVAMA -FER1_MESCR/1-148 MAAT--TAALSGATMSTAFAPK--TPPMTAALPTNVGR--ALFGLKS-SASR-GRVTAMA -FER1_SPIOL/1-147 MAAT--TTTMMG--MATTFVPKPQAPPMMAALPSNTGR--SLFGLKT-GSR--GGRMTMA -FER3_RAPSA/1-96 -----------------------------------------------------------A -FER1_ARATH/1-148 MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMA -FER_BRANA/1-96 -----------------------------------------------------------A -FER2_ARATH/1-148 MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMA -Q93Z60_ARATH/1-118 MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMA -FER1_MAIZE/1-150 MATVLGSPRAPAFFFSSSSLRAAPAPTAV--ALPAAKV--GIMGRSA-SSRR--RLRAQA -O80429_MAIZE/1-140 MAAT---------ALSMSILR---APPPCFSSPLRLRV--AVAKPLA-APMRRQLLRAQA -1A70|/1-97 -----------------------------------------------------------A - -FER_CAPAA/1-97 SYKVKLITPDGPIEFDCPDDVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDG -FER_CAPAN/1-144 SYKVKLITPDGPIEFDCPDNVYILDQAEEAGHDLPYSCRAGSCSSCAGKIAGGAVDQTDG -FER1_SOLLC/1-144 SYKVKLITPEGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGSVDQSDG -Q93XJ9_SOLTU/1-144 SYKVKLITPDGPIEFECPDDVYILDQAEEEGHDLPYSCRAGSCSSCAGKVTAGTVDQSDG -FER1_PEA/1-149 SYKVKLVTPDGTQEFECPSDVYILDHAEEVGIDLPYSCRAGSCSSCAGKVVGGEVDQSDG -Q7XA98_TRIPR/1-152 TYKVKLITPEGPQEFDCPDDVYILDHAEEVGIELPYSCRAGSCSSCAGKVVNGNVNQEDG -FER1_MESCR/1-148 AYKVTLVTPEGKQELECPDDVYILDAAEEAGIDLPYSCRAGSCSSCAGKVTSGSVNQDDG -FER1_SPIOL/1-147 AYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQ -FER3_RAPSA/1-96 TYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQ -FER1_ARATH/1-148 TYKVKFITPEGELEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQ -FER_BRANA/1-96 TYKVKFITPEGEQEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDE -FER2_ARATH/1-148 TYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQ -Q93Z60_ARATH/1-118 TYKVKFITPEGEQEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQ -FER1_MAIZE/1-150 TYNVKLITPEGEVELQVPDDVYILDQAEEDGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQ -O80429_MAIZE/1-140 TYNVKLITPEGEVELQVPDDVYILDFAEEEGIDLPFSCRAGSCSSCAGKVVSGSVDQSDQ -1A70|/1-97 AYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQ - -FER_CAPAA/1-97 NFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG- -FER_CAPAN/1-144 NFLDDDQLEEGWVLTCVAYPQSDVTIETHKEAELVG- -FER1_SOLLC/1-144 NFLDEDQEAAGFVLTCVAYPKGDVTIETHKEEELTA- -Q93XJ9_SOLTU/1-144 KFLDDDQEAAGFVLTCVAYPKCDVTIETHKEEELTA- -FER1_PEA/1-149 SFLDDEQIEAGFVLTCVAYPTSDVVIETHKEEDLTA- -Q7XA98_TRIPR/1-152 SFLDDEQIEGGWVLTCVAFPTSDVTIETHKEEELTA- -FER1_MESCR/1-148 SFLDDDQIKEGWVLTCVAYPTGDVTIETHKEEELTA- -FER1_SPIOL/1-147 SFLDDDQIDEGWVLTCAAYPVSDVTIETHKEEELTA- -FER3_RAPSA/1-96 SFLDDDQIAEGFVLTCAAYPTSDVTIETHREEDMV-- -FER1_ARATH/1-148 SFLDDEQIGEGFVLTCAAYPTSDVTIETHKEEDIV-- -FER_BRANA/1-96 SFLDDDQIAEGFVLTCAAYPTSDVTIETHKEEELV-- -FER2_ARATH/1-148 SFLDDEQMSEGYVLTCVAYPTSDVVIETHKEEAIM-- -Q93Z60_ARATH/1-118 SFLDD-------------------------------- -FER1_MAIZE/1-150 SYLDDGQIADGWVLTCHAYPTSDVVIETHKEEELTGA -O80429_MAIZE/1-140 SFLNDNQVADGWVLTCAAYPTSDVVIETHKEDDLL-- -1A70|/1-97 SFLDDDQIDEGWVLTCAAYPVSDVTIETHKKEELTA - +FER_CAPAA/1-97 -----------------------------------------------------------A 1 +FER_CAPAN/1-144 MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMA 48 +FER1_SOLLC/1-144 MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA 48 +Q93XJ9_SOLTU/1-144 MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA 48 +FER1_PEA/1-149 MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMA 53 + +FER_CAPAA/1-97 SYKVKLI 8 +FER_CAPAN/1-144 SYKVKLI 55 +FER1_SOLLC/1-144 SYKVKLI 55 +Q93XJ9_SOLTU/1-144 SYKVKLI 55 +FER1_PEA/1-149 SYKVKLV 60 diff --git a/help/help.jhm b/help/help.jhm index 4ea119c..6239272 100755 --- a/help/help.jhm +++ b/help/help.jhm @@ -22,7 +22,7 @@ - + diff --git a/help/html/releases.html b/help/html/releases.html index dd2bb62..3c1d73c 100755 --- a/help/html/releases.html +++ b/help/html/releases.html @@ -70,7 +70,53 @@ li:before {
- 2.10.4
8/05/2018
+ 2.10.4b1
+ 27/05/2018
+
+ +
+ +
    +
  • + Windows File Shortcuts can be dragged + onto the Jalview Desktop +
  • +
+
+
+ +
    +
  • + Clustal files with sequence positions in + right-hand column parsed correctly +
  • +
  • + F2/Keyboard mode edits work when Overview + window has input focus +
  • +
  • + Wrap view - export to SVG - IDs shown but + not alignment area in exported graphic +
  • +
  • + Drag URL from chrome, firefox, IE to + Jalview desktop on Windows doesn't open file
    + Dragging the currently open URL and links from a page viewed in Firefox or Chrome on + Windows is now fully supported. If you are using Edge, only + links in the page can be dragged, and with Internet Explorer, only + the currently open URL in the browser can be dropped onto + Jalview. +
  • +
  • + +
  • +
+
+ + + +
+ 2.10.4
10/05/2018
@@ -112,14 +158,23 @@ li:before { overlapping alignment panel
  • - overview doesn't show end of unpadded + Overview doesn't show end of unpadded sequence as gaps
  • - Cross-reference handling improved: CDS not handled correctly if transcript has no UTR + Cross-reference handling + improved: CDS not handled correctly if transcript has no + UTR
  • - + Secondary structure and temperature + factor annotation not added to sequence when local PDB + file associated with it by drag'n'drop or structure + chooser +
  • +
  • + Answering 'No' to PDB Autoassociate + dialog doesn't import PDB files dropped on an alignment
  • Linked scrolling via protein horizontal @@ -134,8 +189,8 @@ li:before { columns in annotation row
  • - Preferences panel's ID Width control is - honored in interactive and batch mode + Preferences panel's ID Width control is not + honored in batch mode
  • Linked sequence highlighting doesn't work @@ -156,6 +211,10 @@ li:before { as generated by CONSURF)
  • + Uniprot 'sequence variant' features + tooltip doesn't include a text description of mutation +
  • +
  • Invert displayed features very slow when structure and/or overview windows are also shown
  • diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index db3dbf8..c25cda8 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -269,6 +269,7 @@ label.use_rnaview = Use RNAView for secondary structure label.autoadd_secstr = Add secondary structure annotation to alignment label.autoadd_temp = Add Temperature Factor annotation to alignment label.structure_viewer = Default structure viewer +label.double_click_to_browse = Double-click to browse for file label.chimera_path = Path to Chimera program label.chimera_path_tip = Jalview will first try any path entered here, else standard installation locations.
    Double-click to browse for file. label.invalid_chimera_path = Chimera path not found or not executable @@ -1420,3 +1421,4 @@ label.groups_and_alignment = All groups and alignment label.groups = All groups label.selected_group = Selected group label.use_info_for_height = Use Information Content as Letter Height +action.search = Search \ No newline at end of file diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 0144522..eb217bd 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -1177,6 +1177,7 @@ action.select_by_annotation=Seleccionar/Ocultar Columnas por Anotaci action.export_features=Exportar Características error.invalid_regex=Expresión regular inválida label.autoadd_temp=Añadir anotación factor de temperatura al alineamiento +label.double_click_to_browse = Haga doble clic para buscar fichero label.chimera_path_tip=Jalview intentará primero las rutas introducidas aquí, Y si no las rutas usuales de instalación label.structure_chooser=Selector de Estructuras label.structure_chooser_manual_association=Selector de Estructuras - asociación manual @@ -1223,13 +1224,13 @@ exception.resource_not_be_found=El recurso solicitado no se ha encontrado label.aacon_calculations=cálculos AACon label.pdb_web-service_error=Error de servicio web PDB exception.unable_to_detect_internet_connection=Jalview no puede detectar una conexión a Internet -label.chimera_path=Ruta de acceso a programa Chimera +label.chimera_path=Ruta de acceso a Chimera warn.delete_all=Borrar todas las secuencias cerrará la ventana del alineamiento.
    Confirmar o Cancelar. label.select_all=Seleccionar Todos label.alpha_helix=Hélice Alfa label.chimera_help=Ayuda para Chimera label.find_tip=Buscar alineamiento, selección o IDs de secuencia para una subsecuencia (sin huecos) -label.structure_viewer=Visualizador de estructura por defecto +label.structure_viewer=Visualizador por defecto label.embbed_biojson=Incrustar BioJSON al exportar HTML label.transparency_tip=Ajustar la transparencia a "ver a través" los colores de las características. label.choose_annotations=Escoja anotaciones @@ -1361,3 +1362,4 @@ label.most_bound_molecules = M label.most_polymer_residues = Más Residuos de Polímeros label.cached_structures = Estructuras en Caché label.free_text_search = Búsqueda de texto libre +action.search = Buscar \ No newline at end of file diff --git a/resources/uniprot_mapping.xml b/resources/uniprot_mapping.xml index 6344d1e..832d3e5 100755 --- a/resources/uniprot_mapping.xml +++ b/resources/uniprot_mapping.xml @@ -62,13 +62,19 @@ - + - - - - + + + + + + + + + + diff --git a/src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java b/src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java index effe556..b90a5a1 100644 --- a/src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java +++ b/src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java @@ -34,6 +34,7 @@ package ext.edu.ucsf.rbvi.strucviz2; import jalview.bin.Cache; import jalview.gui.Preferences; +import jalview.util.FileUtils; import java.io.File; import java.io.IOException; @@ -97,7 +98,7 @@ public class StructureManager this.haveGUI = haveGUI; // Create the Chimera interface chimeraManager = new ChimeraManager(this); - chimSelectionList = new ArrayList(); + chimSelectionList = new ArrayList<>(); pathProps = new Properties(); } @@ -110,7 +111,7 @@ public class StructureManager ModelType type) { // new models - Map> newModels = new HashMap>(); + Map> newModels = new HashMap<>(); if (chimObjNames.size() > 0) { List names = chimObjNames.iterator().next(); @@ -846,7 +847,7 @@ public class StructureManager // alDialog.dispose(); // } // System.out.println("launch align dialog"); - List chimObjectList = new ArrayList(); + List chimObjectList = new ArrayList<>(); for (ChimeraModel model : chimeraManager.getChimeraModels()) { if (useChains) @@ -887,7 +888,7 @@ public class StructureManager public List getAllChimeraResidueAttributes() { - List attributes = new ArrayList(); + List attributes = new ArrayList<>(); // attributes.addAll(rinManager.getResAttrs()); attributes.addAll(chimeraManager.getAttrList()); return attributes; @@ -898,7 +899,7 @@ public class StructureManager // TODO: [Optional] Change priority of Chimera paths public static List getChimeraPaths() { - List pathList = new ArrayList(); + List pathList = new ArrayList<>(); // if no network is available and the settings have been modified by the // user, check for a @@ -934,8 +935,16 @@ public class StructureManager } else if (os.startsWith("Windows")) { - pathList.add("\\Program Files\\Chimera\\bin\\chimera"); - pathList.add("C:\\Program Files\\Chimera\\bin\\chimera.exe"); + /* + * typical Windows installation path is + * C:\Program Files\Chimera 1.12\bin\chimera.exe + */ + // current drive: + pathList.addAll(FileUtils.findMatches("\\", + "Program Files*/Chimera*/bin/{chimera,chimera.exe}")); + // C: drive (note may add as duplicates) + pathList.addAll(FileUtils.findMatches("C:\\", + "Program Files*/Chimera*/bin/{chimera,chimera.exe}")); } else if (os.startsWith("Mac")) { diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java index e66b7ae..4c1e848 100755 --- a/src/jalview/bin/Jalview.java +++ b/src/jalview/bin/Jalview.java @@ -61,6 +61,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Vector; +import javax.swing.LookAndFeel; import javax.swing.UIManager; import groovy.lang.Binding; @@ -284,26 +285,33 @@ public class Jalview } if (Platform.isAMac()) { + + LookAndFeel lookAndFeel = ch.randelshofer.quaqua.QuaquaManager + .getLookAndFeel(); System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Jalview"); System.setProperty("apple.laf.useScreenMenuBar", "true"); - try - { - UIManager.setLookAndFeel( - ch.randelshofer.quaqua.QuaquaManager.getLookAndFeel()); - } catch (Throwable e) + if (lookAndFeel != null) { - System.err.println( - "Failed to set QuaQua look and feel: " + e.toString()); + try + { + UIManager.setLookAndFeel(lookAndFeel); + } catch (Throwable e) + { + System.err.println( + "Failed to set QuaQua look and feel: " + e.toString()); + } } - if (!ch.randelshofer.quaqua.QuaquaManager.getLookAndFeel() - .equals(UIManager.getLookAndFeel())) + if (lookAndFeel == null || !(lookAndFeel.getClass() + .isAssignableFrom(UIManager.getLookAndFeel().getClass())) + || !UIManager.getLookAndFeel().getClass().toString() + .toLowerCase().contains("quaqua")) { try { System.err.println( - "Quaqua LaF not available. Using VAqua(4)."); - // UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel"); + "Quaqua LaF not available on this plaform. Using VAqua(4).\nSee https://issues.jalview.org/browse/JAL-2976"); + UIManager.setLookAndFeel("org.violetlib.aqua.AquaLookAndFeel"); } catch (Throwable e) { System.err.println( diff --git a/src/jalview/datamodel/HiddenCursorPosition.java b/src/jalview/datamodel/HiddenCursorPosition.java index 160ed71..bdca6d0 100644 --- a/src/jalview/datamodel/HiddenCursorPosition.java +++ b/src/jalview/datamodel/HiddenCursorPosition.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.datamodel; public final class HiddenCursorPosition diff --git a/src/jalview/datamodel/RangeElementsIterator.java b/src/jalview/datamodel/RangeElementsIterator.java index 85272f2..9ca6b2a 100644 --- a/src/jalview/datamodel/RangeElementsIterator.java +++ b/src/jalview/datamodel/RangeElementsIterator.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.datamodel; import java.util.Iterator; diff --git a/src/jalview/datamodel/RangeIterator.java b/src/jalview/datamodel/RangeIterator.java index 7a69ac6..5d45236 100644 --- a/src/jalview/datamodel/RangeIterator.java +++ b/src/jalview/datamodel/RangeIterator.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.datamodel; import java.util.ArrayList; diff --git a/src/jalview/datamodel/StartRegionIterator.java b/src/jalview/datamodel/StartRegionIterator.java index bd036e4..c21f04a 100644 --- a/src/jalview/datamodel/StartRegionIterator.java +++ b/src/jalview/datamodel/StartRegionIterator.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.datamodel; import java.util.ArrayList; diff --git a/src/jalview/datamodel/VisibleContigsIterator.java b/src/jalview/datamodel/VisibleContigsIterator.java index 6d3f43d..0185978 100644 --- a/src/jalview/datamodel/VisibleContigsIterator.java +++ b/src/jalview/datamodel/VisibleContigsIterator.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.datamodel; import java.util.ArrayList; diff --git a/src/jalview/datamodel/xdb/uniprot/UniprotFeature.java b/src/jalview/datamodel/xdb/uniprot/UniprotFeature.java index b1ed275..4c2ae24 100644 --- a/src/jalview/datamodel/xdb/uniprot/UniprotFeature.java +++ b/src/jalview/datamodel/xdb/uniprot/UniprotFeature.java @@ -27,7 +27,11 @@ public class UniprotFeature { private String type; - private String description; + private String description = null; + + private String original = null; + + private String variation = null; private String status; @@ -47,7 +51,19 @@ public class UniprotFeature public String getDescription() { - return description; + if (description == null && variation == null && original == null) + { + return null; + } + return (description == null ? "" : description) + + (variation != null + ? (description != null ? " " : "") + "Variation: '" + + variation + "'" + : "") + + (original != null + ? ((description != null || variation != null) ? " " + : "") + "Original: '" + original + "'" + : ""); } public void setDescription(String d) @@ -95,4 +111,24 @@ public class UniprotFeature this.begin = p; this.end = p; } + + public String getOriginal() + { + return original; + } + + public void setOriginal(String original) + { + this.original = original; + } + + public String getVariation() + { + return variation; + } + + public void setVariation(String variant) + { + this.variation = variant; + } } diff --git a/src/jalview/ext/jmol/JmolParser.java b/src/jalview/ext/jmol/JmolParser.java index dc3d0ee..2a510a2 100644 --- a/src/jalview/ext/jmol/JmolParser.java +++ b/src/jalview/ext/jmol/JmolParser.java @@ -28,7 +28,6 @@ import jalview.io.DataSourceType; import jalview.io.FileParse; import jalview.io.StructureFile; import jalview.schemes.ResidueProperties; -import jalview.structure.StructureImportSettings; import jalview.util.Format; import jalview.util.MessageManager; @@ -60,6 +59,12 @@ public class JmolParser extends StructureFile implements JmolStatusListener { Viewer viewer = null; + public JmolParser(boolean immediate, String inFile, + DataSourceType sourceType) throws IOException + { + super(immediate, inFile, sourceType); + } + public JmolParser(String inFile, DataSourceType sourceType) throws IOException { @@ -183,7 +188,11 @@ public class JmolParser extends StructureFile implements JmolStatusListener } lastID = tmpatom.resNumIns.trim(); } - xferSettings(); + if (isParseImmediately()) + { + // configure parsing settings from the static singleton + xferSettings(); + } makeResidueList(); makeCaBondList(); @@ -200,7 +209,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener prot.add(chainseq); } - if (StructureImportSettings.isProcessSecondaryStructure()) + // look at local setting for adding secondary tructure + if (predictSecondaryStructure) { createAnnotation(chainseq, chain, ms.at); } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index be765ec..5fa168d 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -3476,6 +3476,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, alignPanel.setOverviewPanel(null); }; }); + if (getKeyListeners().length > 0) + { + frame.addKeyListener(getKeyListeners()[0]); + } alignPanel.setOverviewPanel(overview); } @@ -4674,17 +4678,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, int assocfiles = 0; if (filesmatched.size() > 0) { - if (Cache.getDefault("AUTOASSOCIATE_PDBANDSEQS", false) - || JvOptionPane.showConfirmDialog(thisaf, - MessageManager.formatMessage( - "label.automatically_associate_structure_files_with_sequences_same_name", - new Object[] - { Integer.valueOf(filesmatched.size()) - .toString() }), - MessageManager.getString( - "label.automatically_associate_structure_files_by_name"), - JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION) - + boolean autoAssociate = Cache.getDefault("AUTOASSOCIATE_PDBANDSEQS", false); + if (!autoAssociate) + { + String msg = MessageManager.formatMessage( + "label.automatically_associate_structure_files_with_sequences_same_name", + new Object[] + { Integer.valueOf(filesmatched.size()) + .toString() }); + String ttl = MessageManager.getString( + "label.automatically_associate_structure_files_by_name"); + int choice = JvOptionPane.showConfirmDialog(thisaf, msg, + ttl, JvOptionPane.YES_NO_OPTION); + autoAssociate = choice == JvOptionPane.YES_OPTION; + } + if (autoAssociate) { for (Object[] fm : filesmatched) { @@ -4710,6 +4718,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, alignPanel.paintAlignment(true, false); } } + else + { + /* + * add declined structures as sequences + */ + for (Object[] o : filesmatched) + { + filesnotmatched.add((String) o[0]); + } + } } if (filesnotmatched.size() > 0) { diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index f5634d2..2c5684a 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -48,7 +48,6 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; -import java.awt.Insets; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ComponentAdapter; @@ -556,13 +555,10 @@ public class AlignmentPanel extends GAlignmentPanel implements /* * Estimate available height in the AlignFrame for alignment + * annotations. Deduct an estimate for title bar, menu bar, scale panel, - * hscroll, status bar (as these are not laid out we can't inspect their - * actual heights). Insets gives frame borders. + * hscroll, status bar, insets. */ - int stuff = Platform.isAMac() ? 80 : 100; - Insets insets = alignFrame.getInsets(); - int availableHeight = alignFrame.getHeight() - stuff - insets.top - - insets.bottom; + int stuff = Platform.isAMac() ? 120 : 140; + int availableHeight = alignFrame.getHeight() - stuff; /* * If not enough vertical space, maximize annotation height while keeping diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index be64c85..a7eb9b0 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -32,6 +32,7 @@ import jalview.io.FileFormatException; import jalview.io.FileFormatI; import jalview.io.FileFormats; import jalview.io.FileLoader; +import jalview.io.FormatAdapter; import jalview.io.IdentifyFile; import jalview.io.JalviewFileChooser; import jalview.io.JalviewFileView; @@ -68,6 +69,7 @@ import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -91,10 +93,13 @@ import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.DefaultDesktopManager; import javax.swing.DesktopManager; +import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; @@ -116,6 +121,8 @@ import javax.swing.event.InternalFrameEvent; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; +import org.stackoverflowusers.file.WindowsShortcut; + /** * Jalview Desktop * @@ -919,6 +926,8 @@ public class Desktop extends jalview.jbgui.GDesktop } }); + setKeyBindings(frame); + desktop.add(frame); windowMenu.add(menuItem); @@ -938,6 +947,42 @@ public class Desktop extends jalview.jbgui.GDesktop } } + /** + * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close + * the window + * + * @param frame + */ + private static void setKeyBindings(JInternalFrame frame) + { + @SuppressWarnings("serial") + final Action closeAction = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + frame.dispose(); + } + }; + + /* + * set up key bindings for Ctrl-W and Cmd-W, with the same (Close) action + */ + KeyStroke ctrlWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, + InputEvent.CTRL_DOWN_MASK); + KeyStroke cmdWKey = KeyStroke.getKeyStroke(KeyEvent.VK_W, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); + + InputMap inputMap = frame + .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); + String ctrlW = ctrlWKey.toString(); + inputMap.put(ctrlWKey, ctrlW); + inputMap.put(cmdWKey, ctrlW); + + ActionMap actionMap = frame.getActionMap(); + actionMap.put(ctrlW, closeAction); + } + @Override public void lostOwnership(Clipboard clipboard, Transferable contents) { @@ -3292,13 +3337,67 @@ public class Desktop extends jalview.jbgui.GDesktop return groovyConsole; } + /** + * handles the payload of a drag and drop event. + * + * TODO refactor to desktop utilities class + * + * @param files + * - Data source strings extracted from the drop event + * @param protocols + * - protocol for each data source extracted from the drop event + * @param evt + * - the drop event + * @param t + * - the payload from the drop event + * @throws Exception + */ 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"); + "text/uri-list;class=java.lang.String"), urlFlavour = null; + try + { + urlFlavour = new DataFlavor( + "application/x-java-url; class=java.net.URL"); + } catch (ClassNotFoundException cfe) + { + Cache.log.debug("Couldn't instantiate the URL dataflavor.", cfe); + } + + if (urlFlavour != null && t.isDataFlavorSupported(urlFlavour)) + { + + try + { + java.net.URL url = (URL) t.getTransferData(urlFlavour); + // nb: java 8 osx bug https://bugs.openjdk.java.net/browse/JDK-8156099 + // means url may be null. + if (url != null) + { + protocols.add(DataSourceType.URL); + files.add(url.toString()); + Cache.log.debug("Drop handled as URL dataflavor " + + files.get(files.size() - 1)); + return; + } + else + { + if (Platform.isAMac()) + { + System.err.println( + "Please ignore plist error - occurs due to problem with java 8 on OSX"); + } + ; + } + } catch (Throwable ex) + { + Cache.log.debug("URL drop handler failed.", ex); + } + } if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { // Works on Windows and MacOSX @@ -3326,63 +3425,112 @@ public class Desktop extends jalview.jbgui.GDesktop // 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()) + DataFlavor textDf = new DataFlavor( + "text/plain;class=java.lang.String"); + if (t.isDataFlavorSupported(textDf)) { - Cache.log.debug("fallback returned " + data); + data = (String) t.getTransferData(textDf); } + + Cache.log.debug("Plain text drop content returned " + + (data == null ? "Null - failed" : data)); + } - while (protocols.size() < files.size()) - { - Cache.log.debug("Adding missing FILE protocol for " - + files.get(protocols.size())); - protocols.add(DataSourceType.FILE); - } - for (java.util.StringTokenizer st = new java.util.StringTokenizer( - data, "\r\n"); st.hasMoreTokens();) + if (data != null) { - added = true; - String s = st.nextToken(); - if (s.startsWith("#")) + while (protocols.size() < files.size()) { - // 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(DataSourceType.URL); - files.add(uri.toString()); + Cache.log.debug("Adding missing FILE protocol for " + + files.get(protocols.size())); + protocols.add(DataSourceType.FILE); } - else + for (java.util.StringTokenizer st = new java.util.StringTokenizer( + data, "\r\n"); st.hasMoreTokens();) { - // otherwise preserve old behaviour: catch all for file objects - java.io.File file = new java.io.File(uri); - protocols.add(DataSourceType.FILE); - files.add(file.toString()); + 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(DataSourceType.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(DataSourceType.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()) + + if (t.getTransferDataFlavors() != null + && t.getTransferDataFlavors().length > 0) { Cache.log.debug( - "Supported transfer dataflavor: " + fl.toString()); - Object df = t.getTransferData(fl); - if (df != null) + "Couldn't resolve drop data. Here are the supported flavors:"); + for (DataFlavor fl : t.getTransferDataFlavors()) { - Cache.log.debug("Retrieves: " + df); - } - else - { - Cache.log.debug("Retrieved nothing"); + Cache.log.debug( + "Supported transfer dataflavor: " + fl.toString()); + Object df = t.getTransferData(fl); + if (df != null) + { + Cache.log.debug("Retrieves: " + df); + } + else + { + Cache.log.debug("Retrieved nothing"); + } } } + else + { + Cache.log.debug("Couldn't resolve dataflavor for drop: " + + t.toString()); + } + } + } + } + if (Platform.isWindows()) + + { + Cache.log.debug("Scanning dropped content for Windows Link Files"); + + // resolve any .lnk files in the file drop + for (int f = 0; f < files.size(); f++) + { + String source = files.get(f).toLowerCase(); + if (protocols.get(f).equals(DataSourceType.FILE) + && (source.endsWith(".lnk") || source.endsWith(".url") + || source.endsWith(".site"))) + { + try { + File lf = new File(files.get(f)); + // process link file to get a URL + Cache.log.debug("Found potential link file: " + lf); + WindowsShortcut wscfile = new WindowsShortcut(lf); + String fullname = wscfile.getRealFilename(); + protocols.set(f, FormatAdapter.checkProtocol(fullname)); + files.set(f, fullname); + Cache.log.debug("Parsed real filename " + fullname + + " to extract protocol: " + protocols.get(f)); + } + catch (Exception ex) + { + Cache.log.error("Couldn't parse "+files.get(f)+" as a link file.",ex); + } } } } diff --git a/src/jalview/gui/OptsAndParamsPage.java b/src/jalview/gui/OptsAndParamsPage.java index 4cac990..00c5a92 100644 --- a/src/jalview/gui/OptsAndParamsPage.java +++ b/src/jalview/gui/OptsAndParamsPage.java @@ -20,6 +20,11 @@ */ package jalview.gui; +import jalview.bin.Cache; +import jalview.io.DataSourceType; +import jalview.io.FileLoader; +import jalview.io.JalviewFileChooser; +import jalview.io.JalviewFileView; import jalview.util.MessageManager; import jalview.ws.jws2.dm.JabaOption; import jalview.ws.params.ArgumentI; @@ -27,12 +32,15 @@ import jalview.ws.params.OptionI; import jalview.ws.params.ParameterI; import jalview.ws.params.ValueConstrainI; import jalview.ws.params.ValueConstrainI.ValueType; +import jalview.ws.params.simple.FileParameter; import jalview.ws.params.simple.LogarithmicParameter; +import jalview.ws.params.simple.RadioChoiceParameter; import jalview.ws.params.simple.StringParameter; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; @@ -41,14 +49,17 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; @@ -57,6 +68,7 @@ import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; +import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.JTextArea; @@ -342,8 +354,16 @@ public class OptsAndParamsPage boolean adjusting; + /* + * drop-down list of choice options (if applicable) + */ JComboBox choicebox; + /* + * radio buttons as an alternative to combo box + */ + ButtonGroup buttonGroup; + JPanel controlsPanel = new JPanel(); boolean descriptionIsVisible = false; @@ -384,7 +404,8 @@ public class OptsAndParamsPage { ValueType type = validator.getType(); isIntegerParameter = type == ValueType.Integer; - isStringParameter = type == ValueType.String; + isStringParameter = type == ValueType.String + || type == ValueType.File; /* * ensure slider has an integer range corresponding to @@ -561,10 +582,6 @@ public class OptsAndParamsPage { return; } - if (!isChoiceParameter) - { - updateSliderFromValueField(); - } checkIfModified(); } @@ -606,15 +623,22 @@ public class OptsAndParamsPage public ArgumentI getParameter() { ParameterI prm = parameter.copy(); - if (isChoiceParameter) + String value = null; + if (parameter instanceof RadioChoiceParameter) + { + value = buttonGroup.getSelection().getActionCommand(); + } + else if (isChoiceParameter) { - String value = getSelectedValue(this.parameter, choicebox.getSelectedIndex()); - prm.setValue(value); + value = getSelectedValue(this.parameter, + choicebox.getSelectedIndex()); } else { - prm.setValue(valueField.getText()); + value = valueField.getText(); } + prm.setValue(value); + return prm; } @@ -718,10 +742,15 @@ public class OptsAndParamsPage void updateControls(ParameterI parm) { adjusting = true; - boolean init = (choicebox == null && valueField == null); + boolean init = (choicebox == null && valueField == null + && buttonGroup == null); if (init) { - if (isChoiceParameter) + if (parm instanceof RadioChoiceParameter) + { + buttonGroup = addRadioButtons(parameter, controlsPanel); + } + else if (isChoiceParameter) { choicebox = buildComboBox(parm); choicebox.addActionListener(this); @@ -751,6 +780,38 @@ public class OptsAndParamsPage } }); valueField.setPreferredSize(new Dimension(65, 25)); + if (parm instanceof FileParameter) + { + valueField.setToolTipText(MessageManager + .getString("label.double_click_to_browse")); + valueField.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + if (e.getClickCount() == 2) + { + String dir = Cache.getProperty("LAST_DIRECTORY"); + JalviewFileChooser chooser = new JalviewFileChooser(dir); + chooser.setFileView(new JalviewFileView()); + chooser.setDialogTitle( + MessageManager.getString("action.select_ddbb")); + + int val = chooser.showOpenDialog(ParamBox.this); + if (val == JalviewFileChooser.APPROVE_OPTION) + { + File choice = chooser.getSelectedFile(); + String path = choice.getPath(); + valueField.setText(path); + Cache.setProperty("LAST_DIRECTORY", choice.getParent()); + FileLoader.updateRecentlyOpened(path, + DataSourceType.FILE); + } + } + } + }); + } + controlsPanel.add(slider, BorderLayout.WEST); controlsPanel.add(valueField, BorderLayout.EAST); } @@ -761,7 +822,10 @@ public class OptsAndParamsPage { if (isChoiceParameter) { - choicebox.setSelectedItem(value); + if (!(parm instanceof RadioChoiceParameter)) + { + choicebox.setSelectedItem(value); + } } else { @@ -773,10 +837,43 @@ public class OptsAndParamsPage } /** + * Adds a panel to comp, containing a label and radio buttons for the choice + * of values of the given option. Returns a ButtonGroup whose members are + * the added radio buttons. + * + * @param option + * @param comp + * + * @return + */ + protected ButtonGroup addRadioButtons(OptionI option, Container comp) + { + ButtonGroup bg = new ButtonGroup(); + JPanel radioPanel = new JPanel(); + radioPanel.add(new JLabel(option.getDescription())); + + String value = option.getValue(); + + for (String opt : option.getPossibleValues()) + { + JRadioButton btn = new JRadioButton(opt); + btn.setActionCommand(opt); + boolean selected = opt.equals(value); + btn.setSelected(selected); + btn.addActionListener(this); + bg.add(btn); + radioPanel.add(btn); + } + comp.add(radioPanel); + + return bg; + } + + /** * Action depends on the type of the input parameter: *
      *
    • if a text input, returns the trimmed value
    • - *
    • if a choice list, returns the selected value
    • + *
    • if a choice list or radio button, returns the selected value
    • *
    • if a value slider and input field, sets the value of the slider from * the value in the text field, limiting it to any defined min-max * range.
    • @@ -792,7 +889,15 @@ public class OptsAndParamsPage { if (isChoiceParameter) { - return getSelectedValue(this.parameter, choicebox.getSelectedIndex()); + if (parameter instanceof RadioChoiceParameter) + { + return buttonGroup.getSelection().getActionCommand(); + } + else + { + return getSelectedValue(this.parameter, + choicebox.getSelectedIndex()); + } } slider.setVisible(false); return valueField.getText().trim(); @@ -1067,7 +1172,7 @@ public class OptsAndParamsPage * @param opt * @return */ - protected JComboBox buildComboBox(OptionI opt) + protected static JComboBox buildComboBox(OptionI opt) { JComboBox cb = null; List displayNames = opt.getDisplayNames(); @@ -1087,11 +1192,10 @@ public class OptsAndParamsPage return cb; } - /* + /** * Answers the value corresponding to the selected item in the choice combo - * box. If display names were not provided, this is simply the selected - * value. If display names were provided, it is the value corresponding to - * the selected item index. + * box. Note that this returns the underlying value even if a different + * display name is used in the combo box. * * @return */ @@ -1105,16 +1209,9 @@ public class OptsAndParamsPage // one value is actually returned even if this.val is not displayed value = possibleValues.get(0); } - else + else if (sel >= 0 && sel < possibleValues.size()) { - if (sel >= 0 && sel < possibleValues.size()) - { - value = possibleValues.get(sel); - } - else - { - value = opt.getValue(); - } + value = possibleValues.get(sel); } return value; } diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index 2d8eb7d..8f315bd 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -652,6 +652,11 @@ public class SeqCanvas extends JComponent implements ViewportListenerI ViewportRanges ranges = av.getRanges(); ranges.setViewportStartAndWidth(startColumn, wrappedWidthInResidues); + // we need to call this again to make sure the startColumn + + // wrappedWidthInResidues values are used to calculate wrappedVisibleWidths + // correctly. + calculateWrappedGeometry(canvasWidth, canvasHeight); + /* * draw one width at a time (including any scales or annotation shown), * until we have run out of either alignment or vertical space available diff --git a/src/jalview/hmmer/HMMERParamStore.java b/src/jalview/hmmer/HMMERParamStore.java index 00cae85..452097b 100644 --- a/src/jalview/hmmer/HMMERParamStore.java +++ b/src/jalview/hmmer/HMMERParamStore.java @@ -10,9 +10,11 @@ import jalview.ws.params.ParamDatastoreI; import jalview.ws.params.WsParamSetI; import jalview.ws.params.simple.BooleanOption; import jalview.ws.params.simple.DoubleParameter; +import jalview.ws.params.simple.FileParameter; import jalview.ws.params.simple.IntegerParameter; import jalview.ws.params.simple.LogarithmicParameter; import jalview.ws.params.simple.Option; +import jalview.ws.params.simple.RadioChoiceParameter; import jalview.ws.params.simple.StringParameter; import java.io.File; @@ -104,7 +106,7 @@ public final class HMMERParamStore implements ParamDatastoreI args.add(new BooleanOption( MessageManager.getString(HMMSearch.AUTO_ALIGN_SEQS_KEY), MessageManager.getString("label.auto_align_seqs_desc"), false, - false, true, null)); + false, false, null)); args.add(new BooleanOption( MessageManager.getString(HMMSearch.USE_ACCESSIONS_KEY), MessageManager.getString("label.use_accessions_desc"), false, @@ -119,18 +121,26 @@ public final class HMMERParamStore implements ParamDatastoreI */ addChoiceOfHmm(args); - addChoiceOfDatabase(args); - + // addChoiceOfDatabase(args); + + String thisAlignment = MessageManager + .getString(HMMSearch.THIS_ALIGNMENT_KEY); + String database = MessageManager.getString("label.database"); + args.add(new RadioChoiceParameter( + MessageManager.getString("action.search"), null, + Arrays.asList(thisAlignment, + database), + thisAlignment)); + args.add(new FileParameter(database, "", false, "", "")); args.add(new IntegerParameter( MessageManager.getString(HMMSearch.NUMBER_OF_RESULTS_KEY), MessageManager.getString("label.number_of_results_desc"), true, 100, 0, 100000)); - args.add(new StringParameter( + args.add(new RadioChoiceParameter( MessageManager.getString(HMMSearch.REPORTING_CUTOFF_KEY), null, - true, HMMSearch.CUTOFF_NONE, HMMSearch.CUTOFF_NONE, Arrays.asList(HMMSearch.CUTOFF_NONE, HMMSearch.CUTOFF_EVALUE, HMMSearch.CUTOFF_SCORE), - null)); + HMMSearch.CUTOFF_EVALUE)); args.add(new LogarithmicParameter( MessageManager.getString(HMMSearch.SEQ_EVALUE_KEY), MessageManager.getString("label.seq_e_value_desc"), false, 1D, diff --git a/src/jalview/hmmer/HMMSearch.java b/src/jalview/hmmer/HMMSearch.java index a58b949..6cda421 100644 --- a/src/jalview/hmmer/HMMSearch.java +++ b/src/jalview/hmmer/HMMSearch.java @@ -195,6 +195,7 @@ public class HMMSearch extends HmmerCommand String seqScoreCutoff = null; String domScoreCutoff = null; databaseName = "Alignment"; + boolean searchAlignment = false; if (params != null) { @@ -206,6 +207,18 @@ public class HMMSearch extends HmmerCommand { seqsToReturn = Integer.parseInt(arg.getValue()); } + else if (MessageManager.getString("action.search").equals(name)) + { + searchAlignment = arg.getValue().equals( + MessageManager.getString(HMMSearch.THIS_ALIGNMENT_KEY)); + } + else if (MessageManager.getString(DATABASE_KEY).equals(name)) + { + dbPath = arg.getValue(); + int pos = dbPath.lastIndexOf(File.separator); + databaseName = dbPath.substring(pos + 1); + databaseFile = new File(dbPath); + } else if (MessageManager.getString(AUTO_ALIGN_SEQS_KEY) .equals(name)) { @@ -280,8 +293,9 @@ public class HMMSearch extends HmmerCommand args.add(domScoreCutoff); } - if (!dbFound || MessageManager.getString(THIS_ALIGNMENT_KEY) - .equals(dbPath)) +// if (!dbFound || MessageManager.getString(THIS_ALIGNMENT_KEY) +// .equals(dbPath)) + if (searchAlignment) { /* * no external database specified for search, so diff --git a/src/jalview/io/AlignFile.java b/src/jalview/io/AlignFile.java index dcdf98e..5e15223 100755 --- a/src/jalview/io/AlignFile.java +++ b/src/jalview/io/AlignFile.java @@ -72,7 +72,20 @@ public abstract class AlignFile extends FileParse long end; - private boolean parseCalled; + /** + * true if parse() has been called + */ + private boolean parseCalled = false; + + private boolean parseImmediately = true; + + /** + * @return if doParse() was called at construction time + */ + protected boolean isParseImmediately() + { + return parseImmediately; + } /** * Creates a new AlignFile object. @@ -153,6 +166,11 @@ public abstract class AlignFile extends FileParse { super(source); initData(); + + // stash flag in case parse needs to know if it has to autoconfigure or was + // configured after construction + this.parseImmediately = parseImmediately; + if (parseImmediately) { doParse(); diff --git a/src/jalview/io/ClustalFile.java b/src/jalview/io/ClustalFile.java index c21b02c..afb2009 100755 --- a/src/jalview/io/ClustalFile.java +++ b/src/jalview/io/ClustalFile.java @@ -26,7 +26,8 @@ import jalview.datamodel.SequenceI; import jalview.util.Format; import java.io.IOException; -import java.util.Hashtable; +import java.util.HashMap; +import java.util.Map; import java.util.StringTokenizer; import java.util.Vector; @@ -59,12 +60,11 @@ public class ClustalFile extends AlignFile { int i = 0; boolean flag = false; - boolean rna = false; boolean top = false; - StringBuffer pssecstr = new StringBuffer(), - consstr = new StringBuffer(); - Vector headers = new Vector(); - Hashtable seqhash = new Hashtable(); + StringBuffer pssecstr = new StringBuffer(); + StringBuffer consstr = new StringBuffer(); + Vector headers = new Vector<>(); + Map seqhash = new HashMap<>(); StringBuffer tempseq; String line, id; StringTokenizer str; @@ -77,9 +77,11 @@ public class ClustalFile extends AlignFile { top = true; } - if (line.indexOf(" ") != 0) + boolean isConservation = line.startsWith(SPACE) + || line.startsWith(TAB); + if (!isConservation) { - str = new StringTokenizer(line, " "); + str = new StringTokenizer(line); if (str.hasMoreTokens()) { @@ -95,7 +97,7 @@ public class ClustalFile extends AlignFile { if (seqhash.containsKey(id)) { - tempseq = (StringBuffer) seqhash.get(id); + tempseq = seqhash.get(id); } else { @@ -173,7 +175,7 @@ public class ClustalFile extends AlignFile AlignmentAnnotation lastssa = null; if (pssecstr.length() == maxLength) { - Vector ss = new Vector(); + Vector ss = new Vector<>(); AlignmentAnnotation ssa = lastssa = StockholmFile .parseAnnotationRow(ss, "secondary structure", pssecstr.toString()); @@ -182,7 +184,7 @@ public class ClustalFile extends AlignFile } if (consstr.length() == maxLength) { - Vector ss = new Vector(); + Vector ss = new Vector<>(); AlignmentAnnotation ssa = StockholmFile.parseAnnotationRow(ss, "secondary structure", consstr.toString()); ssa.label = "Consensus Secondary Structure"; @@ -238,19 +240,19 @@ public class ClustalFile extends AlignFile out.append(new Format("%-" + maxid + "s") .form(printId(s[j], jvsuffix) + " ")); - int start = i * len; - int end = start + len; + int chunkStart = i * len; + int chunkEnd = chunkStart + len; int length = s[j].getLength(); - if ((end < length) && (start < length)) + if ((chunkEnd < length) && (chunkStart < length)) { - out.append(s[j].getSequenceAsString(start, end)); + out.append(s[j].getSequenceAsString(chunkStart, chunkEnd)); } else { - if (start < length) + if (chunkStart < length) { - out.append(s[j].getSequenceAsString().substring(start)); + out.append(s[j].getSequenceAsString().substring(chunkStart)); } } diff --git a/src/jalview/io/FeaturesFile.java b/src/jalview/io/FeaturesFile.java index 99663c8..169da5a 100755 --- a/src/jalview/io/FeaturesFile.java +++ b/src/jalview/io/FeaturesFile.java @@ -84,8 +84,6 @@ public class FeaturesFile extends AlignFile implements FeaturesSourceI private static final String NOTE = "Note"; - protected static final String TAB = "\t"; - protected static final String GFF_VERSION = "##gff-version"; private AlignmentI lastmatchedAl = null; diff --git a/src/jalview/io/FileLoader.java b/src/jalview/io/FileLoader.java index 798875f..66b51cd 100755 --- a/src/jalview/io/FileLoader.java +++ b/src/jalview/io/FileLoader.java @@ -43,13 +43,16 @@ import jalview.ws.utils.UrlDownloadClient; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.StringTokenizer; -import java.util.Vector; import javax.swing.SwingUtilities; public class FileLoader implements Runnable { + private static final String TAB = "\t"; + String file; DataSourceType protocol; @@ -225,56 +228,69 @@ public class FileLoader implements Runnable } } - public void updateRecentlyOpened() + /** + * Updates (or creates) the tab-separated list of recently opened files held + * under the given property name by inserting the filePath at the front of the + * list. Duplicates are removed, and the list is limited to 11 entries. The + * method returns the updated value of the property. + * + * @param filePath + * @param sourceType + */ + public static String updateRecentlyOpened(String filePath, + DataSourceType sourceType) { - Vector recent = new Vector(); - if (protocol == DataSourceType.PASTE) + if (sourceType != DataSourceType.FILE + && sourceType != DataSourceType.URL) { - // do nothing if the file was pasted in as text... there is no filename to - // refer to it as. - return; + return null; } - if (file != null - && file.indexOf(System.getProperty("java.io.tmpdir")) > -1) + + String propertyName = sourceType == DataSourceType.FILE ? "RECENT_FILE" + : "RECENT_URL"; + String historyItems = Cache.getProperty(propertyName); + if (filePath != null + && filePath.indexOf(System.getProperty("java.io.tmpdir")) > -1) { // ignore files loaded from the system's temporary directory - return; + return null; } - String type = protocol == DataSourceType.FILE ? "RECENT_FILE" - : "RECENT_URL"; - String historyItems = jalview.bin.Cache.getProperty(type); - - StringTokenizer st; + List recent = new ArrayList<>(); if (historyItems != null) { - st = new StringTokenizer(historyItems, "\t"); + StringTokenizer st = new StringTokenizer(historyItems, TAB); while (st.hasMoreTokens()) { - recent.addElement(st.nextElement().toString().trim()); + String trimmed = st.nextToken().trim(); + if (!recent.contains(trimmed)) + { + recent.add(trimmed); + } } } - if (recent.contains(file)) + /* + * if file was already in the list, it moves to the top + */ + if (recent.contains(filePath)) { - recent.remove(file); + recent.remove(filePath); } - StringBuffer newHistory = new StringBuffer(file); + StringBuilder newHistory = new StringBuilder(filePath); for (int i = 0; i < recent.size() && i < 10; i++) { - newHistory.append("\t"); - newHistory.append(recent.elementAt(i)); + newHistory.append(TAB); + newHistory.append(recent.get(i)); } - Cache.setProperty(type, newHistory.toString()); + String newProperty = newHistory.toString(); + Cache.setProperty(propertyName, newProperty); - if (protocol == DataSourceType.FILE) - { - Cache.setProperty("DEFAULT_FILE_FORMAT", format.getName()); - } + return newProperty; } @Override @@ -539,7 +555,12 @@ public class FileLoader implements Runnable } } - updateRecentlyOpened(); + updateRecentlyOpened(file, protocol); + + if (protocol == DataSourceType.FILE && format != null) + { + Cache.setProperty("DEFAULT_FILE_FORMAT", format.getName()); + } } catch (Exception er) { diff --git a/src/jalview/io/FileParse.java b/src/jalview/io/FileParse.java index c0328d5..7117d0f 100755 --- a/src/jalview/io/FileParse.java +++ b/src/jalview/io/FileParse.java @@ -45,6 +45,10 @@ import java.util.zip.GZIPInputStream; */ public class FileParse { + protected static final String SPACE = " "; + + protected static final String TAB = "\t"; + /** * text specifying source of data. usually filename or url. */ diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java index bc71566..e71d548 100755 --- a/src/jalview/jbgui/GAlignFrame.java +++ b/src/jalview/jbgui/GAlignFrame.java @@ -2007,9 +2007,9 @@ public class GAlignFrame extends JInternalFrame } } }); - hmmSearch.add(hmmSearchSettings); hmmSearch.add(hmmSearchRun); - hmmSearch.add(addDatabase); + hmmSearch.add(hmmSearchSettings); + // hmmSearch.add(addDatabase); /* * top level menu diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index 380db74..a3921f6 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -683,7 +683,9 @@ public class GPreferences extends JPanel MessageManager.getString("label.default_browser_unix")); defaultBrowser.setFont(LABEL_FONT); defaultBrowser.setText(""); - + final String tooltip = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.double_click_to_browse")); + defaultBrowser.setToolTipText(tooltip); defaultBrowser.addMouseListener(new MouseAdapter() { @Override @@ -1365,14 +1367,14 @@ public class GPreferences extends JPanel pathLabel.setFont(new java.awt.Font("SansSerif", 0, 11)); pathLabel.setHorizontalAlignment(SwingConstants.LEFT); pathLabel.setText(MessageManager.getString("label.chimera_path")); - final String tooltip = JvSwingUtils.wrapTooltip(true, - MessageManager.getString("label.chimera_path_tip")); - pathLabel.setToolTipText(tooltip); pathLabel.setBounds(new Rectangle(10, ypos, 140, height)); structureTab.add(pathLabel); chimeraPath.setFont(LABEL_FONT); chimeraPath.setText(""); + final String tooltip = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.chimera_path_tip")); + chimeraPath.setToolTipText(tooltip); chimeraPath.setBounds(new Rectangle(160, ypos, 300, height)); chimeraPath.addMouseListener(new MouseAdapter() { @@ -1660,6 +1662,9 @@ public class GPreferences extends JPanel startupCheckbox.setSelected(true); startupFileTextfield.setFont(LABEL_FONT); startupFileTextfield.setBounds(new Rectangle(172, 310, 330, 20)); + final String tooltip = JvSwingUtils.wrapTooltip(true, + MessageManager.getString("label.double_click_to_browse")); + startupFileTextfield.setToolTipText(tooltip); startupFileTextfield.addMouseListener(new MouseAdapter() { @Override diff --git a/src/jalview/jbgui/GStructureChooser.java b/src/jalview/jbgui/GStructureChooser.java index a30be66..240e1fd 100644 --- a/src/jalview/jbgui/GStructureChooser.java +++ b/src/jalview/jbgui/GStructureChooser.java @@ -1,6 +1,6 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2) - * Copyright (C) 2014 The Jalview Authors + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index ad259fd..cd986c0 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -398,8 +398,11 @@ public class StructureSelectionManager { // FIXME if sourceType is not null, we've lost data here sourceType = AppletFormatAdapter.checkProtocol(pdbFile); - pdb = new JmolParser(pdbFile, sourceType); - + pdb = new JmolParser(false, pdbFile, sourceType); + pdb.addSettings(parseSecStr && processSecondaryStructure, + parseSecStr && addTempFacAnnot, + parseSecStr && secStructServices); + pdb.doParse(); if (pdb.getId() != null && pdb.getId().trim().length() > 0 && DataSourceType.FILE == sourceType) { diff --git a/src/jalview/util/FileUtils.java b/src/jalview/util/FileUtils.java index 1684763..7e607ab 100644 --- a/src/jalview/util/FileUtils.java +++ b/src/jalview/util/FileUtils.java @@ -2,6 +2,15 @@ package jalview.util; import java.io.File; import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * Miscellaneous file-related functions @@ -75,4 +84,125 @@ public final class FileUtils return f; } + /** + * Answers a (possibly empty) list of file paths found by searching below + * from that match the supplied regular expression + * pattern. Results may include from itself if it + * matches. If an exception occurs it is written to syserr and any results up to + * that point are returned. Note that the regular expression match applies to + * the whole path of any matched file. + *

      + * WARNING: because the whole directory tree below from is + * searched, this method may be slow if used for a high level directory, or may + * exit prematurely if security or other exceptions occur. + * + *

      +   * Example: 
      +   *   findMatchingPaths(Paths.get("C:/Program Files"), ".*/chimera.exe$")
      +   * 
      + * + * @param from + * @param pattern + * + * @return + * @see https://stackoverflow.com/questions/794381/how-to-find-files-that-match-a-wildcard-string-in-java/31685610#comment62441832_31685610 + */ + public static List findMatchingPaths(Path from, String pattern) + { + List matches = new ArrayList<>(); + PathMatcher pathMatcher = FileSystems.getDefault() + .getPathMatcher("regex:" + pattern); + try + { + Files.walk(from).filter(pathMatcher::matches) + .forEach(m -> matches.add(m.toString())); + } catch (IOException e) + { + System.err.println( + "Error searching for " + pattern + " : " + e.toString()); + } + + return matches; + } + + /** + * Answers a (possibly empty) list of paths to files below the given root path, + * that match the given pattern. The pattern should be a '/' delimited set of + * glob patterns, each of which is used to match child file names (not full + * paths). Note that 'directory spanning' glob patterns (**) are not + * supported by this method. + *

      + * For example + * + *

      +   *   findMatches("C:\\", "Program Files*/Chimera*/bin/{chimera,chimera.exe}"
      +   * 
      + * + * would match "C:\Program Files\Chimera 1.11\bin\chimera.exe" and "C:\Program + * Files (x86)\Chimera 1.10.1\bin\chimera" + * + * @param root + * @param pattern + * @return + * @see https://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob + */ + public static List findMatches(String root, String pattern) + { + List results = new ArrayList<>(); + try + { + Path from = Paths.get(root); + findMatches(results, from, Arrays.asList(pattern.split("/"))); + } catch (Throwable e) + { + // Paths.get can throw IllegalArgumentException + System.err.println(String.format("Error searching %s for %s: %s", + root, pattern, e.toString())); + } + + return results; + } + + /** + * A helper method that performs recursive search of file patterns and adds any + * 'leaf node' matches to the results list + * + * @param results + * @param from + * @param patterns + */ + protected static void findMatches(List results, Path from, + List patterns) + { + if (patterns.isEmpty()) + { + /* + * reached end of recursion with all components matched + */ + results.add(from.toString()); + return; + } + + String pattern = patterns.get(0); + try (DirectoryStream dirStream = Files.newDirectoryStream(from, + pattern)) + { + dirStream.forEach(p -> { + + /* + * matched a next level file - search below it + * (ignore non-directory non-leaf matches) + */ + List subList = patterns.subList(1, patterns.size()); + if (subList.isEmpty() || p.toFile().isDirectory()) + { + findMatches(results, p, subList); + } + }); + } catch (IOException e) + { + System.err.println(String.format("Error searching %s: %s", pattern, + e.toString())); + } + } } diff --git a/src/jalview/ws/params/ValueConstrainI.java b/src/jalview/ws/params/ValueConstrainI.java index 47f454a..d1bdc98 100644 --- a/src/jalview/ws/params/ValueConstrainI.java +++ b/src/jalview/ws/params/ValueConstrainI.java @@ -29,7 +29,7 @@ public interface ValueConstrainI public enum ValueType { - Integer, Float, String, Double + Integer, Float, String, Double, File }; ValueType getType(); diff --git a/src/jalview/ws/params/simple/FileParameter.java b/src/jalview/ws/params/simple/FileParameter.java new file mode 100644 index 0000000..aa8e7ad --- /dev/null +++ b/src/jalview/ws/params/simple/FileParameter.java @@ -0,0 +1,47 @@ +package jalview.ws.params.simple; + +import jalview.ws.params.ValueConstrainI; + +/** + * A class that represents a file parameter. User entry options should include + * direct input of a file path as text, or file selection using a file browser. + * + * @author gmcarstairs + * + */ +public class FileParameter extends StringParameter +{ + + public FileParameter(String name, String description, boolean required, + String defValue, String value) + { + super(name, description, required, defValue, value); + } + + @Override + public ValueConstrainI getValidValue() + { + return new ValueConstrainI() + { + + @Override + public ValueType getType() + { + return ValueType.File; + } + + @Override + public Number getMax() + { + return null; + } + + @Override + public Number getMin() + { + return null; + } + }; + } + +} diff --git a/src/jalview/ws/params/simple/RadioChoiceParameter.java b/src/jalview/ws/params/simple/RadioChoiceParameter.java new file mode 100644 index 0000000..4fdb05e --- /dev/null +++ b/src/jalview/ws/params/simple/RadioChoiceParameter.java @@ -0,0 +1,45 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.ws.params.simple; + +import java.util.List; + +/** + * A parameter with a choice of possible options, preferred to be rendered as + * radio buttons if possible + */ +public class RadioChoiceParameter extends StringParameter +{ + + /** + * Constructor + * + * @param name + * @param description + * @param options + * @param def + */ + public RadioChoiceParameter(String name, String description, + List options, String def) + { + super(name, description, true, def, def, options, null); + } +} diff --git a/src/org/stackoverflowusers/file/WindowsShortcut.java b/src/org/stackoverflowusers/file/WindowsShortcut.java new file mode 100644 index 0000000..671e002 --- /dev/null +++ b/src/org/stackoverflowusers/file/WindowsShortcut.java @@ -0,0 +1,215 @@ +package org.stackoverflowusers.file; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; + +/** + * Represents a Windows shortcut (typically visible to Java only as a '.lnk' file). + * + * Retrieved 2011-09-23 from http://stackoverflow.com/questions/309495/windows-shortcut-lnk-parser-in-java/672775#672775 + * Originally called LnkParser + * + * Written by: (the stack overflow users, obviously!) + * Apache Commons VFS dependency removed by crysxd (why were we using that!?) https://github.com/crysxd + * Headerified, refactored and commented by Code Bling http://stackoverflow.com/users/675721/code-bling + * Network file support added by Stefan Cordes http://stackoverflow.com/users/81330/stefan-cordes + * Adapted by Sam Brightman http://stackoverflow.com/users/2492/sam-brightman + * Based on information in 'The Windows Shortcut File Format' by Jesse Hager <jessehager@iname.com> + * And somewhat based on code from the book 'Swing Hacks: Tips and Tools for Killer GUIs' + * by Joshua Marinacci and Chris Adamson + * ISBN: 0-596-00907-0 + * http://www.oreilly.com/catalog/swinghks/ + */ +public class WindowsShortcut +{ + private boolean isDirectory; + private boolean isLocal; + private String real_file; + + /** + * Provides a quick test to see if this could be a valid link ! + * If you try to instantiate a new WindowShortcut and the link is not valid, + * Exceptions may be thrown and Exceptions are extremely slow to generate, + * therefore any code needing to loop through several files should first check this. + * + * @param file the potential link + * @return true if may be a link, false otherwise + * @throws IOException if an IOException is thrown while reading from the file + */ + public static boolean isPotentialValidLink(File file) throws IOException { + final int minimum_length = 0x64; + InputStream fis = new FileInputStream(file); + boolean isPotentiallyValid = false; + try { + isPotentiallyValid = file.isFile() + && file.getName().toLowerCase().endsWith(".lnk") + && fis.available() >= minimum_length + && isMagicPresent(getBytes(fis, 32)); + } finally { + fis.close(); + } + return isPotentiallyValid; + } + + public WindowsShortcut(File file) throws IOException, ParseException { + InputStream in = new FileInputStream(file); + try { + parseLink(getBytes(in)); + } finally { + in.close(); + } + } + + /** + * @return the name of the filesystem object pointed to by this shortcut + */ + public String getRealFilename() { + return real_file; + } + + /** + * Tests if the shortcut points to a local resource. + * @return true if the 'local' bit is set in this shortcut, false otherwise + */ + public boolean isLocal() { + return isLocal; + } + + /** + * Tests if the shortcut points to a directory. + * @return true if the 'directory' bit is set in this shortcut, false otherwise + */ + public boolean isDirectory() { + return isDirectory; + } + + /** + * Gets all the bytes from an InputStream + * @param in the InputStream from which to read bytes + * @return array of all the bytes contained in 'in' + * @throws IOException if an IOException is encountered while reading the data from the InputStream + */ + private static byte[] getBytes(InputStream in) throws IOException { + return getBytes(in, null); + } + + /** + * Gets up to max bytes from an InputStream + * @param in the InputStream from which to read bytes + * @param max maximum number of bytes to read + * @return array of all the bytes contained in 'in' + * @throws IOException if an IOException is encountered while reading the data from the InputStream + */ + private static byte[] getBytes(InputStream in, Integer max) throws IOException { + // read the entire file into a byte buffer + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + byte[] buff = new byte[256]; + while (max == null || max > 0) { + int n = in.read(buff); + if (n == -1) { + break; + } + bout.write(buff, 0, n); + if (max != null) + max -= n; + } + in.close(); + return bout.toByteArray(); + } + + private static boolean isMagicPresent(byte[] link) { + final int magic = 0x0000004C; + final int magic_offset = 0x00; + return link.length >= 32 && bytesToDword(link, magic_offset) == magic; + } + + /** + * Gobbles up link data by parsing it and storing info in member fields + * @param link all the bytes from the .lnk file + */ + private void parseLink(byte[] link) throws ParseException { + try { + if (!isMagicPresent(link)) + throw new ParseException("Invalid shortcut; magic is missing", 0); + + // get the flags byte + byte flags = link[0x14]; + + // get the file attributes byte + final int file_atts_offset = 0x18; + byte file_atts = link[file_atts_offset]; + byte is_dir_mask = (byte)0x10; + if ((file_atts & is_dir_mask) > 0) { + isDirectory = true; + } else { + isDirectory = false; + } + + // if the shell settings are present, skip them + final int shell_offset = 0x4c; + final byte has_shell_mask = (byte)0x01; + int shell_len = 0; + if ((flags & has_shell_mask) > 0) { + // the plus 2 accounts for the length marker itself + shell_len = bytesToWord(link, shell_offset) + 2; + } + + // get to the file settings + int file_start = 0x4c + shell_len; + + final int file_location_info_flag_offset_offset = 0x08; + int file_location_info_flag = link[file_start + file_location_info_flag_offset_offset]; + isLocal = (file_location_info_flag & 2) == 0; + // get the local volume and local system values + //final int localVolumeTable_offset_offset = 0x0C; + final int basename_offset_offset = 0x10; + final int networkVolumeTable_offset_offset = 0x14; + final int finalname_offset_offset = 0x18; + int finalname_offset = link[file_start + finalname_offset_offset] + file_start; + String finalname = getNullDelimitedString(link, finalname_offset); + if (isLocal) { + int basename_offset = link[file_start + basename_offset_offset] + file_start; + String basename = getNullDelimitedString(link, basename_offset); + real_file = basename + finalname; + } else { + int networkVolumeTable_offset = link[file_start + networkVolumeTable_offset_offset] + file_start; + int shareName_offset_offset = 0x08; + int shareName_offset = link[networkVolumeTable_offset + shareName_offset_offset] + + networkVolumeTable_offset; + String shareName = getNullDelimitedString(link, shareName_offset); + real_file = shareName + "\\" + finalname; + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new ParseException("Could not be parsed, probably not a valid WindowsShortcut", 0); + } + } + + private static String getNullDelimitedString(byte[] bytes, int off) { + int len = 0; + // count bytes until the null character (0) + while (true) { + if (bytes[off + len] == 0) { + break; + } + len++; + } + return new String(bytes, off, len); + } + + /* + * convert two bytes into a short note, this is little endian because it's + * for an Intel only OS. + */ + private static int bytesToWord(byte[] bytes, int off) { + return ((bytes[off + 1] & 0xff) << 8) | (bytes[off] & 0xff); + } + + private static int bytesToDword(byte[] bytes, int off) { + return (bytesToWord(bytes, off + 2) << 16) | bytesToWord(bytes, off); + } + +} diff --git a/test/jalview/gui/SeqCanvasTest.java b/test/jalview/gui/SeqCanvasTest.java index 05b9aea..68ee98c 100644 --- a/test/jalview/gui/SeqCanvasTest.java +++ b/test/jalview/gui/SeqCanvasTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.gui; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/io/ClustalFileTest.java b/test/jalview/io/ClustalFileTest.java new file mode 100644 index 0000000..1da2c75 --- /dev/null +++ b/test/jalview/io/ClustalFileTest.java @@ -0,0 +1,67 @@ +package jalview.io; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import jalview.datamodel.SequenceI; + +import java.io.IOException; + +import org.testng.annotations.Test; + +public class ClustalFileTest +{ + @Test(groups="Functional") + public void testParse_withNumbering() throws IOException + { + //@formatter:off + String data = "CLUSTAL\n\n" + + "FER_CAPAA/1-8 -----------------------------------------------------------A\t1\n" + + "FER_CAPAN/1-55 MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMA 48\n" + + "FER1_SOLLC/1-55 MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA 48\n" + + "Q93XJ9_SOLTU/1-55 MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA 48\n" + + "FER1_PEA/1-60 MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMA 53\n\n" + + "FER_CAPAA/1-8 SYKVKLI 8\n" + + "FER_CAPAN/1-55 SYKVKLI 55\n" + + "FER1_SOLLC/1-55 SYKVKLI 55\n" + + "Q93XJ9_SOLTU/1-55 SYKVKLI 55\n" + + "FER1_PEA/1-60 SYKVKLV 60\n" + + " .* .:....*******..** ..........** ********...*:::* ...\n" + + "\t\t.:.::. *\n"; + //@formatter:on + ClustalFile cf = new ClustalFile(data, DataSourceType.PASTE); + cf.parse(); + SequenceI[] seqs = cf.getSeqsAsArray(); + assertEquals(seqs.length, 5); + assertEquals(seqs[0].getName(), "FER_CAPAA"); + assertEquals(seqs[0].getStart(), 1); + assertEquals(seqs[0].getEnd(), 8); + assertTrue(seqs[0].getSequenceAsString().endsWith("ASYKVKLI")); + } + + @Test(groups="Functional") + public void testParse_noNumbering() throws IOException + { + //@formatter:off + String data = "CLUSTAL\n\n" + + "FER_CAPAA/1-8 -----------------------------------------------------------A\n" + + "FER_CAPAN/1-55 MA------SVSATMISTSFMPRKPAVTSL-KPIPNVGE--ALFGLKS-A--NGGKVTCMA\n" + + "FER1_SOLLC/1-55 MA------SISGTMISTSFLPRKPAVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA\n" + + "Q93XJ9_SOLTU/1-55 MA------SISGTMISTSFLPRKPVVTSL-KAISNVGE--ALFGLKS-G--RNGRITCMA\n" + + "FER1_PEA/1-60 MATT---PALYGTAVSTSFLRTQPMPMSV-TTTKAFSN--GFLGLKT-SLKRGDLAVAMA\n\n" + + "FER_CAPAA/1-8 SYKVKLI\n" + + "FER_CAPAN/1-55 SYKVKLI\n" + + "FER1_SOLLC/1-55 SYKVKLI\n" + + "Q93XJ9_SOLTU/1-55 SYKVKLI\n" + + "FER1_PEA/1-60 SYKVKLV\n"; + //@formatter:on + ClustalFile cf = new ClustalFile(data, DataSourceType.PASTE); + cf.parse(); + SequenceI[] seqs = cf.getSeqsAsArray(); + assertEquals(seqs.length, 5); + assertEquals(seqs[0].getName(), "FER_CAPAA"); + assertEquals(seqs[0].getStart(), 1); + assertEquals(seqs[0].getEnd(), 8); + assertTrue(seqs[0].getSequenceAsString().endsWith("ASYKVKLI")); + } +} diff --git a/test/jalview/io/FileLoaderTest.java b/test/jalview/io/FileLoaderTest.java index 968901f..84bd714 100644 --- a/test/jalview/io/FileLoaderTest.java +++ b/test/jalview/io/FileLoaderTest.java @@ -1,5 +1,9 @@ package jalview.io; +import static org.testng.Assert.assertEquals; + +import jalview.bin.Cache; + import org.junit.Assert; import org.testng.annotations.Test; @@ -19,4 +23,34 @@ public class FileLoaderTest // Data source type expected to be DataSourceType.URL Assert.assertEquals(DataSourceType.URL, fileLoader.protocol); } + + @Test(groups = "Functional") + public void testUpdateRecentlyOpened() + { + // ensure properties file is read-only + Cache.loadProperties("test/jalview/io/testProps.jvprops"); + + String recent = "RECENT_FILE"; + Cache.removeProperty(recent); + + String prop = FileLoader.updateRecentlyOpened("a/b/c", + DataSourceType.FILE); + assertEquals(prop, "a/b/c"); + + prop = FileLoader.updateRecentlyOpened("d/e/f", DataSourceType.FILE); + assertEquals(prop, "d/e/f\ta/b/c"); + + // revisiting a file moves it to the top of the list + prop = FileLoader.updateRecentlyOpened("a/b/c", DataSourceType.FILE); + assertEquals(prop, "a/b/c\td/e/f"); + + // history list is limited to the most recent 11 items + for (int i = 0; i < 20; i++) + { + prop = FileLoader.updateRecentlyOpened(String.format("%d.fa", i), + DataSourceType.FILE); + } + assertEquals(prop, + "19.fa\t18.fa\t17.fa\t16.fa\t15.fa\t14.fa\t13.fa\t12.fa\t11.fa\t10.fa\t9.fa"); + } } diff --git a/test/jalview/renderer/OverviewRendererTest.java b/test/jalview/renderer/OverviewRendererTest.java index bc9c2e4..1d532f7 100644 --- a/test/jalview/renderer/OverviewRendererTest.java +++ b/test/jalview/renderer/OverviewRendererTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.renderer; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/renderer/seqfeatures/FeatureRendererTest.java b/test/jalview/renderer/seqfeatures/FeatureRendererTest.java index da7cada..11b129e 100644 --- a/test/jalview/renderer/seqfeatures/FeatureRendererTest.java +++ b/test/jalview/renderer/seqfeatures/FeatureRendererTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.renderer.seqfeatures; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/structure/Mapping.java b/test/jalview/structure/Mapping.java index 85aea40..4bee3f5 100644 --- a/test/jalview/structure/Mapping.java +++ b/test/jalview/structure/Mapping.java @@ -260,6 +260,8 @@ public class Mapping @Test(groups = { "Functional" }) public void compareTransferredToRefPDBAnnot() throws Exception { + StructureImportSettings.setProcessSecondaryStructure(true); + StructureImportSettings.setVisibleChainAnnotation(true); StructureImportSettings.setShowSeqFeatures(true); AlignFrame ref = new FileLoader(false) .LoadFileWaitTillLoaded("test/jalview/ext/jmol/1QCF.pdb", diff --git a/test/jalview/structure/StructureMappingTest.java b/test/jalview/structure/StructureMappingTest.java index 036aeaa..808e662 100644 --- a/test/jalview/structure/StructureMappingTest.java +++ b/test/jalview/structure/StructureMappingTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.structure; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/util/FileUtilsTest.java b/test/jalview/util/FileUtilsTest.java new file mode 100644 index 0000000..07fd375 --- /dev/null +++ b/test/jalview/util/FileUtilsTest.java @@ -0,0 +1,73 @@ +package jalview.util; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.List; + +import org.testng.annotations.Test; + +public class FileUtilsTest +{ + @Test(groups = "Functional") + public void testFindMatchingPaths() throws IOException + { + String expect1 = Paths.get("..", "jalview", "examples", "plantfdx.fa") + .toString(); + String expect2 = Paths.get("../jalview/examples/plantfdx.features") + .toString(); + String expect3 = Paths + .get("../jalview/examples/testdata/plantfdx.features") + .toString(); + + List matches = FileUtils + .findMatchingPaths(Paths.get(".."), + ".*[/\\\\]plant.*\\.f.*"); + System.out.println(matches); + assertTrue(matches.contains(expect1)); + assertTrue(matches.contains(expect2)); + assertTrue(matches.contains(expect3)); + } + + @Test(groups = "External") + public void testWindowsPath() throws IOException + { + if (System.getProperty("os.name").startsWith("Windows")) + { + /* + * should pass provided Eclipse is installed + */ + List matches = FileUtils.findMatches("C:\\", + "Program Files*/eclips*/eclips?.exe"); + assertFalse(matches.isEmpty()); + + /* + * should pass provided Chimera is installed + */ + matches = FileUtils.findMatches("C:\\", + "Program Files*/Chimera*/bin/{chimera,chimera.exe}"); + assertFalse(matches.isEmpty()); + } + } + + @Test(groups = "Functional") + public void testFindMatches() throws IOException + { + String expect1 = Paths.get("..", "jalview", "examples", "plantfdx.fa") + .toString(); + String expect2 = Paths.get("../jalview/examples/plantfdx.features") + .toString(); + String expect3 = Paths + .get("../jalview/examples/testdata/plantfdx.features") + .toString(); + + List matches = FileUtils + .findMatches("..", "jalview/ex*/plant*.f*"); + System.out.println(matches); + assertTrue(matches.contains(expect1)); + assertTrue(matches.contains(expect2)); + assertFalse(matches.contains(expect3)); + } +} diff --git a/test/jalview/ws/dbsources/PfamFullTest.java b/test/jalview/ws/dbsources/PfamFullTest.java index b914a45..f5cc640 100644 --- a/test/jalview/ws/dbsources/PfamFullTest.java +++ b/test/jalview/ws/dbsources/PfamFullTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.ws.dbsources; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/ws/dbsources/PfamSeedTest.java b/test/jalview/ws/dbsources/PfamSeedTest.java index 2fa1871..355ef0c 100644 --- a/test/jalview/ws/dbsources/PfamSeedTest.java +++ b/test/jalview/ws/dbsources/PfamSeedTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.ws.dbsources; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/ws/dbsources/RfamFullTest.java b/test/jalview/ws/dbsources/RfamFullTest.java index cb60b14..2d1497f 100644 --- a/test/jalview/ws/dbsources/RfamFullTest.java +++ b/test/jalview/ws/dbsources/RfamFullTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.ws.dbsources; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/ws/dbsources/RfamSeedTest.java b/test/jalview/ws/dbsources/RfamSeedTest.java index 5ca72c2..745ba2e 100644 --- a/test/jalview/ws/dbsources/RfamSeedTest.java +++ b/test/jalview/ws/dbsources/RfamSeedTest.java @@ -1,3 +1,23 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.ws.dbsources; import static org.testng.Assert.assertEquals; diff --git a/test/jalview/ws/dbsources/UniprotTest.java b/test/jalview/ws/dbsources/UniprotTest.java index f98ef85..c603a11 100644 --- a/test/jalview/ws/dbsources/UniprotTest.java +++ b/test/jalview/ws/dbsources/UniprotTest.java @@ -63,6 +63,9 @@ public class UniprotTest + "" + "" + "" + + "ML" + + "ML" + + "M" + "MHAPL VSKDL" + ""; @@ -98,7 +101,7 @@ public class UniprotTest * Check sequence features */ Vector features = entry.getFeature(); - assertEquals(3, features.size()); + assertEquals(6, features.size()); UniprotFeature sf = features.get(0); assertEquals("signal peptide", sf.getType()); assertNull(sf.getDescription()); @@ -118,6 +121,27 @@ public class UniprotTest assertEquals(21, sf.getBegin()); assertEquals(247, sf.getEnd()); + sf = features.get(3); + assertEquals("sequence variant", sf.getType()); + assertEquals("Variation: 'L' Original: 'M'", sf.getDescription()); + assertEquals(41, sf.getPosition()); + assertEquals(41, sf.getBegin()); + assertEquals(41, sf.getEnd()); + + sf = features.get(4); + assertEquals("sequence variant", sf.getType()); + assertEquals("Pathogenic Variation: 'L' Original: 'M'", + sf.getDescription()); + assertEquals(41, sf.getPosition()); + assertEquals(41, sf.getBegin()); + assertEquals(41, sf.getEnd()); + + sf = features.get(5); + assertEquals("sequence variant", sf.getType()); + assertEquals("Pathogenic Original: 'M'", sf.getDescription()); + assertEquals(41, sf.getPosition()); + assertEquals(41, sf.getBegin()); + assertEquals(41, sf.getEnd()); /* * Check cross-references */ diff --git a/utils/InstallAnywhere/Jalview.iap_xml b/utils/InstallAnywhere/Jalview.iap_xml index 20726f5..ced9ac0 100755 --- a/utils/InstallAnywhere/Jalview.iap_xml +++ b/utils/InstallAnywhere/Jalview.iap_xml @@ -314,13 +314,13 @@ and any path to a file to save to the file]]> - + - + - + @@ -367,7 +367,7 @@ and any path to a file to save to the file]]> false - + true @@ -419,7 +419,7 @@ and any path to a file to save to the file]]> false - + true @@ -471,7 +471,7 @@ and any path to a file to save to the file]]> false - + true @@ -523,7 +523,7 @@ and any path to a file to save to the file]]> false - + true @@ -575,7 +575,7 @@ and any path to a file to save to the file]]> false - + true @@ -627,7 +627,7 @@ and any path to a file to save to the file]]> false - + true @@ -679,7 +679,7 @@ and any path to a file to save to the file]]> false - + true @@ -731,7 +731,7 @@ and any path to a file to save to the file]]> false - + true @@ -783,7 +783,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -835,7 +835,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -887,7 +887,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -939,7 +939,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -991,7 +991,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -1043,7 +1043,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -1095,7 +1095,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -1147,7 +1147,7 @@ and any path to a file to save to the file]]>
      false - + true @@ -1199,7 +1199,7 @@ and any path to a file to save to the file]]> false - + true @@ -1251,7 +1251,7 @@ and any path to a file to save to the file]]> false - + true @@ -1303,7 +1303,7 @@ and any path to a file to save to the file]]> false - + true @@ -1355,7 +1355,7 @@ and any path to a file to save to the file]]> false - + true @@ -1407,7 +1407,7 @@ and any path to a file to save to the file]]> false - + true @@ -1459,7 +1459,7 @@ and any path to a file to save to the file]]> false - + true @@ -1511,7 +1511,7 @@ and any path to a file to save to the file]]> false - + true @@ -1563,7 +1563,7 @@ and any path to a file to save to the file]]> false - + true @@ -1615,7 +1615,7 @@ and any path to a file to save to the file]]> false - + true @@ -1667,7 +1667,7 @@ and any path to a file to save to the file]]> false - + true @@ -1719,7 +1719,7 @@ and any path to a file to save to the file]]> false - + true @@ -1771,7 +1771,7 @@ and any path to a file to save to the file]]> false - + true @@ -1823,7 +1823,7 @@ and any path to a file to save to the file]]> false - + true @@ -1875,7 +1875,7 @@ and any path to a file to save to the file]]> false - + true @@ -1927,7 +1927,7 @@ and any path to a file to save to the file]]> false - + true @@ -1979,7 +1979,7 @@ and any path to a file to save to the file]]> false - + true @@ -2031,7 +2031,7 @@ and any path to a file to save to the file]]> false - + true @@ -2083,7 +2083,7 @@ and any path to a file to save to the file]]> false - + true @@ -2135,7 +2135,7 @@ and any path to a file to save to the file]]> false - + true @@ -2187,7 +2187,7 @@ and any path to a file to save to the file]]> false - + true @@ -2239,7 +2239,7 @@ and any path to a file to save to the file]]> false - + true @@ -2291,7 +2291,7 @@ and any path to a file to save to the file]]> false - + true @@ -2343,7 +2343,7 @@ and any path to a file to save to the file]]> false - + true @@ -2395,7 +2395,7 @@ and any path to a file to save to the file]]> false - + true @@ -2447,7 +2447,7 @@ and any path to a file to save to the file]]> false - + true @@ -2499,7 +2499,7 @@ and any path to a file to save to the file]]> false - + true @@ -2551,7 +2551,7 @@ and any path to a file to save to the file]]> false - + true @@ -2603,7 +2603,7 @@ and any path to a file to save to the file]]> false - + true @@ -2655,7 +2655,7 @@ and any path to a file to save to the file]]> false - + true @@ -2707,7 +2707,7 @@ and any path to a file to save to the file]]> false - + true @@ -2759,7 +2759,7 @@ and any path to a file to save to the file]]> false - + true @@ -2811,7 +2811,7 @@ and any path to a file to save to the file]]> false - + true @@ -2863,7 +2863,7 @@ and any path to a file to save to the file]]> false - + true @@ -2915,7 +2915,7 @@ and any path to a file to save to the file]]> false - + true @@ -2967,7 +2967,7 @@ and any path to a file to save to the file]]> false - + true @@ -3001,7 +3001,7 @@ and any path to a file to save to the file]]> - + @@ -4294,7 +4294,7 @@ Press "Done" to quit the installer.]]> true - + @@ -5458,7 +5458,7 @@ Press "Done" to quit the installer.]]> true - + @@ -7344,7 +7344,7 @@ and any path to a file to read from that file]]> false - + true @@ -7385,7 +7385,7 @@ and any path to a file to read from that file]]> false - + true @@ -7426,7 +7426,7 @@ and any path to a file to read from that file]]> false - + true @@ -7498,7 +7498,7 @@ and any path to a file to read from that file]]> false - + true @@ -7539,7 +7539,7 @@ and any path to a file to read from that file]]> false - + true @@ -7580,7 +7580,7 @@ and any path to a file to read from that file]]> false - + true @@ -7621,7 +7621,7 @@ and any path to a file to read from that file]]> false - + true @@ -7662,7 +7662,7 @@ and any path to a file to read from that file]]> false - + true @@ -7712,7 +7712,7 @@ and any path to a file to read from that file]]> false - + true @@ -7753,7 +7753,7 @@ and any path to a file to read from that file]]> false - + true @@ -7794,7 +7794,7 @@ and any path to a file to read from that file]]> false - + true @@ -7835,7 +7835,7 @@ and any path to a file to read from that file]]> false - + true @@ -7876,7 +7876,7 @@ and any path to a file to read from that file]]> false - + true @@ -7917,7 +7917,7 @@ and any path to a file to read from that file]]> false - + true @@ -7958,7 +7958,7 @@ and any path to a file to read from that file]]> false - + true @@ -7999,7 +7999,7 @@ and any path to a file to read from that file]]> false - + true @@ -8090,7 +8090,7 @@ and any path to a file to read from that file]]> false - + true @@ -8131,7 +8131,7 @@ and any path to a file to read from that file]]> false - + false @@ -8187,7 +8187,7 @@ and any path to a file to read from that file]]> false - + true @@ -8228,7 +8228,7 @@ and any path to a file to read from that file]]> false - + true @@ -8413,7 +8413,7 @@ and any path to a file to read from that file]]> - + diff --git a/utils/InstallAnywhere/jalview_buildinstaller.xml b/utils/InstallAnywhere/jalview_buildinstaller.xml index 6310934..6f0115e 100644 --- a/utils/InstallAnywhere/jalview_buildinstaller.xml +++ b/utils/InstallAnywhere/jalview_buildinstaller.xml @@ -20,7 +20,7 @@ - +