Merge branch 'develop' into refactor/JAL-2106_sourceDbRef_revision
authorJim Procter <jprocter@issues.jalview.org>
Thu, 25 Aug 2016 09:54:04 +0000 (10:54 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Thu, 25 Aug 2016 09:54:04 +0000 (10:54 +0100)
73 files changed:
help/html/features/clarguments.html
help/html/features/dasfeatures.html
help/html/features/varna.html
help/html/io/index.html
help/html/na/index.html
help/html/releases.html
help/html/webServices/index.html
help/html/webServices/newsreader.html
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/MCview/Atom.java
src/jalview/analysis/AlignmentUtils.java
src/jalview/analysis/Grouping.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AnnotationColourChooser.java
src/jalview/appletgui/AnnotationPanel.java
src/jalview/appletgui/AnnotationRowFilter.java
src/jalview/appletgui/FeatureColourChooser.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/ScalePanel.java
src/jalview/appletgui/SliderPanel.java
src/jalview/bin/Cache.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewLite.java
src/jalview/controller/AlignViewController.java
src/jalview/datamodel/AlignmentView.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/xdb/embl/EmblEntry.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AnnotationColourChooser.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/AnnotationRowFilter.java
src/jalview/gui/DasSourceBrowser.java
src/jalview/gui/FeatureColourChooser.java
src/jalview/gui/FeatureRenderer.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/FontChooser.java
src/jalview/gui/PCAPanel.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/RedundancyPanel.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/SliderPanel.java
src/jalview/gui/TextColourChooser.java
src/jalview/io/FormatAdapter.java
src/jalview/io/JSONFile.java
src/jalview/io/MSFfile.java
src/jalview/io/PfamFile.java
src/jalview/io/StockholmFile.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/renderer/ScaleRenderer.java
src/jalview/util/Platform.java
src/jalview/ws/SequenceFetcher.java
test/MCview/AtomTest.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/analysis/GroupingTest.java
test/jalview/controller/AlignViewControllerTest.java [new file with mode: 0644]
test/jalview/datamodel/ColumnSelectionTest.java
test/jalview/datamodel/SequenceTest.java
test/jalview/io/AnnotatedPDBFileInputTest.java
test/jalview/io/FormatAdapterTest.java [new file with mode: 0644]
test/jalview/io/Jalview2xmlTests.java
test/jalview/io/StockholmFileTest.java
test/jalview/structure/StructureSelectionManagerTest.java
test/jalview/ws/jabaws/RNAStructExportImport.java
utils/HelpLinksChecker.java
utils/MessageBundleChecker.java
utils/i18nAnt.xml

index 63a14af..1d6f62d 100644 (file)
     </tr>
     <tr>
       <td>
+        <div align="center">-nonews</div>
+      <td>
+        <div align="left">Disable check for <a href="../webServices/newsreader.html">Jalview news</a> on startup (not recommended other than for classroom / demo usage)</div>
+      </td>
+    </tr>
+    <tr>
+      <td>
         <div align="center">-nousagestats</div>
       <td>
         <div align="left">Turn off google analytics usage tracking</div>
index c0c888a..90958ae 100644 (file)
@@ -29,8 +29,7 @@
   </p>
   <p>
     Jalview includes a client for retrieving sequences and their
-    features via the <a href="http://www.biodas.org">Distributed
-      Annotation System</a>.
+    features via the Distributed Annotation System.
   </p>
   <ol>
     <li>Open the Feature Settings panel by selecting &quot;View
   <p>
     <em>DAS support was introduced in Jalview Version 2.1.</em>
   </p>
+  <br/>
+  <p>
+    <em>The DAS registry at http://www.dasregistry.org was decommissioned early in 2015. An unmaintained mirror is currently hosted at http://www.ebi.ac.uk/das-srv/registry/.</em>
+  </p>
   <p>&nbsp;
 </body>
 </html>
index 029edce..ce446f3 100644 (file)
@@ -27,7 +27,7 @@
     <strong>The VARNA RNA Viewer</strong>
   </p>
   <p>
-    <a href="http://varna.lri.fr/index.html">VARNA</a> was integrated
+    <a href="http://varna.lri.fr">VARNA</a> was integrated
     into Jalview 2.8 to allow interactive viewing of RNA secondary
     structure annotation. It is opened by selecting the <strong>&quot;Structure&#8594;View
       Structure:&quot;</strong> option in the <a href="../menus/popupMenu.html">sequence
index c0a89cf..d2196c1 100755 (executable)
       NBRF/PIR (including MODELLER variant), Pfam/Stockholm</em>
   </p>
   <p>
-    The EBI has <a href="http://www.ebi.ac.uk/help/formats.html">examples</a>
-    of these file formats.
-  </p>
-  <p>
     Additionally, whole sets of coloured and annotated alignments and
     trees can be read from a <a href="../features/jalarchive.html">Jalview
       (jar) format</a> file using <strong>Desktop&#8594;Load
index ae4c1c6..de2741b 100644 (file)
@@ -65,7 +65,7 @@ td {
       annotation.</li>
     <li><em>Clustal files</em> - certain RNA alignment programs,
       such as <a
-      href="http://rna.informatik.uni-freiburg.de:8080/LocARNA.jsp"
+      href="http://rna.informatik.uni-freiburg.de/LocARNA"
     >LocaRNA</a> output consensus RNA secondary structure lines in the
       line normally reserved for the Clustal consensus line in a clustal
       file.</li>
index dfb747f..5a5020a 100755 (executable)
                 region export in flat file generation</li>
 
               <li>Export alignment views for display with the <a
-                href="http://biojs.io/d/msa">BioJS MSAViewer</a></li>
+                href="http://msa.biojs.net/">BioJS MSAViewer</a></li>
 
               <li>Export scrollable SVG in HTML page</li>
               <li>Optional embedding of BioJSON data when exporting
index b03bb9d..1463554 100755 (executable)
@@ -90,7 +90,7 @@
     services were maintained by the Barton group at the University of
     Dundee, and ran programs on the Life Sciences High-performance
     Computing Cluster. With the advent of <a
-      href="http://www.compbio.dundee.ac.uk/JABAWS"
+      href="http://www.compbio.dundee.ac.uk/jabaws"
     >JABAWS</a>, however, it is possible for anyone to host Jalview web
     services.
   </p>
index ee69290..5ec088a 100644 (file)
@@ -19,7 +19,7 @@
  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
-<head>Jalview Desktop RSS News Reader
+<head>
 </head>
 <body>
   <p>
   <p>The news reader will be launched automatically when you start
     the Desktop if new items are available. Should you want to browse
     older items, however, you can open it manually from the 'Jalview
-    news reader' option in the Desktop's 'Tools' menu.</p>
-  <img src="jalviewrssreader.gif" align="center" width="513"
-    height="337" alt="Snapshot of the Jalview Desktop's RSS reader"
-  />
-  <p>
+    news reader' option in the Desktop's <a href="../menus/desktopMenu.html">'Tools' menu</a>.</p><br/>
+  <div style="text-align: center;"><img src="jalviewrssreader.gif" width="513"
+    height="337" alt="Snapshot of the Jalview Desktop's RSS reader"/></div>
+
+  <br/><p>
     The <em>Jalview news reader</em> was introduced in <a
       href="http://www.jalview.org/releaseHistory.html#Jalview2.7"
     >Jalview version 2.7</a>. Its implementation is based on <a
       href="http://jswingreader.sourceforge.net/"
     >JSwingReader</a>.
   </p>
+  <br/><em>From Jalview 2.10.0, check for news on startup can be disabled with <a href="../features/clarguments.html">command-line parameter</a> &#39;-nonews&#39;. 
+  This is not recommended for normal use, but may be useful to avoid interruptions when teaching, demonstrating, recording etc.</em>
 </body>
 </html>
index 40c311f..54181fe 100644 (file)
@@ -38,7 +38,6 @@ action.cancel = Cancel
 action.create = Create
 action.update = Update
 action.delete = Delete
-action.snapshot = Snapshot
 action.clear = Clear
 action.accept = Accept
 action.select_ddbb = --- Select Database ---
@@ -121,7 +120,6 @@ action.save_as_default = Save as default
 action.save_as = Save as...
 action.save = Save
 action.cancel_fetch = Cancel Fetch
-action.save_omit_hidden_columns = Save / Omit Hidden Regions
 action.change_font = Change Font
 action.change_font_tree_panel = Change Font (Tree Panel)
 action.colour = Colour
@@ -137,21 +135,22 @@ action.show_group = Show Group
 action.fetch_db_references = Fetch DB References
 action.view_flanking_regions = Show flanking regions
 label.view_flanking_regions = Show sequence data either side of the subsequences involved in this alignment
-label.str = Str:
-label.seq = Seq:
 label.structures_manager = Structures Manager
 label.nickname = Nickname:
 label.url = URL:
 label.input_file_url = Enter URL or Input File
-label.select_feature = Select feature:
+label.select_feature = Select feature
 label.name = Name
+label.name\: = Name:
 label.name_param = Name: {0}
 label.group = Group
+label.group\: = Group:
 label.group_name = Group Name
 label.group_description = Group Description
 label.edit_group_name_description = Edit Group Name/Description
 label.colour = Colour:
-label.description = Description:
+label.description = Description
+label.description\: = Description:
 label.start = Start:
 label.end = End:
 label.current_parameter_set_name = Current parameter set name:
@@ -222,8 +221,8 @@ label.proteins = Proteins
 label.to_new_alignment = To New Alignment
 label.to_this_alignment = Add To This Alignment
 label.apply_colour_to_all_groups = Apply Colour To All Groups
-label.modify_identity_thereshold = Modify Identity Threshold...
-label.modify_conservation_thereshold = Modify Conservation Threshold...
+label.modify_identity_threshold = Modify Identity Threshold...
+label.modify_conservation_threshold = Modify Conservation Threshold...
 label.input_from_textbox = Input from textbox
 label.centre_column_labels = Centre column labels
 label.automatic_scrolling = Automatic Scrolling
@@ -240,7 +239,6 @@ label.except_selected_sequences = All except selected sequences
 label.all_but_selected_region = All but Selected Region (Shift+Ctrl+H)
 label.selected_region = Selected Region
 label.all_sequences_columns = All Sequences and Columns
-label.hide_insertions = Hide columns gapped for selection
 label.hide_selected_annotations = Hide selected annotations
 label.show_selected_annotations = Show selected annotations
 label.group_consensus = Group Consensus
@@ -321,7 +319,6 @@ label.found_match_for = Found match for {0}
 label.font = Font:
 label.size = Size:
 label.style = Style:
-label.enter_redundancy_threshold = Enter the redundancy threshold
 label.calculating = Calculating....
 label.modify_conservation_visibility = Modify conservation visibility
 label.colour_residues_above_occurence = Colour residues above % occurence
@@ -365,7 +362,6 @@ label.example = Example
 label.example_param = Example: {0}
 label.select_file_format_before_saving = You must select a file format before saving!
 label.file_format_not_specified = File format not specified
-label.alignment_contains_hidden_columns = The Alignment contains hidden regions (hidden sequences/columns).\nDo you want to save only the visible alignment?
 label.couldnt_save_file = Couldn't save file: {0}
 label.error_saving_file = Error Saving File
 label.remove_from_default_list = Remove from default list?
@@ -467,7 +463,6 @@ label.no_features_added_to_this_alignment = No Features added to this alignment!
 label.features_can_be_added_from_searches_1 = (Features can be added from searches or
 label.features_can_be_added_from_searches_2 = from Jalview / GFF features files)
 label.calculating_pca= Calculating PCA
-label.reveal_columns = Reveal Columns
 label.jalview_cannot_open_file = Jalview can't open file
 label.jalview_applet = Jalview applet
 label.loading_data = Loading data
@@ -475,7 +470,6 @@ label.memory_stats = Total Free Memory: {0} MB; Max Memory: {1} MB; {2} %
 label.calculating_tree = Calculating tree
 label.state_queueing = queuing
 label.state_running = running
-label.state_complete = complete
 label.state_completed = finished
 label.state_job_cancelled = job cancelled!!
 label.state_job_error = job error!
@@ -501,7 +495,6 @@ label.jmol_help = Jmol Help
 label.chimera_help = Chimera Help
 label.close_viewer = Close Viewer
 label.confirm_close_chimera = This will close Jalview''s connection to {0}.<br>Do you want to close the Chimera window as well?
-label.chimera_help = Chimera Help
 label.all = All
 label.sort_by = Sort alignment by
 label.sort_by_score = Sort by Score
@@ -521,15 +514,14 @@ label.reset_min_max_colours_to_defaults = Reset min and max colours to defaults
 label.align_structures_using_linked_alignment_views = Align structures using {0} linked alignment views
 label.connect_to_session = Connect to session {0}
 label.threshold_feature_display_by_score = Threshold the feature display by score.
-label.threshold_feature_no_thereshold = No Threshold
-label.threshold_feature_above_thereshold = Above Threshold
-label.threshold_feature_below_thereshold = Below Threshold
-label.adjust_thereshold = Adjust threshold
+label.threshold_feature_no_threshold = No Threshold
+label.threshold_feature_above_threshold = Above Threshold
+label.threshold_feature_below_threshold = Below Threshold
+label.adjust_threshold = Adjust threshold
 label.toggle_absolute_relative_display_threshold = Toggle between absolute and relative display threshold.
 label.display_features_same_type_different_label_using_different_colour = Display features of the same type with a different label using a different colour. (e.g. domain features)
 label.select_colour_minimum_value = Select Colour for Minimum Value
 label.select_colour_maximum_value = Select Colour for Maximum Value
-label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment = Open a new structure viewer with all structures associated with the current selection and superimpose them using the alignment.
 label.open_url_param = Open URL {0}
 label.open_url_seqs_param = Open URL ({0}..) ({1} seqs)
 label.load_pdb_file_associate_with_sequence = Load a PDB file and associate it with sequence {0}
@@ -584,8 +576,8 @@ label.histogram = Histogram
 label.logo = Logo
 label.non_positional_features = List Non-positional Features
 label.database_references = List Database References
-label.share_selection_across_views = Share selection across views
-label.scroll_highlighted_regions = Scroll to highlighted regions
+#label.share_selection_across_views = Share selection across views
+#label.scroll_highlighted_regions = Scroll to highlighted regions
 label.gap_symbol = Gap Symbol
 label.prot_alignment_colour = Protein Alignment Colour
 label.nuc_alignment_colour = Nucleotide Alignment Colour
@@ -668,20 +660,12 @@ label.cut_paste = Cut'n'Paste
 label.adjusting_parameters_for_calculation = Adjusting parameters for existing Calculation
 label.2d_rna_structure_line = 2D RNA {0} (alignment)
 label.2d_rna_sequence_name = 2D RNA - {0}
-label.edit_name_and_description_current_group = Edit name and description of current group.
-label.view_structure_for = View structure for {0}
-label.view_all_structures = View all {0} structures.
-label.view_all_representative_structures = View all {0} representative structures.
-label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Opens a new structure viewer with all representative structures\nassociated with the current selection\nsuperimposed with the current alignment.
-label.associate_structure_with_sequence = Associate Structure with Sequence
+label.edit_name_and_description_current_group = Edit name and description of current group
 label.from_file = From File
 label.enter_pdb_id = Enter PDB Id (or pdbid:chaincode)
-label.discover_pdb_ids = Discover PDB IDs
 label.text_colour = Text Colour
 action.set_text_colour = Text Colour...
 label.structure = Structure
-label.view_structure = View Structure
-label.view_protein_structure = View Protein Structure
 label.show_pdbstruct_dialog = 3D Structure Data...
 label.view_rna_structure = VARNA 2D Structure
 label.clustalx_colours = Clustalx colours
@@ -709,7 +693,6 @@ label.translate_cDNA = Translate as cDNA
 label.reverse = Reverse
 label.reverse_complement = Reverse Complement
 label.linked_view_title = Linked CDS and protein view
-label.align = Align
 label.extract_scores = Extract Scores
 label.get_cross_refs = Get Cross-References
 label.sort_alignment_new_tree = Sort Alignment With New Tree
@@ -721,7 +704,6 @@ label.use_registry = Use Registry
 label.add_local_source = Add Local Source
 label.set_as_default = Set as Default
 label.show_labels = Show labels
-label.background_colour = Background Colour
 action.background_colour = Background Colour...
 label.associate_nodes_with = Associate Nodes With
 label.jalview_pca_calculation = Jalview PCA Calculation
@@ -814,7 +796,6 @@ label.services_at = Services at {0}
 label.rest_client_submit = {0} using {1}
 label.fetch_retrieve_from =Retrieve from {0}</html>
 label.fetch_retrieve_from_all_sources = Retrieve from all {0} sources in {1}<br>First is :{2}<html> 
-#label.feature_settings_click_drag = <html>Click/drag feature types up or down to change render order.<br/>Double click to select columns containing feature in alignment/current selection<br/>Pressing Alt will select columns outside features rather than inside<br/>Pressing Shift to modify current selection (rather than clear current selection)<br/>Press CTRL or Command/Meta to toggle columns in/outside features<br/></html>
 label.feature_settings_click_drag = Drag up or down to change render order.<br/>Double click to select columns containing feature.
 label.transparency_tip = Adjust transparency to 'see through' feature colours.
 label.opt_and_params_further_details = see further details by right-clicking
@@ -830,17 +811,10 @@ label.user_preset = User Preset
 label.service_preset = Service Preset
 label.run_with_preset = Run {0} with preset
 label.view_service_doc_url = <html>View <a href="{0}">{1}</a></html>
-label.submit_sequence = <html>Submit {0} {1} {2} {3} to<br/>{4}</html>
 action.by_title_param = By {0}
-label.alignment = Alignment
-label.secondary_structure_prediction = Secondary Structure Prediction
-label.sequence_database_search = Sequence Database Search
-label.analysis = Analysis
-label.protein_disorder = Protein Disorder 
 label.source_from_db_source = Sources from {0}
 label.from_msname = from {0}
 label.superpose_with = Superpose with
-action.do = Do
 label.scale_label_to_column = Scale Label to Column
 label.add_new_row = Add New Row
 label.edit_label_description = Edit Label/Description
@@ -884,7 +858,7 @@ label.service_url = Service URL
 label.copied_sequences = Copied sequences
 label.cut_sequences = Cut Sequences
 label.conservation_colour_increment = Conservation Colour Increment ({0})
-label.percentage_identity_thereshold = Percentage Identity Threshold ({0})
+label.percentage_identity_threshold = Percentage Identity Threshold ({0})
 label.error_unsupported_owwner_user_colour_scheme = Unsupported owner for User Colour scheme dialog
 label.save_alignment_to_file = Save Alignment to file
 label.save_features_to_file = Save Features to File
@@ -900,7 +874,6 @@ label.save_vamsas_document_archive = Save Vamsas Document Archive
 label.saving_vamsas_doc = Saving VAMSAS Document to {0}
 label.load_feature_colours = Load Feature Colours
 label.save_feature_colours = Save Feature Colour Scheme
-label.dataset_for = {0} Dataset for {1}
 label.select_startup_file = Select startup file
 label.select_default_browser = Select default web browser
 label.save_tree_as_newick = Save tree as newick file
@@ -928,15 +901,9 @@ error.null_from_clone1 = Null from clone1!
 error.implementation_error_sortbyfeature = Implementation Error - sortByFeature method must be one of FEATURE_SCORE, FEATURE_LABEL or FEATURE_DENSITY.
 error.not_yet_implemented = Not yet implemented
 error.unknown_type_dna_or_pep = Unknown Type {0} - dna or pep are the only allowed values.
-error.implementation_error_dont_know_thereshold_annotationcolourgradient = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
-error.implementation_error_embeddedpopup_not_null = Implementation error - embeddedPopup must be non-null
-error.invalid_colour_for_mycheckbox = Invalid color for MyCheckBox
-error.implementation_error_unrecognised_render_object_for_features_type = Implementation Error: Unrecognised render object {0} for features of type {1}
-error.implementation_error_unsupported_feature_colour_object = Implementation error: Unsupported feature colour object.
+error.implementation_error_dont_know_threshold_annotationcolourgradient = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
 error.invalid_separator_parameter = Invalid separator parameter - must be non-zero length
 error.alignment_cigararray_not_implemented = Alignment(CigarArray) not yet implemented
-error.weak_sequencei_equivalence_not_yet_implemented = Weak sequenceI equivalence not yet implemented.
-error.implementation_error_can_only_make_alignmnet_from_cigararray = Implementation Error - can only make an alignment view from a CigarArray of sequences.
 error.empty_view_cannot_be_updated = empty view cannot be updated.
 error.mismatch_between_number_of_sequences_in_block = Mismatch between number of sequences in block {0} ({1}) and the original view ({2})
 error.padding_not_yet_implemented = Padding not yet implemented
@@ -958,16 +925,14 @@ error.not_yet_implemented_cigar_object_from_cigar_string = NOT YET Implemented:
 error.implementation_bug_cigar_operation = Implementation Bug. Cigar Operation {0} {1} not one of {2}, {3}, or {4}.
 error.implementation_error_for_new_cigar = Implementation error for new Cigar(SequenceI)
 error.implementation_error_cigar_seq_no_operations = Implementation error: {0}th sequence Cigar has no operations.
-error.implementation_error_jmol_getting_data = Implementation error - Jmol seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016
 error.implementation_error_no_pdbentry_from_index = Implementation error - no corresponding pdbentry (for index {0}) to add sequences mappings to
 error.jmol_version_not_compatible_with_jalview_version = Jmol version {0} is not compatible with this version of Jalview. Report this problem at issues.jalview.org
 error.not_implemented_remove = Remove: Not implemented
 error.not_implemented_clone = Clone: Not implemented
-error.implementation_error_chimera_getting_data = Implementation error - Chimera seems to be still working on getting its data - report at http://issues.jalview.org/browse/JAL-1016
 error.call_setprogressbar_before_registering_handler = call setProgressBar before registering the progress bar's handler.
 label.cancelled_params = Cancelled {0}
 error.implementation_error_cannot_show_view_alignment_frame = Implementation error: cannot show a view from another alignment in an AlignFrame.
-error.implementation_error_dont_know_about_thereshold_setting = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
+error.implementation_error_dont_know_about_threshold_setting = Implementation error: don't know about threshold setting for current AnnotationColourGradient.
 error.eps_generation_not_implemented = EPS Generation not yet implemented
 error.png_generation_not_implemented = PNG Generation not yet implemented
 error.try_join_vamsas_session_another = Trying to join a vamsas session when another is already connected
@@ -986,7 +951,6 @@ error.setstatus_called_non_existent_job_pane = setStatus called for non-existent
 error.implementation_error_cannot_find_marshaller_for_param_set =Implementation error: Can't find a marshaller for the parameter set
 error.implementation_error_old_jalview_object_not_bound =IMPLEMENTATION ERROR: old jalview object is not bound ! ({0})
 error.implementation_error_vamsas_doc_class_should_bind_to_type = Implementation Error: Vamsas Document Class {0} should bind to a {1} (found a {2})
-error.implementation_error_jalview_class_should_bind_to_type = Implementation Error: Jalview Class {0} should bind to a {1} (found a {2})
 error.invalid_vamsas_rangetype_cannot_resolve_lists = Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!
 error.implementation_error_maplist_is_null = Implementation error. MapList is null for initMapType.
 error.implementation_error_cannot_have_null_alignment = Implementation error: Cannot have null alignment property key
@@ -1028,10 +992,11 @@ error.implementation_error_need_to_have_httpresponse = Implementation Error: nee
 error.dbrefsource_implementation_exception =DBRefSource Implementation Exception
 error.implementation_error_dbinstance_must_implement_interface = Implmentation Error - getDbInstances must be given a class that implements jalview.ws.seqfetcher.DbSourceProxy (was given{0})
 error.implementation_error_must_init_dbsources =Implementation error. Must initialise dbSources
-label.view_controller_toggled_marked = {0} {1} columns containing features of type {2}  across {3} sequence(s)
+label.view_controller_toggled_marked = {0} {1} columns {2} features of type {3}  across {4} sequence(s)
 label.toggled = Toggled
 label.marked = Marked
-label.not = not
+label.containing = containing
+label.not_containing = not containing
 label.no_feature_of_type_found = No features of type {0} found.
 label.submission_params = Submission {0}
 label.empty_alignment_job = Empty Alignment Job
@@ -1041,7 +1006,7 @@ label.pca_recalculating = Recalculating PCA
 label.pca_calculating = Calculating PCA
 label.select_foreground_colour = Choose foreground colour
 label.select_colour_for_text = Select Colour for Text
-label.adjunst_foreground_text_colour_thereshold = Adjust Foreground Text Colour Threshold
+label.adjunst_foreground_text_colour_threshold = Adjust Foreground Text Colour Threshold
 label.select_subtree_colour = Select Sub-Tree Colour
 label.create_new_sequence_features = Create New Sequence Feature(s)
 label.amend_delete_features = Amend/Delete Features for {0}
@@ -1061,7 +1026,6 @@ exception.mismatched_unseen_closing_char = Mismatched (unseen) closing character
 exception.mismatched_closing_char = Mismatched closing character {0}
 exception.mismatched_opening_char = Mismatched opening character {0} at {1}
 exception.invalid_datasource_couldnt_obtain_reader = Invalid datasource. Could not obtain Reader
-exception.index_value_not_in_range = {0}: Index value {1} not in range [0..{2}]
 exception.unterminated_cigar_string = Unterminated cigar string
 exception.unexpected_operation_cigar_string_pos = Unexpected operation {0} in cigar string (position {1} in {2}
 exception.couldnt_parse_responde_from_annotated3d_server = Couldn't parse response from Annotate3d server
@@ -1089,7 +1053,6 @@ exception.ranml_problem_parsing_data = Problem parsing data as RNAML ({0})
 exception.pfam_no_sequences_found = No sequences found (PFAM input)
 exception.stockholm_invalid_format = This file is not in valid STOCKHOLM format: First line does not contain '# STOCKHOLM'
 exception.couldnt_parse_sequence_line = Could not parse sequence line: {0}
-exception.error_parsing_line = Error parsing {0}
 exception.unknown_annotation_detected = Unknown annotation detected: {0} {1}
 exception.couldnt_store_sequence_mappings = Couldn't store sequence mappings for {0}
 exception.matrix_too_many_iteration = Too many iterations in {0} (max is {1})
@@ -1097,7 +1060,6 @@ exception.browser_not_found = Exception in finding browser: {0}
 exception.browser_unable_to_locate = Unable to locate browser: {0}
 exception.invocation_target_exception_creating_aedesc = InvocationTargetException while creating AEDesc: {0}
 exception.illegal_access_building_apple_evt= IllegalAccessException while building AppleEvent: {0}
-exception.instantiation_creating_aedesc = InstantiationException while creating AEDesc: {0}
 exception.unable_to_launch_url = Unable to launch URL: {0}
 exception.unable_to_create_internet_config = Unable to create an Internet Config instance: {0}
 exception.invocation_target_calling_url = InvocationTargetException while calling openURL: {0}
@@ -1106,8 +1068,6 @@ exception.interrupted_launching_browser = InterruptedException while launching b
 exception.das_source_doesnt_support_sequence_command = Source {0} does not support the sequence command.
 exception.invalid_das_source = Invalid das source: {0}
 exception.ebiembl_retrieval_failed_on = EBI EMBL XML retrieval failed on {0}:{1}
-label.no_embl_record_found = # No EMBL record retrieved for {0}:{1}
-label.embl_successfully_parsed = # Successfully parsed the {0} queries into an Alignment
 exception.no_pdb_records_for_chain = No PDB Records for {0} chain {1}
 exception.unexpected_handling_rnaml_translation_for_pdb = Unexpected exception when handling RNAML translation of PDB data
 exception.couldnt_recover_sequence_properties_for_alignment = Couldn't recover sequence properties for alignment
@@ -1198,8 +1158,8 @@ label.edit_jabaws_url = Edit JABAWS URL
 label.add_jabaws_url = Add new JABAWS URL
 label.news_from_jalview = News from http://www.jalview.org
 label.cut_paste_alignmen_file = Cut & Paste Alignment File
-label.enter_redundancy_thereshold = Enter the redundancy threshold
-label.select_dark_light_set_thereshold = <html><i>Select a dark and light text colour, then set the threshold to<br>switch between colours, based on background colour</i></html>
+label.enter_redundancy_threshold = Enter the redundancy threshold
+label.select_dark_light_set_threshold = <html><i>Select a dark and light text colour, then set the threshold to<br>switch between colours, based on background colour</i></html>
 label.select_feature_colour = Select Feature Colour
 label.delete_all = Delete all sequences
 warn.delete_all = <html>Deleting all sequences will close the alignment window.<br>Confirm deletion or Cancel.
@@ -1220,28 +1180,23 @@ label.no_colour_selection_in_scheme = Please make a colour selection before appl
 label.no_colour_selection_warn = Error saving colour scheme
 label.open_split_window? = Would you like to open as a split window, with cDNA and protein linked?
 label.open_split_window = Open split window
-label.no_mappings = No mappings found
 action.no = No
 action.yes = Yes
 label.for = for
 label.select_by_annotation = Select/Hide Columns by Annotation
 action.select_by_annotation = Select/Hide Columns by Annotation...
 label.threshold_filter =  Threshold Filter
-action.hide = Hide
-action.select = Select
 label.alpha_helix = Alpha Helix
 label.beta_strand = Beta Strand
 label.turn = Turn
 label.select_all = Select All
 label.structures_filter = Structures Filter
 label.search_filter = Search Filter
-label.description = Description
 label.include_description= Include Description
 action.back = Back
 label.hide_insertions = Hide Insertions
 label.mark_as_representative = Mark as representative
 label.open_jabaws_web_page = Open JABAWS web page
-label.opens_the_jabaws_server_homepage = Opens the JABAWS server's homepage in web browser
 label.pdb_sequence_fetcher = PDB Sequence Fetcher
 label.result = result
 label.results = results
@@ -1308,3 +1263,6 @@ status.fetching_3d_structures_for = Fetching 3D Structure for {0}
 status.obtaining_mapping_with_sifts = Obtaining mapping with SIFTS
 status.obtaining_mapping_with_nw_alignment = Obtaining mapping with NW alignment
 status.exporting_alignment_as_x_file = Exporting alignment as {0} file
+label.column = Column
+label.cant_map_cds = Unable to map CDS to protein\nCDS missing or incomplete
+label.operation_failed = Operation failed
index 618178d..45941c2 100644 (file)
@@ -38,7 +38,6 @@ action.cancel = Cancelar
 action.create = Crear
 action.update = Actualizar
 action.delete = Borrar
-action.snapshot = Imagen
 action.clear = Limpiar
 action.accept = Aceptar
 action.select_ddbb = --- Seleccionar base de datos ---
@@ -118,7 +117,6 @@ action.save_as_default = Guardar como por defecto
 action.save_as = Guardar como
 action.save = Guardar
 action.cancel_fetch = Cancelar búsqueda
-action.save_omit_hidden_columns = Guardar / Omitir las columnas ocultas
 action.change_font = Cambiar Fuente
 action.change_font_tree_panel = Cambiar fuente (panel del Ã¡rbol)
 action.colour = Color
@@ -134,21 +132,22 @@ action.show_group = Mostrar grupo
 action.fetch_db_references = Recuperar referencias a base de datos
 action.view_flanking_regions = Mostrar flancos
 label.view_flanking_regions = Mostrar los datos de la secuencia a ambos lados de las subsecuencias implicadas en este alineamiento
-label.str = Str: 
-label.seq = Seq: 
 label.structures_manager = Administrar estructuras
 label.nickname = Sobrenombre:
 label.url = URL: 
 label.input_file_url = Introducir URL en el fichero de entrada
-label.select_feature = Seleccionar función:
-label.name = Nombre:
+label.select_feature = Seleccionar característica
+label.name = Nombre
+label.name\: = Nombre:
 label.name_param = Nombre: {0}
-label.group = Grupo:
+label.group = Grupo
+label.group\: = Grupo:
 label.group_name = Nombre del grupo
 label.group_description = Descripción del grupo
 label.edit_group_name_description = Editar nombre/descripción del grupo
 label.colour = Color:
-label.description = Descripción:
+label.description = Descripción
+label.description\: = Descripción:
 label.start = Comenzar:
 label.end = Terminar:
 label.current_parameter_set_name = Nombre actual del conjunto de parámetros:
@@ -208,8 +207,8 @@ label.nucleotide = Nucle
 label.to_new_alignment = A nuevo alineamiento
 label.to_this_alignment = Añadir a este alineamiento
 label.apply_colour_to_all_groups = Aplicar color a todos los grupos
-label.modify_identity_thereshold = Modificar el umbral de identidad...
-label.modify_conservation_thereshold = Modificar el umbral de conservación...
+label.modify_identity_threshold = Modificar el umbral de identidad...
+label.modify_conservation_threshold = Modificar el umbral de conservación...
 label.input_from_textbox = Introducir desde el cuadro de texto
 label.centre_column_labels = Centrar las etiquetas de las columnas
 label.automatic_scrolling = Desplazamiento automático
@@ -217,7 +216,6 @@ label.documentation = Documentaci
 label.about = Acerca de...
 label.show_sequence_limits = Mostrar los límites de la secuencia
 label.feature_settings = Ajustar funciones...
-label.sequence_features = Funciones de la secuencia
 label.all_columns = Todas las columnas
 label.all_sequences = Todas las secuencias
 label.selected_columns = Columnas seleccionadas
@@ -291,7 +289,6 @@ label.found_match_for = Buscar coincidencia para {0}
 label.font = Fuente:
 label.size = Talla:
 label.style = Estilo:
-label.enter_redundancy_threshold = Introducir el umbral de redundancia
 label.calculating = Calculando....
 label.modify_conservation_visibility = Modificar la visibilidad de conservación
 label.colour_residues_above_occurence = Residuos de color por encima del % de aparición 
@@ -315,8 +312,6 @@ label.blog_item_published_on_date = {0} {1}
 label.select_das_service_from_table = Seleccionar servicio DAS de la tabla para leer una descripción completa aquí.
 label.session_update = Actualizar sesión
 label.new_vamsas_session = Nueva sesión Vamsas
-label.load_vamsas_session = Cargar sesión Vamsas
-label.save_vamsas_session = Guardar sesión Vamsas
 action.save_vamsas_session = Guardar Sesión Vamsas
 label.select_vamsas_session_opened_as_new_vamsas_session= Selecciones una sesión vamsas para abrirla como una nueva sesión.
 label.open_saved_vamsas_session = Abrir una sesión VAMSAS guardada
@@ -336,7 +331,6 @@ label.example = Ejemplo
 label.example_param = Ejemplo: {0}
 label.select_file_format_before_saving = Debe seleccionar un formato de fichero antes de guardar!
 label.file_format_not_specified = Formato de fichero no especificado
-label.alignment_contains_hidden_columns = El alineamiento contiene columnas ocultas.\nQuieres guardar s\u00F3lo el alineamiento visible?
 label.couldnt_save_file = No se pudo guardar el fichero: {0}
 label.error_saving_file = Error guardando el fichero
 label.remove_from_default_list = eliminar de la lista de defectuosos?
@@ -436,7 +430,6 @@ label.no_features_added_to_this_alignment = No hay funciones asociadas a este al
 label.features_can_be_added_from_searches_1 = (Las funciones pueden ser añadidas de búsquedas o
 label.features_can_be_added_from_searches_2 = de ficheros de funciones Jalview / GFF)
 label.calculating_pca= Calculando PCA
-label.reveal_columns = Mostrar Columnas
 label.jalview_cannot_open_file = Jalview no puede abrir el fichero
 label.jalview_applet = Aplicación Jalview  
 label.loading_data = Cargando datos
@@ -444,7 +437,6 @@ label.memory_stats = Memoria libre total: {0} MB; Memoria m
 label.calculating_tree = Calculando Ã¡rbol
 label.state_queueing = En cola 
 label.state_running = Procesando
-label.state_complete = Completar
 label.state_completed = Finalizado
 label.state_job_cancelled = Â¡Trabajo cancelado!
 label.state_job_error = Error del trabajo!
@@ -458,8 +450,6 @@ label.load_associated_tree = Cargar 
 label.load_features_annotations = Cargar características/anotaciones ...
 label.export_features = Exportar características...
 label.export_annotations = Exportar anotaciones ...
-label.jalview_copy = Copiar (sólo Jalview)
-label.jalview_cut = Cortar (sólo Jalview)
 label.to_upper_case = Pasar a mayúsculas
 label.to_lower_case = Pasar a minúsculas
 label.toggle_case = Alternar mayúsculas y minúsculas
@@ -468,8 +458,9 @@ label.create_sequence_feature = Crear funci
 label.edit_sequence = Editar secuencia
 label.edit_sequences = Editar secuencias
 label.sequence_details = Detalles de la secuencia
-label.jmol_help = Ayuda de Jmol 
-label.all = Todo
+label.jmol_help = Ayuda de Jmol
+# Todos/Todas is gender-sensitive, but currently only used for feminine (cadena / anotación)! 
+label.all = Todas
 label.sort_by = Ordenar por
 label.sort_by_score = Ordenar por puntuación
 label.sort_by_density = Ordenar por densidad
@@ -485,15 +476,14 @@ label.reset_min_max_colours_to_defaults = Reiniciar los colores min y max colour
 label.align_structures_using_linked_alignment_views = Alinear las estructuras utlizando las {0} vistas de alineamiento enlazadas
 label.connect_to_session = Conectar a la sesión {0}
 label.threshold_feature_display_by_score = Filtrar la característica mostrada por puntuación.
-label.threshold_feature_no_thereshold = Sin umbral
-label.threshold_feature_above_thereshold = Por encima del umbral
-label.threshold_feature_below_thereshold = Por debajo del umbral
-label.adjust_thereshold = Ajustar umbral
+label.threshold_feature_no_threshold = Sin umbral
+label.threshold_feature_above_threshold = Por encima del umbral
+label.threshold_feature_below_threshold = Por debajo del umbral
+label.adjust_threshold = Ajustar umbral
 label.toggle_absolute_relative_display_threshold = Cambiar entre mostrar el umbral absoluto y el relativo.
 label.display_features_same_type_different_label_using_different_colour = Mostrar las características del mismo tipo con una etiqueta diferente y empleando un color distinto (p.e. características del dominio)
 label.select_colour_minimum_value = Seleccionar el color para el valor mínimo
 label.select_colour_maximum_value = Seleccionar el color para el valor máximo
-label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment = Abrir una nueva vista Jmol con todas las estructuras asociadas con la selección acxtual y superponer las utilizando el alineamiento.
 label.open_url_param = Abrir URL {0}
 label.open_url_seqs_param = Abrir URL ({0}..) ({1} secuencias)
 label.load_pdb_file_associate_with_sequence = Cargar un fichero PDB y asociarlo con la secuencia {0}
@@ -544,10 +534,9 @@ label.histogram = Histograma
 label.logo = Logo
 label.non_positional_features = Características no posicionales
 label.database_references = Referencias a base de datos
-label.share_selection_across_views = Compartir la selección en todas las vistas
-label.scroll_highlighted_regions = Desplazarse hasta las regiones resaltadas
+#label.share_selection_across_views = Compartir la selección en todas las vistas
+#label.scroll_highlighted_regions = Desplazarse hasta las regiones resaltadas
 label.gap_symbol = Símbolo del hueco
-label.alignment_colour = Color del alineamiento
 label.address = Dirección
 label.port = Puerto
 label.default_browser_unix = Navegador por defecto (Unix)
@@ -626,18 +615,11 @@ label.cut_paste = Cortar y pegar
 label.adjusting_parameters_for_calculation = Ajustar los parámetros para el cálculo existente
 label.2d_rna_structure_line = 2D RNA {0}
 label.2d_rna_sequence_name = 2D RNA - {0}
-label.edit_name_and_description_current_group = Editar el nombre y la descripción del grupo actual.
-label.view_structure_for = Visualizar la estructura para {0}
-label.view_all_structures = Visualizar todas las {0} estructuras.
-label.view_all_representative_structures = Visualizar todas las {0} estructuras representativas.
-label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Abrir una nueva vista de Jmol con todas las estructuras representativas\nasociadas con la selecci\u00F3n actual\nsuperpuesta con el alineamiento actual.
-label.associate_structure_with_sequence = Asociar estructura con la secuencia
+label.edit_name_and_description_current_group = Editar el nombre y la descripción del grupo actual
 label.from_file = desde fichero
 label.enter_pdb_id = Introducir PDB Id
-label.discover_pdb_ids = Buscar PDB ids
 label.text_colour = Color del texto
 label.structure = Estructura
-label.view_structure = Visualizar estructura
 label.clustalx_colours = Colores de Clustalx
 label.above_identity_percentage = Sobre % identidad
 label.create_sequence_details_report_annotation_for = Anotación para {0}
@@ -670,7 +652,6 @@ label.use_registry = Utilizar el registro
 label.add_local_source = Añadir fuente local
 label.set_as_default = Establecer por defecto
 label.show_labels = Mostrar etiquetas
-label.background_colour = Color de fondo
 label.associate_nodes_with = Asociar nodos con
 label.jalview_pca_calculation = Cálculo del PCA por Jalview
 label.link_name = Nombre del enalce
@@ -763,17 +744,10 @@ label.user_preset = Preselecci
 label.service_preset = Preselección del servicio
 label.run_with_preset = Ejecutar {0} con preselección
 label.view_service_doc_url = Visualizar <a href="{0}">{1}</a></html>
-label.submit_sequence = Enviar {0} {1} {2} {3} a<br/>{4}</html>
 action.by_title_param = por {0}
-label.alignment = Alineamiento
-label.secondary_structure_prediction = Predicción de la estructura secundaria
-label.sequence_database_search = Búsqueda en base de datos de secuencias
-label.analysis = Análisis
-label.protein_disorder = Desorden en la proteína 
 label.source_from_db_source = Fuentes de {0}
 label.from_msname = de {0}
 label.superpose_with = Superponer con...
-action.do = Hacer
 label.scale_label_to_column = Ajustar la etiqueta a la columna
 label.add_new_row = Añadir nuevo fila
 label.edit_label_description = Editar etiqueta/descripción
@@ -817,7 +791,7 @@ label.service_url = URL del servicio
 label.copied_sequences = Secuencias copiadas
 label.cut_sequences = Cortar secuencias
 label.conservation_colour_increment = Incremento de Conservación del Color ({0})
-label.percentage_identity_thereshold = Umbral del Porcentaje de Identidad ({0})
+label.percentage_identity_threshold = Umbral del Porcentaje de Identidad ({0})
 label.error_unsupported_owwner_user_colour_scheme = Propietario no soportado para el diálogo del Esquema Cromático del Usuario
 label.save_alignment_to_file = Guardar Alineamiento en fichero
 label.save_features_to_file = Guardar Características en un fichero
@@ -833,7 +807,6 @@ label.save_vamsas_document_archive = Guardar el archivo de documento Vamsas
 label.saving_vamsas_doc = Guardando el documento VAMSAS en {0}
 label.load_feature_colours = Cargar colores de características
 label.save_feature_colours = Guardar esquema cromático de características
-label.dataset_for = {0} conjunto de datos para {1}
 label.select_startup_file = Seleccionar fichero de arranque
 label.select_default_browser = Seleccionar navegador web por defecto
 label.save_tree_as_newick = Guardar Ã¡rbol como fichero newick
@@ -861,15 +834,9 @@ error.null_from_clone1 = Nulo de clone1!
 error.implementation_error_sortbyfeature = Error de implementación - sortByFeature debe ser uno de FEATURE_SCORE, FEATURE_LABEL o FEATURE_DENSITY.
 error.not_yet_implemented = No se ha implementado todavía
 error.unknown_type_dna_or_pep = Tipo desconocido {0} - dna o pep son los Ãºnicos valores permitidos
-error.implementation_error_dont_know_thereshold_annotationcolourgradient = Error de implementación: no se conoce el valor umbral para el AnnotationColourGradient actual.
-error.implementation_error_embeddedpopup_not_null = Error de implementación - embeddedPopup debe ser no nulo.
-error.invalid_colour_for_mycheckbox = Color no válido para MyCheckBox
-error.implementation_error_unrecognised_render_object_for_features_type = Error de implementación: no se reconoce el objeto de representación {0} para las características de tipo {1}
-error.implementation_error_unsupported_feature_colour_object = Error de implementación: objeto de color de características no soportado.
+error.implementation_error_dont_know_threshold_annotationcolourgradient = Error de implementación: no se conoce el valor umbral para el AnnotationColourGradient actual.
 error.invalid_separator_parameter = Separador de parámetros no válido - debe tener longitud mayor que cero
 error.alignment_cigararray_not_implemented = Alignment(CigarArray) no se ha implementado todavía
-error.weak_sequencei_equivalence_not_yet_implemented = Equivalencia débil sequenceI no se ha implementado todavía.
-error.implementation_error_can_only_make_alignmnet_from_cigararray = Error de implementación - sólo se puede construir un vista de alineamiento a partir de una CigarArray de secuencias.
 error.empty_view_cannot_be_updated = una vista vacía no se puede actualizar.
 error.mismatch_between_number_of_sequences_in_block = No hay coincidencia entre el número de secuencias en el bloque {0} ({1}) y la vista original ({2})
 error.padding_not_yet_implemented = El relleno no se ha implementado todavía
@@ -891,16 +858,14 @@ error.not_yet_implemented_cigar_object_from_cigar_string = No implementado todav
 error.implementation_bug_cigar_operation = Bug de implementación. La operación Cigar {0} {1} no es ni {2}, ni {3} ni {4}.
 error.implementation_error_for_new_cigar = Error de implementación en new Cigar(SequenceI)
 error.implementation_error_cigar_seq_no_operations = Error de implementación: la {0}a secuencia Cigar no tiene operaciones.
-error.implementation_error_jmol_getting_data = Error de implementación - Jmol parece estar todavía intentando recuperar sus datos - informe de ello en http://issues.jalview.org/browse/JAL-1016
 error.implementation_error_no_pdbentry_from_index = Error de implementación - no existe la correspondiente entrada pdb (para el Ã­ndice {0}) para añadir el mapeo de secuencias a
 error.jmol_version_not_compatible_with_jalview_version = La versión {0} de Jmol no es compatible con esta versión de Jalview. Informe de este problema en http://issues.jalview.org
 error.not_implemented_remove = Borrar: no implementado
 error.not_implemented_clone = Clonar: no implementado
-error.implementation_error_chimera_getting_data = Error de implementación - Chimera parece estar todavía intentando recuperar sus datos - informe de ello en http://issues.jalview.org/browse/JAL-1016
 error.call_setprogressbar_before_registering_handler = llamada a setProgressBar antes de registrar el manejador de la barra de estado
 label.cancelled_params = {0} cancelado
 error.implementation_error_cannot_show_view_alignment_frame = Error de implementación: no es posible mostrar una vista de otro alineamiento en un AlignFrame.
-error.implementation_error_dont_know_about_thereshold_setting = Error de implementación: no se conoce la configuración del umbral para el AnnotationColourGradient actual.
+error.implementation_error_dont_know_about_threshold_setting = Error de implementación: no se conoce la configuración del umbral para el AnnotationColourGradient actual.
 error.eps_generation_not_implemented = La generación de EPS no se ha implementado todavía
 error.png_generation_not_implemented = La generación de PNG no se ha implementado todavía
 error.try_join_vamsas_session_another = Tratando de establecer una sesión VAMSAS cuando ya había otra conectada
@@ -919,7 +884,6 @@ error.setstatus_called_non_existent_job_pane = se lllamado a setStatus para el p
 error.implementation_error_cannot_find_marshaller_for_param_set =Error de implementación: no puede encontrar un marshaller para el conjunto de parámetros
 error.implementation_error_old_jalview_object_not_bound =Error de implementación: Â¡el objeto Jalview antiguo no está enlazado! ({0})
 error.implementation_error_vamsas_doc_class_should_bind_to_type = Error de implementación: la clase de documento VAMSAS {0} debe enlazar a {1} (pero se ha encontrado que lo está a {2})
-error.implementation_error_jalview_class_should_bind_to_type = Error de implementación: la clase Jalview {0} debe enlazar a {1} (pero se ha encontrado que lo está a {2})
 error.invalid_vamsas_rangetype_cannot_resolve_lists = RangeType VAMSAS no válido - Â¡no es posible resolver ambas listas de Pos y Seg con los valores elegidos!
 error.implementation_error_maplist_is_null = Error de implementación. MapList es nulo en initMapType.
 error.implementation_error_cannot_have_null_alignment = Error de implementación: no es posible tener una clave nula en el alineamiento
@@ -961,10 +925,11 @@ error.implementation_error_need_to_have_httpresponse = Error de implementaci
 error.dbrefsource_implementation_exception = Excepción de implementación DBRefSource
 error.implementation_error_dbinstance_must_implement_interface = Error de Implementación- getDbInstances debe recibir una clase que implemente jalview.ws.seqfetcher.DbSourceProxy (recibió {0})
 error.implementation_error_must_init_dbsources =Error de implementación. Debe inicializar dbSources
-label.view_controller_toggled_marked = {0} {1} columnas conteniendo características del tipo {2} en {3} secuencia(s)
+label.view_controller_toggled_marked = {0} {1} columnas {2} características del tipo {3} en {4} secuencia(s)
 label.toggled = Invertida
 label.marked = Marcada
-label.not = no
+label.containing = conteniendo
+label.not_containing = no conteniendo
 label.no_feature_of_type_found = No se han encontrado características del tipo {0}.
 label.submission_params = Envío {0}
 label.empty_alignment_job = Trabajo de alineamiento vacío
@@ -974,7 +939,7 @@ label.pca_recalculating = Recalculando PCA
 label.pca_calculating = Calculando PCA
 label.select_foreground_colour = Escoger color del primer plano
 label.select_colour_for_text = Seleccione el color del texto
-label.adjunst_foreground_text_colour_thereshold = Ajustar el umbral del color del texto en primer plano
+label.adjunst_foreground_text_colour_threshold = Ajustar el umbral del color del texto en primer plano
 label.select_subtree_colour = Seleccioanr el color del sub-árbol
 label.create_new_sequence_features = Crear nueva(s) característica(s) de secuencia
 label.amend_delete_features = Arrelgar/Borrar características de {0}
@@ -994,7 +959,6 @@ exception.mismatched_unseen_closing_char = Discordancia (no vista) en el car
 exception.mismatched_closing_char = Carácter de cierre discordante {0}
 exception.mismatched_opening_char = Carácter de apertura discordante {0} en {1}
 exception.invalid_datasource_couldnt_obtain_reader = Fuente de datos no válida. No es posible obtener el Reader
-exception.index_value_not_in_range = {0}: el valor del Ã­ndice {1} en se encuentra en el rango [0..{2}]
 exception.unterminated_cigar_string = Cadena cigar sin terminar
 exception.unexpected_operation_cigar_string_pos = Operación no esperada {0} en una cadena cigar (posición {1} en {2})
 exception.couldnt_parse_responde_from_annotated3d_server = No es posible parsear la respuesta procedente del servidor Annotate3d 
@@ -1022,7 +986,6 @@ exception.ranml_problem_parsing_data = Problema parseando los datos como RNAML (
 exception.pfam_no_sequences_found = No se han encontrado secuencias (entrada PFAM)
 exception.stockholm_invalid_format = Este fichero no es tiene un formato STOCKHOLM válido: la primera línea no contiene '# STOCKHOLM'
 exception.couldnt_parse_sequence_line = No es posible parse la línea de secuencia: {0}
-exception.error_parsing_line = Error parseando {0}
 exception.unknown_annotation_detected = Anotación desconocida detectada: {0} {1}
 exception.couldnt_store_sequence_mappings = No es posible almacenar los mapeos de secuencia para {0}
 exception.matrix_too_many_iteration = Demasiadas iteraciones en {0} (el máximo es {1})
@@ -1030,7 +993,6 @@ exception.browser_not_found = Excepci
 exception.browser_unable_to_locate = Imposible encontrar el navegador: {0}
 exception.invocation_target_exception_creating_aedesc = InvocationTargetException mientras se creaba AEDesc: {0}
 exception.illegal_access_building_apple_evt= IllegalAccessException mientras se construía AppleEvent: {0}
-exception.instantiation_creating_aedesc = InstantiationException mientras se creaba AEDesc: {0}
 exception.unable_to_launch_url = Imposible lanzar la URL: {0}
 exception.unable_to_create_internet_config = Imposible crear una instancia de configuración de Internet: {0}
 exception.invocation_target_calling_url = InvocationTargetException mientras se invocaba openURL: {0}
@@ -1039,8 +1001,6 @@ exception.interrupted_launching_browser = InterruptedException mientras se lanza
 exception.das_source_doesnt_support_sequence_command = La fuente {0} no soporta el comando sequence.
 exception.invalid_das_source = Fuente DAS no válida: {0}
 exception.ebiembl_retrieval_failed_on = La recuperación de datos EBI EMBL XML ha fallado en {0}:{1}
-label.no_embl_record_found = # No se ha recuperado ningún registro EMBL de {0}:{1}
-label.embl_successfully_parsed = # Se han parseado con Ã©xito las consultas {0} en un alineamiento
 exception.no_pdb_records_for_chain = No se han encontrado registros {0} para la cadena {1}
 exception.unexpected_handling_rnaml_translation_for_pdb = Excepcion inesperada cuando se traducían a RNAML los datos PDB
 exception.couldnt_recover_sequence_properties_for_alignment = No es posible recuperar las propiedades de la secuencia para el alineamiento
@@ -1122,8 +1082,8 @@ label.edit_jabaws_url = Editar JABAWS URL
 label.add_jabaws_url = Añadir nueva JABAWS URL
 label.news_from_jalview = Noticias de http://www.jalview.org
 label.cut_paste_alignmen_file = Cortar & Pegar fichero de alineamiento
-label.enter_redundancy_thereshold = Introducir el umbral de redundancia
-label.select_dark_light_set_thereshold = <i>Seleccionar un color oscuro y un color claro para el texto y establecer el umbral en que<br>cambiar entre colores, basándose en el color de fondo</i>
+label.enter_redundancy_threshold = Introducir el umbral de redundancia
+label.select_dark_light_set_threshold = <i>Seleccionar un color oscuro y un color claro para el texto y establecer el umbral en que<br>cambiar entre colores, basándose en el color de fondo</i>
 label.select_feature_colour = Seleccionar color de las características
 label.ignore_gaps_consensus = Ignorar huecos en el consenso
 label.show_group_histogram = Mostrar histograma de grupo
@@ -1143,7 +1103,6 @@ action.feature_settings=Ajustes de caracter
 info.invalid_msa_notenough=No suficientes datos de sequencia para alinear
 label.result=resultado
 label.results=resultados
-label.no_mappings=No hay mapeados encontrados
 label.struct_from_pdb=Procesar la estructura secundaria PDB
 label.hide_selected_annotations=Ocultar anotaciones seleccionados
 info.select_annotation_row=Seleccionar Fila de Anotaciones
@@ -1167,7 +1126,6 @@ action.no=No
 action.yes=Sí
 label.export_settings=Exportar Ajustes
 label.linked_view_title=Vista vinculada de cDNA y proteína
-label.view_protein_structure=Ver Estructura Proteica
 label.couldnt_read_data=No se pudo leer los datos
 status.opening_file=abriendo fichero
 label.except_selected_sequences=Todo excepto secuencias seleccionadas
@@ -1212,7 +1170,6 @@ 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
-tooltip.rnalifold_settings=Modificar la configuración de la predicción RNAAlifold. Ãšselo para ocultar o mostrar resultados del cálculo de RNA, o cambiar parámetros de el plegado de RNA.
 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
@@ -1228,9 +1185,7 @@ label.colour_with_chimera=Colorear con Chimera
 label.show_pdbstruct_dialog=Datos de Estructura 3D...
 label.hide_all=Ocultar todos
 label.invert=Invertir
-label.pdb_sequence_getcher=Buscador de Secuencias PDB
 tooltip.aacon_settings=Cambiar ajustes para cálculos AACon
-label.align=Alinear
 label.mark_as_representative=Marcar como representativa
 label.include_description=Incluir Descripción
 label.for=para
@@ -1246,15 +1201,13 @@ info.associate_wit_sequence=Asociar con secuencia
 label.protein=Proteína
 warn.oneseq_msainput_selection=La selección actual sólo contiene una Ãºnica secuencia. Â¿Quieres enviar todas las secuencias para la alineación en su lugar?
 label.use_rnaview=Usar RNAView para estructura secondaria
-label.opens_the_jabaws_server_homepage=Abre la página de inicio del servidor JABAWS en navegador
 label.search_all=Introducir uno o más valores de búsqueda separados por punto y coma ";" (Nota: buscará en toda la base de datos PDB)
 label.confirm_close_chimera=Cerrará la conexión de Jalview a {0}.<br>¿Quieres cerrar la ventana Chimera también?
 tooltip.rnalifold_calculations=Se calcularán predicciones de estructura secondaria de RNA para el alineaminento, y se actualizarán si se efectuan cambios
-Calcular predicciónes de estructura secondaria para el alineamiento
+tooltip.rnalifold_settings=Modificar la configuración de la predicción RNAAlifold. Ãšselo para ocultar o mostrar resultados del cálculo de RNA, o cambiar parámetros de el plegado de RNA.
 label.show_selected_annotations=Mostrar anotaciones seleccionadas
 status.colouring_chimera=Coloreando Chimera
 label.configure_displayed_columns=Configurar Columnas Mostradas
-exception.pdb_server_error=Error desde el servidor PDB
 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
@@ -1263,10 +1216,8 @@ label.chimera_path=Ruta de acceso a programa Chimera
 warn.delete_all=<html>Borrar todas las secuencias cerrará la ventana del alineamiento.<br>Confirmar o Cancelar.
 label.select_all=Seleccionar Todos
 label.alpha_helix=Hélice Alfa
-label.sequence_details_for=Detalles de secuencia para {0}
 label.chimera_help=Ayuda para Chimera
 label.find_tip=Buscar alineamiento, selección o IDs de secuencia para una subsecuencia (sin huecos)
-exception.pdb_server_unreachable=Jalview no puede conectar con el servidor PDBE Solr.\nPor favor, asegúrese de que está conectado a Internet y vuelva a intentarlo.
 label.structure_viewer=Visualizador de estructura for 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.
@@ -1279,7 +1230,6 @@ info.select_filter_option=Escoger Opci
 info.invalid_msa_input_mininfo=Necesita por lo menos dos secuencias con al menos 3 residuos cada una, sin regiones ocultas entre ellas.
 label.chimera_missing=Visualizador de estructura Chimera no encontrado.<br/>Por favor, introduzca la ruta de Chimera,<br/>o descargar e instalar la UCSF Chimera.
 label.save_as_biojs_html=Guardar como HTML BioJs
-exception.pdb_rest_service_no_longer_available=Servicios Rest PDB ya no están disponibles!
 exception.fts_server_unreachable=Jalview no puede conectar con el servidor {0}. \nPor favor asegúrese de que está conectado a Internet y vuelva a intentarlo.
 exception.outofmemory_loading_mmcif_file=Sin memoria al cargar el fichero mmCIF
 label.hide_columns_not_containing=Ocultar las columnas que no contengan
@@ -1314,3 +1264,6 @@ status.fetching_3d_structures_for_selected_entries=Buscando las estructuras 3D p
 status.fetching_dbrefs_for_sequences_without_valid_refs=Buscando referencias para {0} secuencia(s) sin referencia válida necesaria para mapeado SIFTS
 status.obtaining_mapping_with_nw_alignment=Obteniendo mapeo por alineamiento Needleman y Wunsch
 status.exporting_alignment_as_x_file = Exportando alineamiento como fichero tipo {0}
+label.column = Columna
+label.cant_map_cds = No se pudo mapear CDS a proteína\nDatos CDS faltantes o incompletos
+label.operation_failed = Operación fallada
index ab038a0..fe6a0ac 100755 (executable)
@@ -81,7 +81,7 @@ public class Atom
     chain = str.substring(21, 22);
 
     resNumber = Integer.parseInt(str.substring(22, 26).trim());
-    resNumIns = str.substring(22, 27);
+    resNumIns = str.substring(22, 27).trim();
     insCode = str.substring(26, 27).charAt(0);
     this.x = (new Float(str.substring(30, 38).trim()).floatValue());
     this.y = (new Float(str.substring(38, 46).trim()).floatValue());
index ec5b6a1..dc57f6e 100644 (file)
@@ -2649,13 +2649,16 @@ public class AlignmentUtils
       return false; // should only pass alignments with datasets here
     }
 
-    // map from dataset sequence to alignment sequence
-    Map<SequenceI, SequenceI> alignedDatasets = new HashMap<SequenceI, SequenceI>();
+    // map from dataset sequence to alignment sequence(s)
+    Map<SequenceI, List<SequenceI>> alignedDatasets = new HashMap<SequenceI, List<SequenceI>>();
     for (SequenceI seq : aligned.getSequences())
     {
-      // JAL-2110: fail if two or more alignment sequences have a common dataset
-      // sequence.
-      alignedDatasets.put(seq.getDatasetSequence(), seq);
+      SequenceI ds = seq.getDatasetSequence();
+      if (alignedDatasets.get(ds) == null)
+      {
+        alignedDatasets.put(ds, new ArrayList<SequenceI>());
+      }
+      alignedDatasets.get(ds).add(seq);
     }
 
     /*
@@ -2671,17 +2674,22 @@ public class AlignmentUtils
     }
 
     /*
-     * second pass - copy aligned sequences
+     * second pass - copy aligned sequences;
+     * heuristic rule: pair off sequences in order for the case where 
+     * more than one shares the same dataset sequence 
      */
     for (SequenceI seq : unaligned.getSequences())
     {
-      SequenceI alignedSequence = alignedDatasets.get(seq
+      List<SequenceI> alignedSequences = alignedDatasets.get(seq
               .getDatasetSequence());
-      // JAL-2110: fail if two or more alignment sequences have common dataset
-      // sequence.
       // TODO: getSequenceAsString() will be deprecated in the future
       // TODO: need to leave to SequenceI implementor to update gaps
-      seq.setSequence(alignedSequence.getSequenceAsString());
+      seq.setSequence(alignedSequences.get(0).getSequenceAsString());
+      if (alignedSequences.size() > 0)
+      {
+        // pop off aligned sequences (except the last one)
+        alignedSequences.remove(0);
+      }
     }
 
     return true;
index 51a818f..2ddd015 100644 (file)
@@ -127,6 +127,11 @@ public class Grouping
         }
       }
     }
+
+    /*
+     * get selected columns (in the order they were selected);
+     * note this could include right-to-left ranges
+     */
     int[] spos = new int[cs.getSelected().size()];
     int width = -1;
     int i = 0;
@@ -134,7 +139,7 @@ public class Grouping
     {
       spos[i++] = pos.intValue();
     }
-    ;
+
     for (i = 0; i < sequences.length; i++)
     {
       int slen = sequences[i].getLength();
index 948c8e5..ec7cd25 100644 (file)
@@ -70,8 +70,6 @@ import java.util.Vector;
 public class APopupMenu extends java.awt.PopupMenu implements
         ActionListener, ItemListener
 {
-  private static final String ALL_ANNOTATIONS = "All";
-
   Menu groupMenu = new Menu();
 
   MenuItem editGroupName = new MenuItem();
@@ -966,7 +964,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
             "label.represent_group_with", new Object[] { "" }));
     revealAll.setLabel(MessageManager.getString("action.reveal_all"));
     revealSeq.setLabel(MessageManager.getString("action.reveal_sequences"));
-    menu1.setLabel(MessageManager.getString("label.group") + ":");
+    menu1.setLabel(MessageManager.getString("label.group:"));
     add(groupMenu);
     this.add(seqMenu);
     this.add(hideSeqs);
@@ -1326,7 +1324,8 @@ public class APopupMenu extends java.awt.PopupMenu implements
     showMenu.removeAll();
     hideMenu.removeAll();
 
-    final List<String> all = Arrays.asList(ALL_ANNOTATIONS);
+    final List<String> all = Arrays.asList(new String[] { MessageManager
+            .getString("label.all") });
     addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true, true);
     addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true,
             false);
index 849c05c..0312015 100644 (file)
@@ -3517,10 +3517,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     nucleotideColour.setLabel(MessageManager.getString("label.nucleotide"));
     nucleotideColour.addActionListener(this);
     modifyPID.setLabel(MessageManager
-            .getString("label.modify_identity_thereshold"));
+            .getString("label.modify_identity_threshold"));
     modifyPID.addActionListener(this);
     modifyConservation.setLabel(MessageManager
-            .getString("label.modify_conservation_thereshold"));
+            .getString("label.modify_conservation_threshold"));
     modifyConservation.addActionListener(this);
     annotationColour.setLabel(MessageManager
             .getString("action.by_annotation"));
index 57b182c..5a9cd55 100644 (file)
@@ -138,11 +138,11 @@ public class AnnotationColourChooser extends Panel implements
     }
 
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_no_thereshold"));
+            .getString("label.threshold_feature_no_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_above_thereshold"));
+            .getString("label.threshold_feature_above_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_below_thereshold"));
+            .getString("label.threshold_feature_below_threshold"));
 
     if (oldcs instanceof AnnotationColourGradient)
     {
@@ -162,7 +162,7 @@ public class AnnotationColourChooser extends Panel implements
       default:
         throw new Error(
                 MessageManager
-                        .getString("error.implementation_error_dont_know_thereshold_annotationcolourgradient"));
+                        .getString("error.implementation_error_dont_know_threshold_annotationcolourgradient"));
       }
       thresholdIsMin.setState(acg.thresholdIsMinMax);
       thresholdValue.setText("" + acg.getAnnotationThreshold());
index 77700d0..e5475f8 100755 (executable)
@@ -22,8 +22,11 @@ package jalview.appletgui;
 
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
 import jalview.renderer.AnnotationRenderer;
 import jalview.renderer.AwtRenderPanelI;
+import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
 import jalview.util.MessageManager;
 
 import java.awt.Color;
@@ -158,12 +161,12 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
     if (evt.getActionCommand().equals(REMOVE))
     {
-      for (int sel : av.getColumnSelection().getSelected())
+      for (int index : av.getColumnSelection().getSelected())
       {
-        // TODO: JAL-2001 check if applet has faulty 'REMOVE' selected columns
-        // of
-        // annotation if selection includes hidden columns
-        anot[sel] = null;
+        if (av.getColumnSelection().isVisible(index))
+        {
+          anot[index] = null;
+        }
       }
     }
     else if (evt.getActionCommand().equals(LABEL))
@@ -457,21 +460,67 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
       }
     }
 
-    int res = evt.getX() / av.getCharWidth() + av.getStartRes();
+    int column = evt.getX() / av.getCharWidth() + av.getStartRes();
 
     if (av.hasHiddenColumns())
     {
-      res = av.getColumnSelection().adjustForHiddenColumns(res);
+      column = av.getColumnSelection().adjustForHiddenColumns(column);
     }
 
-    if (row > -1 && res < aa[row].annotations.length
-            && aa[row].annotations[res] != null)
+    if (row > -1 && column < aa[row].annotations.length
+            && aa[row].annotations[column] != null)
     {
-      StringBuffer text = new StringBuffer("Sequence position " + (res + 1));
-      if (aa[row].annotations[res].description != null)
+      StringBuilder text = new StringBuilder();
+      text.append(MessageManager.getString("label.column")).append(" ")
+              .append(column + 1);
+      String description = aa[row].annotations[column].description;
+      if (description != null && description.length() > 0)
       {
-        text.append("  " + aa[row].annotations[res].description);
+        text.append("  ").append(description);
       }
+
+      /*
+       * if the annotation is sequence-specific, show the sequence number
+       * in the alignment, and (if not a gap) the residue and position
+       */
+      SequenceI seqref = aa[row].sequenceRef;
+      if (seqref != null)
+      {
+        int seqIndex = av.getAlignment().findIndex(seqref);
+        if (seqIndex != -1)
+        {
+          text.append(", ")
+                  .append(MessageManager.getString("label.sequence"))
+                  .append(" ").append(seqIndex + 1);
+          char residue = seqref.getCharAt(column);
+          if (!Comparison.isGap(residue))
+          {
+            text.append(" ");
+            String name;
+            if (av.getAlignment().isNucleotide())
+            {
+              name = ResidueProperties.nucleotideName.get(String
+                      .valueOf(residue));
+              text.append(" Nucleotide: ").append(
+                      name != null ? name : residue);
+            }
+            else
+            {
+              name = 'X' == residue ? "X" : ('*' == residue ? "STOP"
+                      : ResidueProperties.aa2Triplet.get(String
+                              .valueOf(residue)));
+              text.append(" Residue: ").append(
+                      name != null ? name : residue);
+            }
+            int residuePos = seqref.findPosition(column);
+            text.append(" (").append(residuePos).append(")");
+            // int residuePos = seqref.findPosition(column);
+            // text.append(residue).append(" (")
+            // .append(residuePos).append(")");
+          }
+        }
+      }
+
       ap.alignFrame.statusBar.setText(text.toString());
     }
   }
index 4cb5ede..fc49de5 100644 (file)
@@ -186,11 +186,11 @@ public abstract class AnnotationRowFilter extends Panel
   protected void populateThresholdComboBox(Choice threshold)
   {
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_no_thereshold"));
+            .getString("label.threshold_feature_no_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_above_thereshold"));
+            .getString("label.threshold_feature_above_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_below_thereshold"));
+            .getString("label.threshold_feature_below_threshold"));
   }
 
   public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
index 3c04ccd..0e85017 100644 (file)
@@ -191,11 +191,11 @@ public class FeatureColourChooser extends Panel implements ActionListener,
     jPanel4.setBackground(Color.white);
     threshold.addItemListener(this);
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_no_thereshold"));
+            .getString("label.threshold_feature_no_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_above_thereshold"));
+            .getString("label.threshold_feature_above_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_below_thereshold"));
+            .getString("label.threshold_feature_below_threshold"));
     thresholdValue.addActionListener(this);
     slider.setBackground(Color.white);
     slider.setEnabled(false);
index 81d8ef5..82736d7 100644 (file)
@@ -251,23 +251,24 @@ public class FeatureRenderer extends
 
     tmp = new Panel();
     panel.add(tmp);
-    tmp.add(new Label("Name: ", Label.RIGHT));
+    tmp.add(new Label(MessageManager.getString("label.name:"), Label.RIGHT));
     tmp.add(name);
 
     tmp = new Panel();
     panel.add(tmp);
-    tmp.add(new Label("Group: ", Label.RIGHT));
+    tmp.add(new Label(MessageManager.getString("label.group:"), Label.RIGHT));
     tmp.add(source);
 
     tmp = new Panel();
     panel.add(tmp);
-    tmp.add(new Label("Colour: ", Label.RIGHT));
+    tmp.add(new Label(MessageManager.getString("label.colour"), Label.RIGHT));
     tmp.add(colourPanel);
 
     bigPanel.add(panel, BorderLayout.NORTH);
 
     panel = new Panel();
-    panel.add(new Label("Description: ", Label.RIGHT));
+    panel.add(new Label(MessageManager.getString("label.description:"),
+            Label.RIGHT));
     panel.add(new ScrollPane().add(description));
 
     if (!newFeatures)
@@ -275,9 +276,11 @@ public class FeatureRenderer extends
       bigPanel.add(panel, BorderLayout.SOUTH);
 
       panel = new Panel();
-      panel.add(new Label(" Start:", Label.RIGHT));
+      panel.add(new Label(MessageManager.getString("label.start"),
+              Label.RIGHT));
       panel.add(start);
-      panel.add(new Label("  End:", Label.RIGHT));
+      panel.add(new Label(MessageManager.getString("label.end"),
+              Label.RIGHT));
       panel.add(end);
       bigPanel.add(panel, BorderLayout.CENTER);
     }
index 0f71818..d2c1693 100755 (executable)
@@ -409,22 +409,33 @@ public class ScalePanel extends Panel implements MouseMotionListener,
 
     // Fill the selected columns
     ColumnSelection cs = av.getColumnSelection();
-    gg.setColor(new Color(220, 0, 0));
     int avCharWidth = av.getCharWidth();
     int avcharHeight = av.getCharHeight();
-    for (int sel : cs.getSelected())
+    if (cs != null)
     {
-      // TODO: JAL-2001 - provide a fast method to list visible selected in a
-      // given range
-      if (av.hasHiddenColumns())
+      gg.setColor(new Color(220, 0, 0));
+      boolean hasHiddenColumns = cs.hasHiddenColumns();
+      for (int sel : cs.getSelected())
       {
-        sel = av.getColumnSelection().findColumnPosition(sel);
-      }
+        // TODO: JAL-2001 - provide a fast method to list visible selected in a
+        // given range
+        if (hasHiddenColumns)
+        {
+          if (cs.isVisible(sel))
+          {
+            sel = cs.findColumnPosition(sel);
+          }
+          else
+          {
+            continue;
+          }
+        }
 
-      if ((sel >= startx) && (sel <= endx))
-      {
-        gg.fillRect((sel - startx) * avCharWidth, 0, avCharWidth,
-                getSize().height);
+        if ((sel >= startx) && (sel <= endx))
+        {
+          gg.fillRect((sel - startx) * avCharWidth, 0, avCharWidth,
+                  getSize().height);
+        }
       }
     }
 
@@ -471,12 +482,10 @@ public class ScalePanel extends Panel implements MouseMotionListener,
       if (av.getShowHiddenMarkers())
       {
         int widthx = 1 + endx - startx;
-        for (int i = 0; i < av.getColumnSelection().getHiddenColumns()
-                .size(); i++)
+        for (int i = 0; i < cs.getHiddenColumns().size(); i++)
         {
 
-          res = av.getColumnSelection().findHiddenRegionPosition(i)
-                  - startx;
+          res = cs.findHiddenRegionPosition(i) - startx;
 
           if (res < 0 || res > widthx)
           {
index 2fc15d0..2c53c08 100644 (file)
@@ -132,7 +132,7 @@ public class SliderPanel extends Panel implements ActionListener,
       pid.cs = cs;
     }
     PIDSlider.setTitle(MessageManager
-            .formatMessage("label.percentage_identity_thereshold",
+            .formatMessage("label.percentage_identity_threshold",
                     new String[] { source }));
 
     if (ap.av.getAlignment().getGroups() != null)
index 76fdb69..df71ccc 100755 (executable)
@@ -244,8 +244,8 @@ public class Cache
    * even if the user changes their locale setting
    */
   private static final DateFormat date_format = SimpleDateFormat
-          .getDateTimeInstance(SimpleDateFormat.LONG,
-                  SimpleDateFormat.LONG, Locale.UK);
+          .getDateTimeInstance(SimpleDateFormat.MEDIUM,
+                  SimpleDateFormat.MEDIUM, Locale.UK);
 
   /**
    * Initialises the Jalview Application Log
index 764c92c..3294c26 100755 (executable)
@@ -328,7 +328,6 @@ public class Jalview
             Cache.log.debug("Starting questionnaire with default url: "
                     + defurl);
             desktop.checkForQuestionnaire(defurl);
-
           }
         }
       }
@@ -336,14 +335,12 @@ public class Jalview
       {
         System.err.println("CMD [-noquestionnaire] executed successfully!");
       }
+
       if (!aparser.contains("nonews"))
       {
         desktop.checkForNews();
       }
-    }
 
-    if (!isHeadlessMode())
-    {
       BioJsHTMLOutput.updateBioJS();
     }
 
@@ -785,6 +782,7 @@ public class Jalview
                     + "-eps FILE\tCreate EPS file FILE from alignment.\n"
                     + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
                     + "-noquestionnaire\tTurn off questionnaire check.\n"
+                    + "-nonews\tTurn off check for Jalview news.\n"
                     + "-nousagestats\tTurn off google analytics tracking for this session.\n"
                     + "-sortbytree OR -nosortbytree\tEnable or disable sorting of the given alignment by the given tree\n"
                     // +
index 13e4b7e..210a07a 100644 (file)
@@ -466,17 +466,11 @@ public class JalviewLite extends Applet implements
         SequenceI rs = sel.getSequenceAt(0);
         start = rs.findIndex(start);
         end = rs.findIndex(end);
-        if (csel != null)
-        {
-          List<Integer> cs = csel.getSelected();
-          // note - the following actually clears cs as well, since
-          // csel.getSelected returns a reference. Need to check if we need to
-          // have a concurrentModification exception thrown here
-          csel.clear();
-          for (Integer selectedCol : cs)
-          {
-            csel.addElement(rs.findIndex(selectedCol));
-          }
+        List<Integer> cs = csel.getSelected();
+        csel.clear();
+        for (Integer selectedCol : cs)
+        {
+          csel.addElement(rs.findIndex(selectedCol));
         }
       }
       sel.setStartRes(start);
index 24439ca..f508bc3 100644 (file)
@@ -169,157 +169,136 @@ public class AlignViewController implements AlignViewControllerI
     // JBPNote this routine could also mark rows, not just columns.
     // need a decent query structure to allow all types of feature searches
     BitSet bs = new BitSet();
-    int alw, alStart;
-    SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null ? viewport
-            .getAlignment() : viewport.getSelectionGroup());
-    alStart = sqcol.getStartRes();
-    alw = sqcol.getEndRes() + 1;
+    SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null || extendCurrent) ? viewport
+            .getAlignment() : viewport.getSelectionGroup();
+
+    int nseq = findColumnsWithFeature(featureType, sqcol, bs);
+
+    ColumnSelection cs = viewport.getColumnSelection();
+    if (cs == null)
+    {
+      cs = new ColumnSelection();
+    }
+
+    if (bs.cardinality() > 0 || invert)
+    {
+      boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
+              sqcol.getEndRes(), invert, extendCurrent, toggle);
+      if (changed)
+      {
+        viewport.setColumnSelection(cs);
+        alignPanel.paintAlignment(true);
+        int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
+                - bs.cardinality()
+                : bs.cardinality();
+        avcg.setStatus(MessageManager.formatMessage(
+                "label.view_controller_toggled_marked",
+                new String[] {
+                    toggle ? MessageManager.getString("label.toggled")
+                            : MessageManager.getString("label.marked"),
+                    String.valueOf(columnCount),
+                    invert ? MessageManager
+                            .getString("label.not_containing")
+                            : MessageManager.getString("label.containing"),
+                    featureType, Integer.valueOf(nseq).toString() }));
+        return true;
+      }
+    }
+    else
+    {
+      avcg.setStatus(MessageManager.formatMessage(
+              "label.no_feature_of_type_found",
+              new String[] { featureType }));
+      if (!extendCurrent)
+      {
+        cs.clear();
+        alignPanel.paintAlignment(true);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Sets a bit in the BitSet for each column (base 0) in the sequence
+   * collection which includes the specified feature type. Returns the number of
+   * sequences which have the feature in the selected range.
+   * 
+   * @param featureType
+   * @param sqcol
+   * @param bs
+   * @return
+   */
+  static int findColumnsWithFeature(String featureType,
+          SequenceCollectionI sqcol, BitSet bs)
+  {
+    final int startPosition = sqcol.getStartRes() + 1; // converted to base 1
+    final int endPosition = sqcol.getEndRes() + 1;
     List<SequenceI> seqs = sqcol.getSequences();
     int nseq = 0;
     for (SequenceI sq : seqs)
     {
-      int tfeat = 0;
+      boolean sequenceHasFeature = false;
       if (sq != null)
       {
-        SequenceFeature[] sf = sq.getSequenceFeatures();
-        if (sf != null)
+        SequenceFeature[] sfs = sq.getSequenceFeatures();
+        if (sfs != null)
         {
+          /*
+           * check whether the feature start/end (base 1) 
+           * overlaps the selection start/end
+           */
           int ist = sq.findIndex(sq.getStart());
           int iend = sq.findIndex(sq.getEnd());
-          if (iend < alStart || ist > alw)
+          if (iend < startPosition || ist > endPosition)
           {
             // sequence not in region
             continue;
           }
-          for (SequenceFeature sfpos : sf)
+          for (SequenceFeature sf : sfs)
           {
-            // future functionalty - featureType == null means mark columns
+            // future functionality - featureType == null means mark columns
             // containing all displayed features
-            if (sfpos != null && (featureType.equals(sfpos.getType())))
+            if (sf != null && (featureType.equals(sf.getType())))
             {
-              tfeat++;
               // optimisation - could consider 'spos,apos' like cursor argument
               // - findIndex wastes time by starting from first character and
               // counting
 
-              int i = sq.findIndex(sfpos.getBegin());
-              int j = sq.findIndex(sfpos.getEnd());
-              if (j < alStart || i > alw)
+              int i = sq.findIndex(sf.getBegin());
+              int j = sq.findIndex(sf.getEnd());
+              if (j < startPosition || i > endPosition)
               {
                 // feature is outside selected region
                 continue;
               }
-              if (i < alStart)
+              sequenceHasFeature = true;
+              if (i < startPosition)
               {
-                i = alStart;
+                i = startPosition;
               }
               if (i < ist)
               {
                 i = ist;
               }
-              if (j > alw)
+              if (j > endPosition)
               {
-                j = alw;
+                j = endPosition;
               }
               for (; i <= j; i++)
               {
-                bs.set(i - 1);
+                bs.set(i - 1); // convert to base 0
               }
             }
           }
         }
 
-        if (tfeat > 0)
+        if (sequenceHasFeature)
         {
           nseq++;
         }
       }
     }
-    ColumnSelection cs = viewport.getColumnSelection();
-    if (bs.cardinality() > 0 || invert)
-    {
-      boolean changed = false;
-      if (cs == null)
-      {
-        cs = new ColumnSelection();
-      }
-      else
-      {
-        if (!extendCurrent)
-        {
-          changed = !cs.isEmpty();
-          cs.clear();
-        }
-      }
-      if (invert)
-      {
-        // invert only in the currently selected sequence region
-        for (int i = bs.nextClearBit(alStart), ibs = bs.nextSetBit(alStart); i >= alStart
-                && i < (alw);)
-        {
-          if (ibs < 0 || i < ibs)
-          {
-            changed = true;
-            if (toggle && cs.contains(i))
-            {
-              cs.removeElement(i++);
-            }
-            else
-            {
-              cs.addElement(i++);
-            }
-          }
-          else
-          {
-            i = bs.nextClearBit(ibs);
-            ibs = bs.nextSetBit(i);
-          }
-        }
-      }
-      else
-      {
-        for (int i = bs.nextSetBit(alStart); i >= alStart; i = bs
-                .nextSetBit(i + 1))
-        {
-          changed = true;
-          if (toggle && cs.contains(i))
-          {
-            cs.removeElement(i);
-          }
-          else
-          {
-            cs.addElement(i);
-          }
-        }
-      }
-      if (changed)
-      {
-        viewport.setColumnSelection(cs);
-        alignPanel.paintAlignment(true);
-        avcg.setStatus(MessageManager.formatMessage(
-                "label.view_controller_toggled_marked",
-                new String[] {
-                    (toggle ? MessageManager.getString("label.toggled")
-                            : MessageManager.getString("label.marked")),
-                    (invert ? (Integer.valueOf((alw - alStart)
-                            - bs.cardinality()).toString()) : (Integer
-                            .valueOf(bs.cardinality()).toString())),
-                    featureType, Integer.valueOf(nseq).toString() }));
-        return true;
-      }
-    }
-    else
-    {
-      avcg.setStatus(MessageManager.formatMessage(
-              "label.no_feature_of_type_found",
-              new String[] { featureType }));
-      if (!extendCurrent && cs != null)
-      {
-        cs.clear();
-        alignPanel.paintAlignment(true);
-      }
-    }
-    return false;
+    return nseq;
   }
 
   @Override
index fa72e80..9db9f38 100644 (file)
@@ -277,8 +277,7 @@ public class AlignmentView
     if (!seqcigararray.isSeqCigarArray())
     {
       throw new Error(
-              MessageManager
-                      .getString("error.implementation_error_can_only_make_alignmnet_from_cigararray"));
+              "Implementation Error - can only make an alignment view from a CigarArray of sequences.");
     }
     // contigs = seqcigararray.applyDeletions();
     contigs = seqcigararray.getDeletedRegions();
index aaf70b8..7ef2a68 100644 (file)
@@ -290,11 +290,12 @@ public class ColumnSelection
   /**
    * Returns a list of selected columns. The list contains no duplicates but is
    * not necessarily ordered. It also may include columns hidden from the
-   * current view
+   * current view. This returns a copy of the actual list, and changes to the
+   * copy will not affect the selection.
    */
   public List<Integer> getSelected()
   {
-    return selection.getList();
+    return new ArrayList<Integer>(selection.getList());
   }
 
   /**
@@ -985,7 +986,7 @@ public class ColumnSelection
           SequenceI[] seqs)
   {
     int i, iSize = seqs.length;
-    String selection[] = new String[iSize];
+    String selections[] = new String[iSize];
     if (hiddenColumns != null && hiddenColumns.size() > 0)
     {
       for (i = 0; i < iSize; i++)
@@ -1027,18 +1028,18 @@ public class ColumnSelection
           visibleSeq.append(seqs[i].getSequence(blockStart, end));
         }
 
-        selection[i] = visibleSeq.toString();
+        selections[i] = visibleSeq.toString();
       }
     }
     else
     {
       for (i = 0; i < iSize; i++)
       {
-        selection[i] = seqs[i].getSequenceAsString(start, end);
+        selections[i] = seqs[i].getSequenceAsString(start, end);
       }
     }
 
-    return selection;
+    return selections;
   }
 
   /**
@@ -1703,4 +1704,78 @@ public class ColumnSelection
     return true;
   }
 
+  /**
+   * Updates the column selection depending on the parameters, and returns true
+   * if any change was made to the selection
+   * 
+   * @param markedColumns
+   *          a set identifying marked columns (base 0)
+   * @param startCol
+   *          the first column of the range to operate over (base 0)
+   * @param endCol
+   *          the last column of the range to operate over (base 0)
+   * @param invert
+   *          if true, deselect marked columns and select unmarked
+   * @param extendCurrent
+   *          if true, extend rather than replacing the current column selection
+   * @param toggle
+   *          if true, toggle the selection state of marked columns
+   * 
+   * @return
+   */
+  public boolean markColumns(BitSet markedColumns, int startCol,
+          int endCol, boolean invert, boolean extendCurrent, boolean toggle)
+  {
+    boolean changed = false;
+    if (!extendCurrent && !toggle)
+    {
+      changed = !this.isEmpty();
+      clear();
+    }
+    if (invert)
+    {
+      // invert only in the currently selected sequence region
+      int i = markedColumns.nextClearBit(startCol);
+      int ibs = markedColumns.nextSetBit(startCol);
+      while (i >= startCol && i <= endCol)
+      {
+        if (ibs < 0 || i < ibs)
+        {
+          changed = true;
+          if (toggle && contains(i))
+          {
+            removeElement(i++);
+          }
+          else
+          {
+            addElement(i++);
+          }
+        }
+        else
+        {
+          i = markedColumns.nextClearBit(ibs);
+          ibs = markedColumns.nextSetBit(i);
+        }
+      }
+    }
+    else
+    {
+      int i = markedColumns.nextSetBit(startCol);
+      while (i >= startCol && i <= endCol)
+      {
+        changed = true;
+        if (toggle && contains(i))
+        {
+          removeElement(i);
+        }
+        else
+        {
+          addElement(i);
+        }
+        i = markedColumns.nextSetBit(i + 1);
+      }
+    }
+    return changed;
+  }
+
 }
index 8688720..3ba36ca 100644 (file)
@@ -49,8 +49,7 @@ import java.util.regex.Pattern;
  * Castor binding file
  * 
  * For example:
- * http://www.ebi.ac.uk/Tools/dbfetch/dbfetch?db=ena_sequence&id=J03321
- * &format=emblxml
+ * http://www.ebi.ac.uk/ena/data/view/J03321&display=xml
  * 
  * @see embl_mapping.xml
  */
@@ -188,6 +187,10 @@ public class EmblEntry
   public SequenceI getSequence(String sourceDb, List<SequenceI> peptides)
   {
     SequenceI dna = makeSequence(sourceDb);
+    if (dna == null)
+    {
+      return null;
+    }
     dna.setDescription(description);
     DBRefEntry retrievedref = new DBRefEntry(sourceDb,
             getSequenceVersion(), accession);
@@ -239,6 +242,12 @@ public class EmblEntry
    */
   SequenceI makeSequence(String sourceDb)
   {
+    if (sequence == null)
+    {
+      System.err.println("No sequence was returned for ENA accession "
+              + accession);
+      return null;
+    }
     SequenceI dna = new Sequence(sourceDb + "|" + accession,
             sequence.getSequence());
     return dna;
index f9cfe05..72efdc1 100644 (file)
@@ -35,9 +35,11 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
    * changes to Ensembl REST API
    * @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
    */
-  private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.4";
+  private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.6";
 
-  private static final String LATEST_ENSEMBL_REST_VERSION = "4.5";
+  private static final String LATEST_ENSEMBL_REST_VERSION = "4.6";
+
+  private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
 
   private static Map<String, EnsemblInfo> domainData;
 
@@ -453,9 +455,8 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
       if (laterVersion)
       {
         System.err.println(String.format(
-                "Expected %s REST version %s but found %s", getDbSource(),
-                expected,
-                version));
+                "Expected %s REST version %s but found %s, see %s",
+                getDbSource(), expected, version, REST_CHANGE_LOG));
       }
       info.restVersion = version;
     } catch (Throwable t)
index ea969ff..848e7db 100644 (file)
@@ -217,7 +217,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener
         curAtom.resNumber = atom.getResno();
         curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
                 .getIndex()] : Float.valueOf(atom.getOccupancy100());
-        curAtom.resNumIns = "" + curAtom.resNumber + curAtom.insCode;
+        curAtom.resNumIns = ("" + curAtom.resNumber + curAtom.insCode)
+                .trim();
         curAtom.tfactor = atom.getBfactor100() / 100f;
         curAtom.type = 0;
         // significantAtoms.add(curAtom);
index b0debf8..f6268c0 100644 (file)
@@ -849,8 +849,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     showGroupConservation.setEnabled(!nucleotide);
     rnahelicesColour.setEnabled(nucleotide);
     purinePyrimidineColour.setEnabled(nucleotide);
-    showComplementMenuItem.setText(MessageManager
-            .getString(nucleotide ? "label.protein" : "label.nucleotide"));
+    showComplementMenuItem.setText(nucleotide ? MessageManager
+            .getString("label.protein") : MessageManager
+            .getString("label.nucleotide"));
     setColourSelected(jalview.bin.Cache.getDefault(
             nucleotide ? Preferences.DEFAULT_COLOUR_NUC
                     : Preferences.DEFAULT_COLOUR_PROT, "None"));
@@ -3219,30 +3220,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   /**
-   * Set or clear 'Show Sequence Features'
-   * 
-   * @param evt
-   *          DOCUMENT ME!
-   */
-  @Override
-  public void showSeqFeaturesHeight_actionPerformed(ActionEvent evt)
-  {
-    viewport.setShowSequenceFeaturesHeight(showSeqFeaturesHeight
-            .isSelected());
-    if (viewport.isShowSequenceFeaturesHeight())
-    {
-      // ensure we're actually displaying features
-      viewport.setShowSequenceFeatures(true);
-      showSeqFeatures.setSelected(true);
-    }
-    alignPanel.paintAlignment(true);
-    if (alignPanel.getOverviewPanel() != null)
-    {
-      alignPanel.getOverviewPanel().updateOverviewImage();
-    }
-  }
-
-  /**
    * Action on toggle of the 'Show annotations' menu item. This shows or hides
    * the annotations panel as a whole.
    * 
@@ -4467,22 +4444,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           // object broker mechanism.
           final Vector<JMenu> wsmenu = new Vector<JMenu>();
           final IProgressIndicator af = me;
+
+          /*
+           * do not i18n these strings - they are hard-coded in class
+           * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
+           * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
+           */
           final JMenu msawsmenu = new JMenu("Alignment");
           final JMenu secstrmenu = new JMenu(
                   "Secondary Structure Prediction");
           final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
           final JMenu analymenu = new JMenu("Analysis");
           final JMenu dismenu = new JMenu("Protein Disorder");
-          // final JMenu msawsmenu = new
-          // JMenu(MessageManager.getString("label.alignment"));
-          // final JMenu secstrmenu = new
-          // JMenu(MessageManager.getString("label.secondary_structure_prediction"));
-          // final JMenu seqsrchmenu = new
-          // JMenu(MessageManager.getString("label.sequence_database_search"));
-          // final JMenu analymenu = new
-          // JMenu(MessageManager.getString("label.analysis"));
-          // final JMenu dismenu = new
-          // JMenu(MessageManager.getString("label.protein_disorder"));
           // JAL-940 - only show secondary structure prediction services from
           // the legacy server
           if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
@@ -4765,6 +4738,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                       xrefsAlignment.getSequencesArray());
               if (copyAlignment.getHeight() == 0)
               {
+                JOptionPane.showMessageDialog(AlignFrame.this,
+                        MessageManager.getString("label.cant_map_cds"),
+                        MessageManager.getString("label.operation_failed"),
+                        JOptionPane.OK_OPTION);
                 System.err.println("Failed to make CDS alignment");
               }
 
@@ -4832,8 +4809,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           {
             newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
           }
-          String newtitle = String.format("%s %s %s", MessageManager
-                  .getString(dna ? "label.proteins" : "label.nucleotides"),
+          String newtitle = String.format("%s %s %s",
+                  dna ? MessageManager.getString("label.proteins")
+                          : MessageManager.getString("label.nucleotides"),
                   MessageManager.getString("label.for"), getTitle());
           newFrame.setTitle(newtitle);
 
index b1a4fee..62e05d0 100644 (file)
@@ -507,17 +507,6 @@ public class AlignViewport extends AlignmentViewport implements
   /**
    * DOCUMENT ME!
    * 
-   * @return DOCUMENT ME!
-   */
-  @Override
-  public ColumnSelection getColumnSelection()
-  {
-    return colSel;
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
    * @param tree
    *          DOCUMENT ME!
    */
index f06ca94..87d5933 100644 (file)
@@ -1269,6 +1269,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
   void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file)
   {
+    int boarderBottomOffset = 5;
     long pSessionId = System.currentTimeMillis();
     headless = (System.getProperty("java.awt.headless") != null && System
             .getProperty("java.awt.headless").equals("true"));
@@ -1305,14 +1306,15 @@ public class AlignmentPanel extends GAlignmentPanel implements
         }
 
         im = new jalview.util.ImageMaker(this, type, imageAction,
-                aDimension.getWidth(), aDimension.getHeight(), file,
+                aDimension.getWidth(), aDimension.getHeight()
+                        + boarderBottomOffset, file,
                 imageTitle, alignFrame, pSessionId, headless);
         if (av.getWrapAlignment())
         {
           if (im.getGraphics() != null)
           {
             printWrappedAlignment(im.getGraphics(), aDimension.getWidth(),
-                    aDimension.getHeight(), 0);
+                    aDimension.getHeight() + boarderBottomOffset, 0);
             im.writeImage();
           }
         }
index 19eed27..93c9a6b 100644 (file)
@@ -141,7 +141,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       default:
         throw new Error(
                 MessageManager
-                        .getString("error.implementation_error_dont_know_about_thereshold_setting"));
+                        .getString("error.implementation_error_dont_know_about_threshold_setting"));
       }
       thresholdIsMin.setSelected(acg.thresholdIsMinMax);
       thresholdValue.setText("" + acg.getAnnotationThreshold());
index bb311ef..3c9a13e 100755 (executable)
@@ -26,6 +26,8 @@ import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.AnnotationRenderer;
 import jalview.renderer.AwtRenderPanelI;
+import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
 import jalview.util.MessageManager;
 
 import java.awt.AlphaComposite;
@@ -47,6 +49,8 @@ import java.awt.event.MouseMotionListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.awt.image.BufferedImage;
+import java.util.Collections;
+import java.util.List;
 
 import javax.swing.JColorChooser;
 import javax.swing.JMenuItem;
@@ -288,9 +292,12 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
 
     if (evt.getActionCommand().equals(REMOVE))
     {
-      for (int sel : av.getColumnSelection().getSelected())
+      for (int index : av.getColumnSelection().getSelected())
       {
-        anot[sel] = null;
+        if (av.getColumnSelection().isVisible(index))
+        {
+          anot[index] = null;
+        }
       }
     }
     else if (evt.getActionCommand().equals(LABEL))
@@ -351,7 +358,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       }
     }
     else
-    // HELIX OR SHEET
+    // HELIX, SHEET or STEM
     {
       char type = 0;
       String symbol = "\u03B1";
@@ -412,22 +419,37 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
 
       }
     }
+
     av.getAlignment().validateAnnotation(aa[activeRow]);
     ap.alignmentChanged();
-
+    ap.alignFrame.setMenusForViewport();
     adjustPanelHeight();
     repaint();
 
     return;
   }
 
-  private String collectAnnotVals(Annotation[] anot, String label2)
+  /**
+   * Returns any existing annotation concatenated as a string. For each
+   * annotation, takes the description, if any, else the secondary structure
+   * character (if type is HELIX, SHEET or STEM), else the display character (if
+   * type is LABEL).
+   * 
+   * @param anots
+   * @param type
+   * @return
+   */
+  private String collectAnnotVals(Annotation[] anots, String type)
   {
-    String collatedInput = "";
+    // TODO is this method wanted? why? 'last' is not used
+
+    StringBuilder collatedInput = new StringBuilder(64);
     String last = "";
     ColumnSelection viscols = av.getColumnSelection();
     // TODO: refactor and save av.getColumnSelection for efficiency
-    for (int index : viscols.getSelected())
+    List<Integer> selected = viscols.getSelected();
+    Collections.sort(selected);
+    for (int index : selected)
     {
       // always check for current display state - just in case
       if (!viscols.isVisible(index))
@@ -435,22 +457,22 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         continue;
       }
       String tlabel = null;
-      if (anot[index] != null)
+      if (anots[index] != null)
       { // LML added stem code
-        if (label2.equals(HELIX) || label2.equals(SHEET)
-                || label2.equals(STEM) || label2.equals(LABEL))
+        if (type.equals(HELIX) || type.equals(SHEET)
+                || type.equals(STEM) || type.equals(LABEL))
         {
-          tlabel = anot[index].description;
+          tlabel = anots[index].description;
           if (tlabel == null || tlabel.length() < 1)
           {
-            if (label2.equals(HELIX) || label2.equals(SHEET)
-                    || label2.equals(STEM))
+            if (type.equals(HELIX) || type.equals(SHEET)
+                    || type.equals(STEM))
             {
-              tlabel = "" + anot[index].secondaryStructure;
+              tlabel = "" + anots[index].secondaryStructure;
             }
             else
             {
-              tlabel = "" + anot[index].displayCharacter;
+              tlabel = "" + anots[index].displayCharacter;
             }
           }
         }
@@ -458,13 +480,13 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         {
           if (last.length() > 0)
           {
-            collatedInput += " ";
+            collatedInput.append(" ");
           }
-          collatedInput += tlabel;
+          collatedInput.append(tlabel);
         }
       }
     }
-    return collatedInput;
+    return collatedInput.toString();
   }
 
   /**
@@ -628,10 +650,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
   }
 
   /**
-   * DOCUMENT ME!
+   * Constructs the tooltip, and constructs and displays a status message, for
+   * the current mouse position
    * 
    * @param evt
-   *          DOCUMENT ME!
    */
   @Override
   public void mouseMoved(MouseEvent evt)
@@ -657,7 +679,6 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       if (evt.getY() < height)
       {
         row = i;
-
         break;
       }
     }
@@ -668,64 +689,140 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       return;
     }
 
-    int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();
+    int column = (evt.getX() / av.getCharWidth()) + av.getStartRes();
 
     if (av.hasHiddenColumns())
     {
-      res = av.getColumnSelection().adjustForHiddenColumns(res);
+      column = av.getColumnSelection().adjustForHiddenColumns(column);
     }
 
-    if (row > -1 && aa[row].annotations != null
-            && res < aa[row].annotations.length)
+    AlignmentAnnotation ann = aa[row];
+    if (row > -1 && ann.annotations != null
+            && column < ann.annotations.length)
     {
-      if (aa[row].graphGroup > -1)
+      buildToolTip(ann, column, aa);
+      setStatusMessage(column, ann);
+    }
+    else
+    {
+      this.setToolTipText(null);
+      ap.alignFrame.statusBar.setText(" ");
+    }
+  }
+
+  /**
+   * Builds a tooltip for the annotation at the current mouse position.
+   * 
+   * @param ann
+   * @param column
+   * @param anns
+   */
+  void buildToolTip(AlignmentAnnotation ann, int column,
+          AlignmentAnnotation[] anns)
+  {
+    if (ann.graphGroup > -1)
+    {
+      StringBuilder tip = new StringBuilder(32);
+      tip.append("<html>");
+      for (int i = 0; i < anns.length; i++)
       {
-        StringBuffer tip = new StringBuffer("<html>");
-        for (int gg = 0; gg < aa.length; gg++)
+        if (anns[i].graphGroup == ann.graphGroup
+                && anns[i].annotations[column] != null)
         {
-          if (aa[gg].graphGroup == aa[row].graphGroup
-                  && aa[gg].annotations[res] != null)
+          tip.append(anns[i].label);
+          String description = anns[i].annotations[column].description;
+          if (description != null && description.length() > 0)
           {
-            tip.append(aa[gg].label + " "
-                    + aa[gg].annotations[res].description + "<br>");
+            tip.append(" ").append(description);
           }
-        }
-        if (tip.length() != 6)
-        {
-          tip.setLength(tip.length() - 4);
-          this.setToolTipText(tip.toString() + "</html>");
+          tip.append("<br>");
         }
       }
-      else if (aa[row].annotations[res] != null
-              && aa[row].annotations[res].description != null
-              && aa[row].annotations[res].description.length() > 0)
+      if (tip.length() != 6)
       {
-        this.setToolTipText(JvSwingUtils.wrapTooltip(true,
-                aa[row].annotations[res].description));
+        tip.setLength(tip.length() - 4);
+        this.setToolTipText(tip.toString() + "</html>");
       }
-      else
+    }
+    else if (ann.annotations[column] != null)
+    {
+      String description = ann.annotations[column].description;
+      if (description != null && description.length() > 0)
       {
-        // clear the tooltip.
-        this.setToolTipText(null);
+        this.setToolTipText(JvSwingUtils.wrapTooltip(true, description));
       }
+    }
+    else
+    {
+      // clear the tooltip.
+      this.setToolTipText(null);
+    }
+  }
 
-      if (aa[row].annotations[res] != null)
+  /**
+   * Constructs and displays the status bar message
+   * 
+   * @param column
+   * @param ann
+   */
+  void setStatusMessage(int column, AlignmentAnnotation ann)
+  {
+    /*
+     * show alignment column and annotation description if any
+     */
+    StringBuilder text = new StringBuilder(32);
+    text.append(MessageManager.getString("label.column")).append(" ")
+            .append(column + 1);
+
+    if (ann.annotations[column] != null)
+    {
+      String description = ann.annotations[column].description;
+      if (description != null && description.trim().length() > 0)
       {
-        StringBuffer text = new StringBuffer("Sequence position "
-                + (res + 1));
+        text.append("  ").append(description);
+      }
+    }
 
-        if (aa[row].annotations[res].description != null)
+    /*
+     * if the annotation is sequence-specific, show the sequence number
+     * in the alignment, and (if not a gap) the residue and position
+     */
+    SequenceI seqref = ann.sequenceRef;
+    if (seqref != null)
+    {
+      int seqIndex = av.getAlignment().findIndex(seqref);
+      if (seqIndex != -1)
+      {
+        text.append(", ")
+                .append(MessageManager.getString("label.sequence"))
+                .append(" ")
+                .append(seqIndex + 1);
+        char residue = seqref.getCharAt(column);
+        if (!Comparison.isGap(residue))
         {
-          text.append("  " + aa[row].annotations[res].description);
+          text.append(" ");
+          String name;
+          if (av.getAlignment().isNucleotide())
+          {
+            name = ResidueProperties.nucleotideName.get(String
+                    .valueOf(residue));
+            text.append(" Nucleotide: ").append(
+                    name != null ? name : residue);
+          }
+          else
+          {
+            name = 'X' == residue ? "X" : ('*' == residue ? "STOP"
+                    : ResidueProperties.aa2Triplet.get(String
+                            .valueOf(residue)));
+            text.append(" Residue: ").append(name != null ? name : residue);
+          }
+          int residuePos = seqref.findPosition(column);
+          text.append(" (").append(residuePos).append(")");
         }
-
-        ap.alignFrame.statusBar.setText(text.toString());
       }
     }
-    else
-    {
-      this.setToolTipText(null);
-    }
+
+    ap.alignFrame.statusBar.setText(text.toString());
   }
 
   /**
index 17298ba..f0bea60 100644 (file)
@@ -257,11 +257,11 @@ public abstract class AnnotationRowFilter extends JPanel
   protected void populateThresholdComboBox(JComboBox<String> threshold)
   {
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_no_thereshold"));
+            .getString("label.threshold_feature_no_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_above_thereshold"));
+            .getString("label.threshold_feature_above_threshold"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_below_thereshold"));
+            .getString("label.threshold_feature_below_threshold"));
   }
 
   protected void seqAssociated_actionPerformed(ActionEvent arg0,
index b176672..e677084 100644 (file)
@@ -448,7 +448,7 @@ public class DasSourceBrowser extends GDasSourceBrowser implements
     seqs.setSelected(seqsrc);
     JPanel panel = new JPanel(new BorderLayout());
     JPanel pane12 = new JPanel(new BorderLayout());
-    pane12.add(new JLabel(MessageManager.getString("label.name")),
+    pane12.add(new JLabel(MessageManager.getString("label.name:")),
             BorderLayout.CENTER);
     pane12.add(nametf, BorderLayout.EAST);
     panel.add(pane12, BorderLayout.NORTH);
index 79217ea..5594e1a 100644 (file)
@@ -242,11 +242,11 @@ public class FeatureColourChooser extends JalviewDialog
     threshold.setToolTipText(MessageManager
             .getString("label.threshold_feature_display_by_score"));
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_no_thereshold")); // index 0
+            .getString("label.threshold_feature_no_threshold")); // index 0
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_above_thereshold")); // index 1
+            .getString("label.threshold_feature_above_threshold")); // index 1
     threshold.addItem(MessageManager
-            .getString("label.threshold_feature_below_thereshold")); // index 2
+            .getString("label.threshold_feature_below_threshold")); // index 2
     jPanel3.setLayout(flowLayout2);
     thresholdValue.addActionListener(new ActionListener()
     {
@@ -263,7 +263,7 @@ public class FeatureColourChooser extends JalviewDialog
     slider.setOpaque(false);
     slider.setPreferredSize(new Dimension(100, 32));
     slider.setToolTipText(MessageManager
-            .getString("label.adjust_thereshold"));
+            .getString("label.adjust_threshold"));
     thresholdValue.setEnabled(false);
     thresholdValue.setColumns(7);
     jPanel3.setBackground(Color.white);
index 727c13b..426ea32 100644 (file)
@@ -173,7 +173,8 @@ public class FeatureRenderer extends
     {
       panel = new JPanel(new GridLayout(4, 1));
       tmp = new JPanel();
-      tmp.add(new JLabel(MessageManager.getString("label.select_feature")));
+      tmp.add(new JLabel(MessageManager.getString("label.select_feature")
+              + ":"));
       overlaps = new JComboBox();
       for (int i = 0; i < features.length; i++)
       {
@@ -224,12 +225,13 @@ public class FeatureRenderer extends
 
     tmp = new JPanel();
     panel.add(tmp);
-    tmp.add(new JLabel(MessageManager.getString("label.name"), JLabel.RIGHT));
+    tmp.add(new JLabel(MessageManager.getString("label.name:"),
+            JLabel.RIGHT));
     tmp.add(name);
 
     tmp = new JPanel();
     panel.add(tmp);
-    tmp.add(new JLabel(MessageManager.getString("label.group") + ":",
+    tmp.add(new JLabel(MessageManager.getString("label.group:"),
             JLabel.RIGHT));
     tmp.add(source);
 
@@ -248,7 +250,7 @@ public class FeatureRenderer extends
     bigPanel.add(panel, BorderLayout.NORTH);
 
     panel = new JPanel();
-    panel.add(new JLabel(MessageManager.getString("label.description"),
+    panel.add(new JLabel(MessageManager.getString("label.description:"),
             JLabel.RIGHT));
     description.setFont(JvSwingUtils.getTextAreaFont());
     description.setLineWrap(true);
index 7d9e937..3b8ce37 100644 (file)
@@ -174,7 +174,8 @@ public class FeatureSettings extends JPanel implements
       public void mousePressed(MouseEvent evt)
       {
         selectedRow = table.rowAtPoint(evt.getPoint());
-        if (SwingUtilities.isRightMouseButton(evt))
+        boolean ctrlDown = Platform.isControlDown(evt);
+        if (SwingUtilities.isRightMouseButton(evt) && !ctrlDown)
         {
           popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
                   table.getValueAt(selectedRow, 1), fr.getMinMax(),
@@ -182,9 +183,11 @@ public class FeatureSettings extends JPanel implements
         }
         else if (evt.getClickCount() == 2)
         {
+          boolean invertSelection = evt.isAltDown();
+          boolean toggleSelection = ctrlDown;
+          boolean extendSelection = evt.isShiftDown();
           fr.ap.alignFrame.avc.markColumnsContainingFeatures(
-                  evt.isAltDown(), evt.isShiftDown() || evt.isMetaDown(),
-                  evt.isMetaDown(),
+                  invertSelection, extendSelection, toggleSelection,
                   (String) table.getValueAt(selectedRow, 0));
         }
       }
index 535196e..1f6c068 100755 (executable)
@@ -157,6 +157,7 @@ public class FontChooser extends GFontChooser
     init = false;
   }
 
+  @Override
   public void smoothFont_actionPerformed(ActionEvent e)
   {
     ap.av.antiAlias = smoothFont.isSelected();
@@ -170,6 +171,7 @@ public class FontChooser extends GFontChooser
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   protected void ok_actionPerformed(ActionEvent e)
   {
     try
@@ -194,6 +196,7 @@ public class FontChooser extends GFontChooser
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   protected void cancel_actionPerformed(ActionEvent e)
   {
     if (ap != null)
@@ -247,10 +250,10 @@ public class FontChooser extends GFontChooser
     double iw = iBounds.getWidth();
     if (mw < 1 || iw < 1)
     {
-      final String messageKey = iBounds.getHeight() < 1 ? "label.font_doesnt_have_letters_defined"
-              : "label.font_too_small";
-      JOptionPane.showInternalMessageDialog(this,
-              MessageManager.getString(messageKey),
+      String message = iBounds.getHeight() < 1 ? MessageManager
+              .getString("label.font_doesnt_have_letters_defined")
+              : MessageManager.getString("label.font_too_small");
+      JOptionPane.showInternalMessageDialog(this, message,
               MessageManager.getString("label.invalid_font"),
               JOptionPane.WARNING_MESSAGE);
       /*
@@ -301,6 +304,7 @@ public class FontChooser extends GFontChooser
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   protected void fontName_actionPerformed(ActionEvent e)
   {
     if (init)
@@ -317,6 +321,7 @@ public class FontChooser extends GFontChooser
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   protected void fontSize_actionPerformed(ActionEvent e)
   {
     if (init)
@@ -333,6 +338,7 @@ public class FontChooser extends GFontChooser
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   protected void fontStyle_actionPerformed(ActionEvent e)
   {
     if (init)
@@ -349,6 +355,7 @@ public class FontChooser extends GFontChooser
    * 
    * @param e
    */
+  @Override
   public void defaultButton_actionPerformed(ActionEvent e)
   {
     Cache.setProperty("FONT_NAME", fontName.getSelectedItem().toString());
index 2b09eb6..51d247d 100644 (file)
@@ -140,8 +140,8 @@ public class PCAPanel extends GPCAPanel implements Runnable,
       {
         // create an entry for this score matrix for use in PCA
         JCheckBoxMenuItem jm = new JCheckBoxMenuItem();
-        jm.setText(MessageManager
-                .getStringOrReturn("label.score_model", sm));
+        jm.setText(MessageManager.getStringOrReturn("label.score_model_",
+                sm));
         jm.setSelected(pcaModel.getScore_matrix().equals(sm));
         if ((ResidueProperties.scoreMatrices.get(sm).isDNA() && ResidueProperties.scoreMatrices
                 .get(sm).isProtein())
index 497f3ba..d28dc60 100644 (file)
@@ -91,8 +91,6 @@ import javax.swing.JRadioButtonMenuItem;
  */
 public class PopupMenu extends JPopupMenu
 {
-  private static final String ALL_ANNOTATIONS = "All";
-
   JMenu groupMenu = new JMenu();
 
   JMenuItem groupName = new JMenuItem();
@@ -478,8 +476,6 @@ public class PopupMenu extends JPopupMenu
 
     if (sg != null && sg.getSize() > 0)
     {
-      groupName.setText(MessageManager.formatMessage("label.name_param",
-              new Object[] { sg.getName() }));
       groupName.setText(MessageManager
               .getString("label.edit_name_and_description_current_group"));
 
@@ -756,7 +752,8 @@ public class PopupMenu extends JPopupMenu
     showMenu.removeAll();
     hideMenu.removeAll();
 
-    final List<String> all = Arrays.asList(ALL_ANNOTATIONS);
+    final List<String> all = Arrays.asList(new String[] { MessageManager
+            .getString("label.all") });
     addAnnotationTypeToShowHide(showMenu, forSequences, "", all, true, true);
     addAnnotationTypeToShowHide(hideMenu, forSequences, "", all, true,
             false);
@@ -1098,7 +1095,6 @@ public class PopupMenu extends JPopupMenu
    */
   private void jbInit() throws Exception
   {
-    groupMenu.setText(MessageManager.getString("label.group"));
     groupMenu.setText(MessageManager.getString("label.selection"));
     groupName.setText(MessageManager.getString("label.name"));
     groupName.addActionListener(new java.awt.event.ActionListener()
index 7fb0593..a9d2690 100755 (executable)
@@ -172,7 +172,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
     progress = null;
 
     label.setText(MessageManager
-            .getString("label.enter_redundancy_thereshold"));
+            .getString("label.enter_redundancy_threshold"));
     slider.setVisible(true);
     applyButton.setEnabled(true);
     valueField.setVisible(true);
index e231c6f..316b6be 100755 (executable)
@@ -26,6 +26,7 @@ import jalview.datamodel.SequenceI;
 import jalview.renderer.ScaleRenderer;
 import jalview.renderer.ScaleRenderer.ScaleMark;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 
 import java.awt.Color;
 import java.awt.FontMetrics;
@@ -221,7 +222,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    */
   protected void leftMouseButtonPressed(MouseEvent evt, final int res)
   {
-    if (!evt.isControlDown() && !evt.isShiftDown())
+    if (!Platform.isControlDown(evt) && !evt.isShiftDown())
     {
       av.getColumnSelection().clear();
     }
index 8ebcc87..f476d41 100644 (file)
@@ -857,7 +857,8 @@ public class SeqPanel extends JPanel implements MouseListener,
      * Sequence number (if known), and sequence name.
      */
     String seqno = seq == -1 ? "" : " " + (seq + 1);
-    text.append("Sequence" + seqno + " ID: " + sequence.getName());
+    text.append("Sequence").append(seqno).append(" ID: ")
+            .append(sequence.getName());
 
     String residue = null;
     /*
index e1e70dc..c3fec4f 100755 (executable)
@@ -220,7 +220,7 @@ public class SliderPanel extends GSliderPanel
     }
 
     PIDSlider.setTitle(MessageManager
-            .formatMessage("label.percentage_identity_thereshold",
+            .formatMessage("label.percentage_identity_threshold",
                     new String[] { source }));
 
     if (ap.av.getAlignment().getGroups() != null)
index f1c6768..39d9c1d 100644 (file)
@@ -81,7 +81,7 @@ public class TextColourChooser
             new JLabel(
                     "<html>"
                             + MessageManager
-                                    .getString("label.select_dark_light_set_thereshold")
+                                    .getString("label.select_dark_light_set_threshold")
                             + "</html>"), BorderLayout.NORTH);
     panel.add(col1);
     panel.add(slider);
@@ -133,7 +133,7 @@ public class TextColourChooser
                     ap,
                     bigpanel,
                     MessageManager
-                            .getString("label.adjunst_foreground_text_colour_thereshold"),
+                            .getString("label.adjunst_foreground_text_colour_threshold"),
                     JOptionPane.OK_CANCEL_OPTION,
                     JOptionPane.QUESTION_MESSAGE, null, null, null);
 
index 4ec077f..6d94616 100755 (executable)
@@ -305,20 +305,6 @@ public class FormatAdapter extends AppletFormatAdapter
     return this.formatSequences(format, alignment, suffix);
   }
 
-  public AlignmentI readFile(String inFile, String type, String format)
-          throws java.io.IOException
-  {
-    AlignmentI al = super.readFile(inFile, type, format);
-    return al;
-  }
-
-  public AlignmentI readFromFile(FileParse source, String format)
-          throws java.io.IOException
-  {
-    AlignmentI al = super.readFromFile(source, format);
-    return al;
-  }
-
   /**
    * validate format is valid for IO in Application. This is basically the
    * AppletFormatAdapter.isValidFormat call with additional checks for
index 3cda444..653c071 100644 (file)
@@ -735,6 +735,10 @@ public class JSONFile extends AlignFile implements ComplexAlignFile
   @Override
   public void configureForView(AlignmentViewPanel avpanel)
   {
+    if (avpanel == null)
+    {
+      return;
+    }
     super.configureForView(avpanel);
     AlignViewportI viewport = avpanel.getAlignViewport();
     AlignmentI alignment = viewport.getAlignment();
index f62ad81..ab510d5 100755 (executable)
@@ -22,12 +22,14 @@ package jalview.io;
 
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 import jalview.util.Format;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.StringTokenizer;
-import java.util.Vector;
 
 /**
  * DOCUMENT ME!
@@ -67,24 +69,23 @@ public class MSFfile extends AlignFile
   }
 
   /**
-   * DOCUMENT ME!
+   * Read and parse MSF sequence data
    */
   @Override
   public void parse() throws IOException
   {
-    int i = 0;
     boolean seqFlag = false;
-    String key = new String();
-    Vector headers = new Vector();
-    Hashtable seqhash = new Hashtable();
-    String line;
+    List<String> headers = new ArrayList<String>();
+    Hashtable<String, StringBuilder> seqhash = new Hashtable<String, StringBuilder>();
 
     try
     {
+      String line;
       while ((line = nextLine()) != null)
       {
         StringTokenizer str = new StringTokenizer(line);
 
+        String key = null;
         while (str.hasMoreTokens())
         {
           String inStr = str.nextToken();
@@ -93,31 +94,31 @@ public class MSFfile extends AlignFile
           if (inStr.indexOf("Name:") != -1)
           {
             key = str.nextToken();
-            headers.addElement(key);
+            headers.add(key);
           }
 
-          // if line has // set SeqFlag to 1 so we know sequences are coming
+          // if line has // set SeqFlag so we know sequences are coming
           if (inStr.indexOf("//") != -1)
           {
             seqFlag = true;
           }
 
           // Process lines as sequence lines if seqFlag is set
-          if ((inStr.indexOf("//") == -1) && (seqFlag == true))
+          if ((inStr.indexOf("//") == -1) && seqFlag)
           {
-            // seqeunce id is the first field
+            // sequence id is the first field
             key = inStr;
 
-            StringBuffer tempseq;
+            StringBuilder tempseq;
 
             // Get sequence from hash if it exists
             if (seqhash.containsKey(key))
             {
-              tempseq = (StringBuffer) seqhash.get(key);
+              tempseq = seqhash.get(key);
             }
             else
             {
-              tempseq = new StringBuffer();
+              tempseq = new StringBuilder(64);
               seqhash.put(key, tempseq);
             }
 
@@ -125,7 +126,8 @@ public class MSFfile extends AlignFile
             while (str.hasMoreTokens())
             {
               // append the word to the sequence
-              tempseq.append(str.nextToken());
+              String sequenceBlock = str.nextToken();
+              tempseq.append(sequenceBlock);
             }
           }
         }
@@ -139,11 +141,11 @@ public class MSFfile extends AlignFile
     this.noSeqs = headers.size();
 
     // Add sequences to the hash
-    for (i = 0; i < headers.size(); i++)
+    for (int i = 0; i < headers.size(); i++)
     {
-      if (seqhash.get(headers.elementAt(i)) != null)
+      if (seqhash.get(headers.get(i)) != null)
       {
-        String head = headers.elementAt(i).toString();
+        String head = headers.get(i);
         String seq = seqhash.get(head).toString();
 
         if (maxLength < head.length())
@@ -151,8 +153,11 @@ public class MSFfile extends AlignFile
           maxLength = head.length();
         }
 
-        // Replace ~ with a sensible gap character
-        seq = seq.replace('~', '-');
+        /*
+         * replace ~ (leading/trailing positions) with the gap character;
+         * use '.' as this is the internal gap character required by MSF
+         */
+        seq = seq.replace('~', '.');
 
         Sequence newSeq = parseId(head);
 
@@ -163,7 +168,7 @@ public class MSFfile extends AlignFile
       else
       {
         System.err.println("MSFFile Parser: Can't find sequence for "
-                + headers.elementAt(i));
+                + headers.get(i));
       }
     }
   }
@@ -211,15 +216,16 @@ public class MSFfile extends AlignFile
    * 
    * @return DOCUMENT ME!
    */
-  public String print(SequenceI[] seqs)
+  public String print(SequenceI[] sqs)
   {
 
-    boolean is_NA = jalview.util.Comparison.isNucleotide(seqs);
+    boolean is_NA = Comparison.isNucleotide(sqs);
 
-    SequenceI[] s = new SequenceI[seqs.length];
+    SequenceI[] s = new SequenceI[sqs.length];
 
-    StringBuffer out = new StringBuffer("!!" + (is_NA ? "NA" : "AA")
-            + "_MULTIPLE_ALIGNMENT 1.0");
+    StringBuilder out = new StringBuilder(256);
+    out.append("!!").append(is_NA ? "NA" : "AA")
+            .append("_MULTIPLE_ALIGNMENT 1.0");
     // TODO: JBPNote : Jalview doesn't remember NA or AA yet.
     out.append(newline);
     out.append(newline);
@@ -227,14 +233,16 @@ public class MSFfile extends AlignFile
     int maxid = 0;
     int i = 0;
 
-    while ((i < seqs.length) && (seqs[i] != null))
+    while ((i < sqs.length) && (sqs[i] != null))
     {
-      // Replace all internal gaps with . and external spaces with ~
-      s[i] = new Sequence(seqs[i].getName(), seqs[i].getSequenceAsString()
-              .replace('-', '.'), seqs[i].getStart(), seqs[i].getEnd());
+      /*
+       * modify to MSF format: uses '.' for internal gaps, 
+       * and '~' for leading or trailing gaps
+       */
+      String seqString = sqs[i].getSequenceAsString()
+              .replace('-', '.');
 
-      StringBuffer sb = new StringBuffer();
-      sb.append(s[i].getSequence());
+      StringBuilder sb = new StringBuilder(seqString);
 
       for (int ii = 0; ii < sb.length(); ii++)
       {
@@ -259,12 +267,12 @@ public class MSFfile extends AlignFile
           break;
         }
       }
+      s[i] = new Sequence(sqs[i].getName(), sb.toString(),
+              sqs[i].getStart(), sqs[i].getEnd());
 
-      s[i].setSequence(sb.toString());
-
-      if (s[i].getSequence().length > max)
+      if (sb.length() > max)
       {
-        max = s[i].getSequence().length;
+        max = sb.length();
       }
 
       i++;
index 71cc7f0..667da9f 100755 (executable)
@@ -108,7 +108,7 @@ public class PfamFile extends AlignFile
       }
       if (spces + 1 < line.length())
       {
-        tempseq.append(line.substring(spces + 1));
+        tempseq.append(line.substring(spces + 1).trim());
       }
     }
 
index 23c4d21..ab80ffa 100644 (file)
@@ -101,6 +101,7 @@ public class StockholmFile extends AlignFile
     super(source);
   }
 
+  @Override
   public void initData()
   {
     super.initData();
@@ -178,6 +179,7 @@ public class StockholmFile extends AlignFile
    * @throws IOException
    *           If there is an error with the input file
    */
+  @Override
   public void parse() throws IOException
   {
     StringBuffer treeString = new StringBuffer();
@@ -533,8 +535,7 @@ public class StockholmFile extends AlignFile
           }
           else
           {
-            // throw new IOException(MessageManager.formatMessage(
-            // "exception.error_parsing_line", new String[] { line }));
+            // throw new IOException("Error parsing " + line);
             System.err.println(">> missing annotation: " + line);
           }
         }
@@ -1106,6 +1107,7 @@ public class StockholmFile extends AlignFile
     return seq;
   }
 
+  @Override
   public String print()
   {
     out = new StringBuffer();
index b2eb094..d7def6b 100755 (executable)
@@ -136,8 +136,6 @@ public class GAlignFrame extends JInternalFrame
 
   public JCheckBoxMenuItem showSeqFeatures = new JCheckBoxMenuItem();
 
-  public JCheckBoxMenuItem showSeqFeaturesHeight = new JCheckBoxMenuItem();
-
   JMenuItem copy = new JMenuItem();
 
   JMenuItem cut = new JMenuItem();
@@ -1591,7 +1589,7 @@ public class GAlignFrame extends JInternalFrame
     });
 
     JMenuItem modifyPID = new JMenuItem(
-            MessageManager.getString("label.modify_identity_thereshold"));
+            MessageManager.getString("label.modify_identity_threshold"));
     modifyPID.addActionListener(new ActionListener()
     {
       @Override
@@ -1601,7 +1599,7 @@ public class GAlignFrame extends JInternalFrame
       }
     });
     modifyConservation.setText(MessageManager
-            .getString("label.modify_conservation_thereshold"));
+            .getString("label.modify_conservation_threshold"));
     modifyConservation.addActionListener(new ActionListener()
     {
       @Override
@@ -2520,13 +2518,6 @@ public class GAlignFrame extends JInternalFrame
 
   }
 
-  protected void showSeqFeaturesHeight_actionPerformed(
-          ActionEvent actionEvent)
-  {
-    // TODO Auto-generated method stub
-
-  }
-
   protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
   {
     // TODO Auto-generated method stub
index 164c7c7..6940f22 100644 (file)
@@ -34,7 +34,7 @@ import java.util.List;
  */
 public class ScaleRenderer
 {
-  public class ScaleMark
+  public final class ScaleMark
   {
     public final boolean major;
 
index 786f5bf..85a27f6 100644 (file)
@@ -78,10 +78,21 @@ public class Platform
     return f.toString();
   }
 
+  /**
+   * Answers true if the mouse event has Meta-down (on Mac) or Ctrl-down (on
+   * other o/s)
+   * 
+   * @param e
+   * @return
+   */
   public static boolean isControlDown(MouseEvent e)
   {
-    return (jalview.util.Platform.isAMac() ? (Toolkit.getDefaultToolkit()
-            .getMenuShortcutKeyMask() & e.getModifiers()) != 0 : e
-            .isControlDown());
+    if (isAMac())
+    {
+      return (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() & e
+              .getModifiers()) != 0;
+      // could we use e.isMetaDown() here?
+    }
+    return e.isControlDown();
   }
 }
index 65179a2..37946b1 100644 (file)
@@ -27,10 +27,8 @@ import jalview.ws.dbsources.EmblSource;
 import jalview.ws.dbsources.Pdb;
 import jalview.ws.dbsources.PfamFull;
 import jalview.ws.dbsources.PfamSeed;
-import jalview.ws.dbsources.RfamFull;
 import jalview.ws.dbsources.RfamSeed;
 import jalview.ws.dbsources.Uniprot;
-import jalview.ws.dbsources.UniprotName;
 import jalview.ws.dbsources.das.api.jalviewSourceI;
 import jalview.ws.seqfetcher.ASequenceFetcher;
 import jalview.ws.seqfetcher.DbSourceProxy;
@@ -62,11 +60,11 @@ public class SequenceFetcher extends ASequenceFetcher
     addDBRefSourceImpl(EmblSource.class);
     addDBRefSourceImpl(EmblCdsSource.class);
     addDBRefSourceImpl(Uniprot.class);
-    addDBRefSourceImpl(UniprotName.class);
     addDBRefSourceImpl(Pdb.class);
     addDBRefSourceImpl(PfamFull.class);
     addDBRefSourceImpl(PfamSeed.class);
     addDBRefSourceImpl(RfamSeed.class);
+
     if (addDas)
     {
       registerDasSequenceSources();
index 33d332a..21a79fe 100644 (file)
@@ -42,7 +42,7 @@ public class AtomTest
     assertEquals("GLN", a.resName);
     assertEquals("A", a.chain);
     assertEquals(48, a.resNumber);
-    assertEquals("  48 ", a.resNumIns);
+    assertEquals("48", a.resNumIns);
     assertEquals(' ', a.insCode);
     assertEquals(22.290, a.x, 0.00001);
     assertEquals(8.595, a.y, 0.00001);
index 34ec73b..0426091 100644 (file)
@@ -2452,8 +2452,9 @@ public class AlignmentUtilsTests
   {
     SequenceI dna1 = new Sequence("dna1", "cccGGGTTTaaa");
     SequenceI dna2 = new Sequence("dna2", "CCCgggtttAAA");
-    SequenceI as1 = dna1.deriveSequence(), as2 = dna1.deriveSequence()
-            .getSubSequence(3, 7), as3 = dna2.deriveSequence();
+    SequenceI as1 = dna1.deriveSequence();
+    SequenceI as2 = dna1.deriveSequence().getSubSequence(3, 7);
+    SequenceI as3 = dna2.deriveSequence();
     as1.insertCharAt(6, 5, '-');
     String s_as1 = as1.getSequenceAsString();
     as2.insertCharAt(6, 5, '-');
@@ -2464,8 +2465,9 @@ public class AlignmentUtilsTests
 
     // why do we need to cast this still ?
     ((Alignment) aligned).createDatasetAlignment();
-    SequenceI uas1 = dna1.deriveSequence(), uas2 = dna1.deriveSequence()
-            .getSubSequence(3, 7), uas3 = dna2.deriveSequence();
+    SequenceI uas1 = dna1.deriveSequence();
+    SequenceI uas2 = dna1.deriveSequence().getSubSequence(3, 7);
+    SequenceI uas3 = dna2.deriveSequence();
     AlignmentI tobealigned = new Alignment(new SequenceI[] { uas1, uas2,
         uas3 });
     ((Alignment) tobealigned).createDatasetAlignment();
index 55823e4..df39b81 100644 (file)
@@ -27,7 +27,6 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 
 import org.testng.AssertJUnit;
@@ -45,21 +44,26 @@ public class GroupingTest
 
   Sequence s5 = new Sequence("s5", "AAAADDEDTTEE");
 
-  SequenceGroup sg1 = new SequenceGroup(Arrays.asList(new SequenceI[] { s1,
+  SequenceGroup sg_12 = new SequenceGroup(Arrays.asList(new SequenceI[] { s1,
       s2 }), "Group1", null, false, false, false, 0, 5);
 
-  SequenceGroup sg2 = new SequenceGroup(Arrays.asList(new SequenceI[] { s3,
+  SequenceGroup sg_345 = new SequenceGroup(Arrays.asList(new SequenceI[] { s3,
       s4, s5 }), "Group2", null, false, false, false, 0, 5);
 
   AlignmentI alignment = new Alignment(
           new SequenceI[] { s1, s2, s3, s4, s5 });
 
-  int[] positions = new int[] { 1, 7, 9 };
+  /*
+   * test for the case where column selections are not added in
+   * left to right order
+   */
+  int[] positions = new int[] { 7, 9, 1 };
 
   @Test(groups = { "Functional" })
   public void testMakeGroupsWithBoth()
   {
-    ArrayList<String> str = new ArrayList<String>();
+    String[] str = new String[alignment.getHeight()];
+    int seq = 0;
     for (SequenceI s : alignment.getSequences())
     {
       StringBuilder sb = new StringBuilder();
@@ -67,12 +71,12 @@ public class GroupingTest
       {
         sb.append(s.getCharAt(p));
       }
-      str.add(sb.toString());
+      str[seq++] = sb.toString();
     }
     SequenceGroup[] seqgroupsString = Grouping.makeGroupsFrom(
-            alignment.getSequencesArray(),
-            str.toArray(new String[str.size()]),
-            Arrays.asList(new SequenceGroup[] { sg1, sg2 }));
+            alignment.getSequencesArray(), str,
+            Arrays.asList(new SequenceGroup[] { sg_12, sg_345 }));
+
     ColumnSelection cs = new ColumnSelection();
     for (int p : positions)
     {
@@ -80,7 +84,7 @@ public class GroupingTest
     }
     SequenceGroup[] seqgroupsColSel = Grouping.makeGroupsFromCols(
             alignment.getSequencesArray(), cs,
-            Arrays.asList(new SequenceGroup[] { sg1, sg2 }));
+            Arrays.asList(new SequenceGroup[] { sg_12, sg_345 }));
     AssertJUnit
             .assertEquals(seqgroupsString.length, seqgroupsColSel.length);
     for (int p = 0; p < seqgroupsString.length; p++)
diff --git a/test/jalview/controller/AlignViewControllerTest.java b/test/jalview/controller/AlignViewControllerTest.java
new file mode 100644 (file)
index 0000000..3eefada
--- /dev/null
@@ -0,0 +1,100 @@
+package jalview.controller;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+import java.util.BitSet;
+
+import org.testng.annotations.Test;
+
+public class AlignViewControllerTest
+{
+  @Test(groups = "Functional")
+  public void testFindColumnsWithFeature()
+  {
+    SequenceI seq1 = new Sequence("seq1", "aMMMaaaaaaaaaaaaaaaa");
+    SequenceI seq2 = new Sequence("seq2", "aaaMMMMMMMaaaaaaaaaa");
+    SequenceI seq3 = new Sequence("seq3", "aaaaaaaaaaMMMMMaaaaa");
+    SequenceI seq4 = new Sequence("seq3", "aaaaaaaaaaaaaaaaaaaa");
+
+    /*
+     * features start/end are base 1
+     */
+    seq1.addSequenceFeature(new SequenceFeature("Metal", "desc", 2, 4, 0f,
+            null));
+    seq1.addSequenceFeature(new SequenceFeature("Helix", "desc", 1, 15, 0f,
+            null));
+    seq2.addSequenceFeature(new SequenceFeature("Metal", "desc", 4, 10, 0f,
+            null));
+    seq3.addSequenceFeature(new SequenceFeature("Metal", "desc", 11, 15,
+            0f, null));
+
+    /*
+     * select the first three columns --> Metal in seq1 2-3
+     */
+    SequenceGroup sg = new SequenceGroup();
+    sg.setStartRes(0); // base 0
+    sg.setEndRes(2);
+    sg.addSequence(seq1, false);
+    sg.addSequence(seq2, false);
+    sg.addSequence(seq3, false);
+    sg.addSequence(seq4, false);
+
+    BitSet bs = new BitSet();
+    int seqCount = AlignViewController.findColumnsWithFeature("Metal", sg,
+            bs);
+    assertEquals(1, seqCount);
+    assertEquals(2, bs.cardinality());
+    assertTrue(bs.get(1));
+    assertTrue(bs.get(2));
+    
+    /*
+     * select the first four columns: Metal in seq1 2:4, seq2 4:4
+     */
+    sg.setEndRes(3);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("Metal", sg,
+            bs);
+    assertEquals(2, seqCount);
+    assertEquals(3, bs.cardinality());
+    assertTrue(bs.get(1));
+    assertTrue(bs.get(2));
+    assertTrue(bs.get(3));
+
+    /*
+     * select column 11: Metal in seq3 only
+     */
+    sg.setStartRes(10);
+    sg.setEndRes(10);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+    assertEquals(1, seqCount);
+    assertEquals(1, bs.cardinality());
+    assertTrue(bs.get(10));
+
+    /*
+     * select columns 16-20: no Metal feature
+     */
+    sg.setStartRes(15);
+    sg.setEndRes(19);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+    assertEquals(0, seqCount);
+    assertEquals(0, bs.cardinality());
+
+    /*
+     * look for a feature that isn't there
+     */
+    sg.setStartRes(0);
+    sg.setEndRes(19);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("Pfam", sg, bs);
+    assertEquals(0, seqCount);
+    assertEquals(0, bs.cardinality());
+  }
+}
index 1a7ae32..e59719c 100644 (file)
@@ -22,10 +22,12 @@ package jalview.datamodel;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNotSame;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
 import java.util.Arrays;
+import java.util.BitSet;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -66,6 +68,9 @@ public class ColumnSelectionTest
 
     // removing an element in the list removes it
     cs.removeElement(2);
+    // ...but not from the copy list!
+    assertEquals(2, sel.size());
+    sel = cs.getSelected();
     assertEquals(1, sel.size());
     assertEquals(new Integer(5), sel.get(0));
   }
@@ -325,10 +330,14 @@ public class ColumnSelectionTest
    * this fails, HideSelectedColumns may also fail
    */
   @Test(groups = { "Functional" })
-  public void testgetSelectedRanges()
+  public void testGetSelectedRanges()
   {
+    /*
+     * getSelectedRanges returns ordered columns regardless
+     * of the order in which they are added
+     */
     ColumnSelection cs = new ColumnSelection();
-    int[] sel = { 2, 3, 4, 7, 8, 9, 20, 21, 22 };
+    int[] sel = { 4, 3, 7, 21, 9, 20, 8, 22, 2 };
     for (int col : sel)
     {
       cs.addElement(col);
@@ -527,4 +536,137 @@ public class ColumnSelectionTest
     cs.addElement(88);
     assertTrue(cs.equals(cs2));
   }
+
+  /**
+   * Test the method that returns selected columns, in the order in which they
+   * were added
+   */
+  @Test(groups = { "Functional" })
+  public void testGetSelection()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    int[] sel = { 4, 3, 7, 21 };
+    for (int col : sel)
+    {
+      cs.addElement(col);
+    }
+
+    List<Integer> selected1 = cs.getSelected();
+    assertEquals(4, selected1.size());
+
+    /*
+     * getSelected returns a copy, verify the list
+     * is externally immutable
+     */
+    selected1.clear();
+    List<Integer> selected2 = cs.getSelected();
+    assertNotSame(selected1, selected2);
+    assertEquals(4, selected2.size());
+    int i = 0;
+    for (int col : sel)
+    {
+      assertEquals(col, selected2.get(i++).intValue());
+    }
+
+    cs.removeElement(7);
+    cs.addElement(1);
+    cs.removeElement(4);
+
+    List<Integer> selected3 = cs.getSelected();
+    assertEquals(3, selected3.size());
+    assertEquals(3, selected3.get(0).intValue());
+    assertEquals(21, selected3.get(1).intValue());
+    assertEquals(1, selected3.get(2).intValue());
+  }
+
+  @Test(groups = "Functional")
+  public void testMarkColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(5); // this will be cleared
+    BitSet toMark = new BitSet();
+    toMark.set(1);
+    toMark.set(3);
+    toMark.set(6);
+    toMark.set(9);
+
+    assertTrue(cs.markColumns(toMark, 3, 8, false, false, false));
+    List<Integer> selected = cs.getSelected();
+    assertEquals(2, selected.size());
+    assertTrue(selected.contains(3));
+    assertTrue(selected.contains(6));
+  }
+
+  @Test(groups = "Functional")
+  public void testMarkColumns_extend()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(1);
+    cs.addElement(5);
+    BitSet toMark = new BitSet();
+    toMark.set(1);
+    toMark.set(3);
+    toMark.set(6);
+    toMark.set(9);
+
+    /*
+     * extending selection of {3, 6} should leave {1, 3, 5, 6} selected
+     */
+    assertTrue(cs.markColumns(toMark, 3, 8, false, true, false));
+    List<Integer> selected = cs.getSelected();
+    assertEquals(4, selected.size());
+    assertTrue(selected.contains(1));
+    assertTrue(selected.contains(3));
+    assertTrue(selected.contains(5));
+    assertTrue(selected.contains(6));
+  }
+
+  @Test(groups = "Functional")
+  public void testMarkColumns_invert()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(5); // this will be cleared
+    BitSet toMark = new BitSet();
+    toMark.set(1);
+    toMark.set(3);
+    toMark.set(6);
+    toMark.set(9);
+
+    /*
+     * inverted selection of {3, 6} should select {4, 5, 7, 8}
+     */
+    assertTrue(cs.markColumns(toMark, 3, 8, true, false, false));
+    List<Integer> selected = cs.getSelected();
+    assertEquals(4, selected.size());
+    assertTrue(selected.contains(4));
+    assertTrue(selected.contains(5));
+    assertTrue(selected.contains(7));
+    assertTrue(selected.contains(8));
+  }
+
+  @Test(groups = "Functional")
+  public void testMarkColumns_toggle()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(1); // outside change range
+    cs.addElement(3);
+    cs.addElement(4);
+    cs.addElement(10); // outside change range
+    BitSet toMark = new BitSet();
+    toMark.set(1);
+    toMark.set(3);
+    toMark.set(6);
+    toMark.set(9);
+
+    /*
+     * toggling state of {3, 6} should leave {1, 4, 6, 10} selected
+     */
+    assertTrue(cs.markColumns(toMark, 3, 8, false, false, true));
+    List<Integer> selected = cs.getSelected();
+    assertEquals(4, selected.size());
+    assertTrue(selected.contains(1));
+    assertTrue(selected.contains(4));
+    assertTrue(selected.contains(6));
+    assertTrue(selected.contains(10));
+  }
 }
index f586776..fcd24dd 100644 (file)
@@ -110,8 +110,7 @@ public class SequenceTest
   {
     AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
             1f);
-    AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2",
-            1f);
+    addAnnotation("label2", "desc2", "calcId2", 1f);
     AlignmentAnnotation ann3 = addAnnotation("label1", "desc3", "calcId3",
             1f);
     AlignmentAnnotation[] anns = seq.getAnnotation("label1");
@@ -133,16 +132,15 @@ public class SequenceTest
   @Test(groups = { "Functional" })
   public void testGetAlignmentAnnotations_forCalcIdAndLabel()
   {
-    AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1",
-            1f);
+    addAnnotation("label1", "desc1", "calcId1", 1f);
     AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2",
             1f);
-    AlignmentAnnotation ann3 = addAnnotation("label2", "desc3", "calcId3",
-            1f);
+    addAnnotation("label2", "desc3", "calcId3", 1f);
     AlignmentAnnotation ann4 = addAnnotation("label2", "desc3", "calcId2",
             1f);
-    AlignmentAnnotation ann5 = addAnnotation("label5", "desc3", null, 1f);
-    AlignmentAnnotation ann6 = addAnnotation(null, "desc3", "calcId3", 1f);
+    addAnnotation("label5", "desc3", null, 1f);
+    addAnnotation(null, "desc3", "calcId3", 1f);
+
     List<AlignmentAnnotation> anns = seq.getAlignmentAnnotations("calcId2",
             "label2");
     assertEquals(2, anns.size());
index e6019aa..d3d9ff8 100644 (file)
@@ -68,8 +68,8 @@ public class AnnotatedPDBFileInputTest
     pdbId = al.getSequenceAt(0).getDatasetSequence().getAllPDBEntries()
             .get(0).getId();
     StructureImportSettings.setDefaultStructureFileFormat("PDB");
-    StructureImportSettings
-            .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
+    // StructureImportSettings
+    // .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
   }
 
   @Test(groups = { "Functional" })
@@ -101,7 +101,11 @@ public class AnnotatedPDBFileInputTest
       {
 
         System.out.println("CalcId: " + aa.getCalcId());
+        if (StructureImportSettings.getDefaultPDBFileParser().equals(
+                StructureParser.JALVIEW_PARSER))
+        {
         assertTrue(MCview.PDBfile.isCalcIdForFile(aa, pdbId));
+        }
       }
     }
   }
@@ -118,9 +122,9 @@ public class AnnotatedPDBFileInputTest
     SequenceFeature[] sf = al.getSequenceAt(0).getSequenceFeatures();
     assertEquals(296, sf.length);
     assertEquals("RESNUM", sf[0].getType());
-    assertEquals("GLU:  19  1gaqA", sf[0].getDescription());
+    assertEquals("GLU:19 1gaqA", sf[0].getDescription());
     assertEquals("RESNUM", sf[295].getType());
-    assertEquals("TYR: 314  1gaqA", sf[295].getDescription());
+    assertEquals("TYR:314 1gaqA", sf[295].getDescription());
 
     /*
      * 1GAQ/B
@@ -128,9 +132,9 @@ public class AnnotatedPDBFileInputTest
     sf = al.getSequenceAt(1).getSequenceFeatures();
     assertEquals(98, sf.length);
     assertEquals("RESNUM", sf[0].getType());
-    assertEquals("ALA:   1  1gaqB", sf[0].getDescription());
+    assertEquals("ALA:1 1gaqB", sf[0].getDescription());
     assertEquals("RESNUM", sf[97].getType());
-    assertEquals("ALA:  98  1gaqB", sf[97].getDescription());
+    assertEquals("ALA:98 1gaqB", sf[97].getDescription());
 
     /*
      * 1GAQ/C
@@ -138,9 +142,9 @@ public class AnnotatedPDBFileInputTest
     sf = al.getSequenceAt(2).getSequenceFeatures();
     assertEquals(296, sf.length);
     assertEquals("RESNUM", sf[0].getType());
-    assertEquals("GLU:  19  1gaqC", sf[0].getDescription());
+    assertEquals("GLU:19 1gaqC", sf[0].getDescription());
     assertEquals("RESNUM", sf[295].getType());
-    assertEquals("TYR: 314  1gaqC", sf[295].getDescription());
+    assertEquals("TYR:314 1gaqC", sf[295].getDescription());
   }
 
   @Test(groups = { "Functional" })
diff --git a/test/jalview/io/FormatAdapterTest.java b/test/jalview/io/FormatAdapterTest.java
new file mode 100644 (file)
index 0000000..81e336e
--- /dev/null
@@ -0,0 +1,138 @@
+package jalview.io;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.fail;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class FormatAdapterTest
+{
+
+  /**
+   * Test saving and re-reading in a specified format
+   * 
+   * @throws IOException
+   */
+  @Test(groups = { "Functional" }, dataProvider = "formats")
+  public void testRoundTrip(String format) throws IOException
+  {
+    try
+    {
+      AlignmentI al = new FormatAdapter().readFile("examples/uniref50.fa",
+              FormatAdapter.FILE, "FASTA");
+
+      /*
+       * 'gap' is the gap character used in the alignment data file here,
+       * not the user preferred gap character
+       */
+      char gap = al.getGapCharacter();
+      assertNotNull(al);
+
+      SequenceI[] seqs = al.getSequencesArray();
+      String formatted = new FormatAdapter().formatSequences(format, al,
+              false);
+
+      AlignmentI reloaded = new FormatAdapter().readFile(formatted,
+              FormatAdapter.PASTE, format);
+      List<SequenceI> reread = reloaded.getSequences();
+      assertEquals("Wrong number of reloaded sequences", seqs.length,
+              reread.size());
+
+      int i = 0;
+      for (SequenceI seq : reread)
+      {
+        String sequenceString = seq.getSequenceAsString();
+
+        /*
+         * special case: MSF always uses '.' as gap character
+         */
+        sequenceString = adjustForGapTreatment(sequenceString, gap, format);
+        assertEquals(
+                String.format("Sequence %d: %s", i,
+                        seqs[i].getName()), seqs[i].getSequenceAsString(),
+                sequenceString);
+        i++;
+      }
+    } catch (IOException e)
+    {
+      fail(String
+              .format("Format %s failed with %s", format, e.getMessage()));
+    }
+  }
+
+  /**
+   * Optionally change the gap character in the string to the given character,
+   * depending on the sequence file format
+   * 
+   * @param sequenceString
+   *          a sequence (as written in 'format' format)
+   * @param gap
+   *          the sequence's original gap character
+   * @param format
+   * @return
+   */
+  String adjustForGapTreatment(String sequenceString, char gap,
+          String format)
+  {
+    if ("MSF".equals(format))
+    {
+      /*
+       * MSF forces gap character to '.', so change it back
+       * for comparison purposes
+       */
+      sequenceString = sequenceString.replace('.', gap);
+    }
+    return sequenceString;
+  }
+
+  /**
+   * Data provider that serves alignment formats that are both readable and
+   * writable
+   * 
+   * @return
+   */
+  @DataProvider(name = "formats")
+  static Object[][] getFormats()
+  {
+    List<String> both = new ArrayList<String>();
+    String[] readable = FormatAdapter.READABLE_FORMATS;
+    List<String> writeable = Arrays.asList(FormatAdapter.WRITEABLE_FORMATS);
+    for (String r : readable)
+    {
+      if (writeable.contains(r))
+      {
+        both.add(r);
+      }
+    }
+
+    Object[][] formats = new Object[both.size()][];
+    int i = 0;
+    for (String format : both)
+    {
+      formats[i] = new Object[] { format };
+      i++;
+    }
+    return formats;
+  }
+
+  /**
+   * Enable this to isolate testing to a single file format
+   * 
+   * @throws IOException
+   */
+  @Test(groups = { "Functional" }, enabled = false)
+  public void testOneFormatRoundTrip() throws IOException
+  {
+    testRoundTrip("JSON");
+  }
+}
index c2e3a66..784f3dd 100644 (file)
@@ -34,10 +34,12 @@ import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.HiddenSequences;
+import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
+import jalview.gui.AlignmentPanel;
 import jalview.gui.Desktop;
 import jalview.gui.Jalview2XML;
 import jalview.schemes.AnnotationColourGradient;
@@ -686,4 +688,92 @@ public class Jalview2xmlTests
               hidden.size(), hs.getSize());
     }
   }
+
+  /**
+   * Test save and reload of PDBEntry in Jalview project
+   * 
+   * @throws Exception
+   */
+  @Test(groups = { "Functional" })
+  public void testStoreAndRecoverPDBEntry() throws Exception
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+    String exampleFile = "examples/3W5V.pdb";
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
+            FormatAdapter.FILE);
+    assertTrue("Didn't read in the example file correctly.", af != null);
+    String afid = af.getViewport().getSequenceSetId();
+
+    AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
+    System.out.println();
+    AlignmentViewPanel ap = alignPanels[0];
+    String tfileBase = new File(".").getAbsolutePath().replace(".", "");
+    String testFile = tfileBase + exampleFile;
+    AlignmentI alignment = ap.getAlignment();
+    System.out.println("blah");
+    SequenceI[] seqs = alignment.getSequencesArray();
+    Assert.assertNotNull(seqs[0]);
+    Assert.assertNotNull(seqs[1]);
+    Assert.assertNotNull(seqs[2]);
+    Assert.assertNotNull(seqs[3]);
+    Assert.assertNotNull(seqs[0].getDatasetSequence());
+    Assert.assertNotNull(seqs[1].getDatasetSequence());
+    Assert.assertNotNull(seqs[2].getDatasetSequence());
+    Assert.assertNotNull(seqs[3].getDatasetSequence());
+    PDBEntry[] pdbEntries = new PDBEntry[4];
+    pdbEntries[0] = new PDBEntry("3W5V", "A", null, testFile);
+    pdbEntries[1] = new PDBEntry("3W5V", "B", null, testFile);
+    pdbEntries[2] = new PDBEntry("3W5V", "C", null, testFile);
+    pdbEntries[3] = new PDBEntry("3W5V", "D", null, testFile);
+    Assert.assertTrue(seqs[0].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[0]));
+    Assert.assertTrue(seqs[1].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[1]));
+    Assert.assertTrue(seqs[2].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[2]));
+    Assert.assertTrue(seqs[3].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[3]));
+
+    File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
+    try
+    {
+      new Jalview2XML(false).saveState(tfile);
+    } catch (Throwable e)
+    {
+      Assert.fail("Didn't save the state", e);
+    }
+    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.getAlignFrames() != null)
+    {
+      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+    }
+
+    AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
+            tfile.getAbsolutePath(), FormatAdapter.FILE);
+    String rfid = restoredFrame.getViewport().getSequenceSetId();
+    AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
+    AlignmentViewPanel rap = rAlignPanels[0];
+    AlignmentI rAlignment = rap.getAlignment();
+    System.out.println("blah");
+    SequenceI[] rseqs = rAlignment.getSequencesArray();
+    Assert.assertNotNull(rseqs[0]);
+    Assert.assertNotNull(rseqs[1]);
+    Assert.assertNotNull(rseqs[2]);
+    Assert.assertNotNull(rseqs[3]);
+    Assert.assertNotNull(rseqs[0].getDatasetSequence());
+    Assert.assertNotNull(rseqs[1].getDatasetSequence());
+    Assert.assertNotNull(rseqs[2].getDatasetSequence());
+    Assert.assertNotNull(rseqs[3].getDatasetSequence());
+
+    // The Asserts below are expected to fail until the PDB chainCode is
+    // recoverable from a Jalview projects
+    Assert.assertTrue(rseqs[0].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[0]));
+    Assert.assertTrue(rseqs[1].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[1]));
+    Assert.assertTrue(rseqs[2].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[2]));
+    Assert.assertTrue(rseqs[3].getDatasetSequence().getAllPDBEntries()
+            .get(0).equals(pdbEntries[3]));
+  }
 }
index d7a9166..b034fb0 100644 (file)
@@ -23,6 +23,7 @@ package jalview.io;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
 
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
@@ -159,7 +160,7 @@ public class StockholmFileTest
    *          'secondary' or generated alignment from some datapreserving
    *          transformation
    * @param ignoreFeatures
-   *          when true, differences in seuqence feature annotation are ignored.
+   *          when true, differences in sequence feature annotation are ignored
    */
   public static void testAlignmentEquivalence(AlignmentI al,
           AlignmentI al_input, boolean ignoreFeatures)
@@ -167,12 +168,9 @@ public class StockholmFileTest
     assertNotNull("Original alignment was null", al);
     assertNotNull("Generated alignment was null", al_input);
 
-    assertTrue(
-            "Alignment dimension mismatch: originl contains "
-                    + al.getHeight() + " and generated has "
-                    + al_input.getHeight() + " sequences; original has "
-                    + al.getWidth() + " and generated has "
-                    + al_input.getWidth() + " columns.",
+    assertTrue("Alignment dimension mismatch: original: " + al.getHeight()
+            + "x" + al.getWidth() + ", generated: " + al_input.getHeight()
+            + "x" + al_input.getWidth(),
             al.getHeight() == al_input.getHeight()
                     && al.getWidth() == al_input.getWidth());
 
@@ -183,9 +181,10 @@ public class StockholmFileTest
     // note - at moment we do not distinguish between alignment without any
     // annotation rows and alignment with no annotation row vector
     // we might want to revise this in future
-    int aa_new_size = (aa_new == null ? 0 : aa_new.length), aa_original_size = (aa_original == null ? 0
-            : aa_original.length);
-    Map<Integer, java.util.BitSet> orig_groups = new HashMap<Integer, java.util.BitSet>(), new_groups = new HashMap<Integer, java.util.BitSet>();
+    int aa_new_size = (aa_new == null ? 0 : aa_new.length);
+    int aa_original_size = (aa_original == null ? 0 : aa_original.length);
+    Map<Integer, BitSet> orig_groups = new HashMap<Integer, BitSet>();
+    Map<Integer, BitSet> new_groups = new HashMap<Integer, BitSet>();
 
     if (aa_new != null && aa_original != null)
     {
@@ -196,20 +195,17 @@ public class StockholmFileTest
           assertTrue("Different alignment annotation at position " + i,
                   equalss(aa_original[i], aa_new[i]));
           // compare graphGroup or graph properties - needed to verify JAL-1299
-          assertTrue("Graph type not identical.",
-                  aa_original[i].graph == aa_new[i].graph);
-          assertTrue("Visibility not identical.",
-                  aa_original[i].visible == aa_new[i].visible);
-          assertTrue(
-                  "Threshold line not identical.",
-                  aa_original[i].threshold == null ? aa_new[i].threshold == null
-                          : aa_original[i].threshold
-                                  .equals(aa_new[i].threshold));
+          assertEquals("Graph type not identical.", aa_original[i].graph,
+                  aa_new[i].graph);
+          assertEquals("Visibility not identical.", aa_original[i].visible,
+                  aa_new[i].visible);
+          assertEquals("Threshold line not identical.",
+                  aa_original[i].threshold, aa_new[i].threshold);
           // graphGroup may differ, but pattern should be the same
-          Integer o_ggrp = new Integer(aa_original[i].graphGroup + 2), n_ggrp = new Integer(
-                  aa_new[i].graphGroup + 2);
-          BitSet orig_g = orig_groups.get(o_ggrp), new_g = new_groups
-                  .get(n_ggrp);
+          Integer o_ggrp = new Integer(aa_original[i].graphGroup + 2);
+          Integer n_ggrp = new Integer(aa_new[i].graphGroup + 2);
+          BitSet orig_g = orig_groups.get(o_ggrp);
+          BitSet new_g = new_groups.get(n_ggrp);
           if (orig_g == null)
           {
             orig_groups.put(o_ggrp, orig_g = new BitSet());
@@ -218,8 +214,8 @@ public class StockholmFileTest
           {
             new_groups.put(n_ggrp, new_g = new BitSet());
           }
-          assertTrue("Graph Group pattern differs at annotation " + i,
-                  orig_g.equals(new_g));
+          assertEquals("Graph Group pattern differs at annotation " + i,
+                  orig_g, new_g);
           orig_g.set(i);
           new_g.set(i);
         }
@@ -230,10 +226,9 @@ public class StockholmFileTest
         }
       }
     }
-    assertTrue(
-            "Generated and imported alignment have different annotation sets ("
-                    + aa_new_size + " != " + aa_original_size + ")",
-            aa_new_size == aa_original_size);
+    assertEquals(
+            "Generated and imported alignment have different annotation sets",
+            aa_new_size, aa_original_size);
 
     // check sequences, annotation and features
     SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length];
@@ -260,8 +255,8 @@ public class StockholmFileTest
         {
           String ss_original = seq_original[i].getSequenceAsString();
           String ss_new = seq_new[in].getSequenceAsString();
-          assertTrue("The sequences " + name + "/" + start + "-" + end
-                  + " are not equal", ss_original.equals(ss_new));
+          assertEquals("The sequences " + name + "/" + start + "-" + end
+                  + " are not equal", ss_original, ss_new);
 
           assertTrue(
                   "Sequence Features were not equivalent"
@@ -284,15 +279,16 @@ public class StockholmFileTest
                     .getSequenceFeatures().length];
             sequenceFeatures_new = seq_new[in].getSequenceFeatures();
 
-            assertTrue("different number of features", seq_original[i]
-                    .getSequenceFeatures().length == seq_new[in]
+            assertEquals("different number of features",
+                    seq_original[i].getSequenceFeatures().length,
+                    seq_new[in]
                     .getSequenceFeatures().length);
 
             for (int feat = 0; feat < seq_original[i].getSequenceFeatures().length; feat++)
             {
-              assertTrue("Different features",
-                      sequenceFeatures_original[feat]
-                              .equals(sequenceFeatures_new[feat]));
+              assertEquals("Different features",
+                      sequenceFeatures_original[feat],
+                      sequenceFeatures_new[feat]);
             }
           }
           // compare alignment annotation
@@ -319,9 +315,9 @@ public class StockholmFileTest
           else if (al.getSequenceAt(i).getAnnotation() != null
                   && al_input.getSequenceAt(in).getAnnotation() == null)
           {
-            assertTrue("Annotations differed between sequences ("
+            fail("Annotations differed between sequences ("
                     + al.getSequenceAt(i).getName() + ") and ("
-                    + al_input.getSequenceAt(i).getName() + ")", false);
+                    + al_input.getSequenceAt(i).getName() + ")");
           }
           break;
         }
index 2074fb4..baaa96b 100644 (file)
@@ -138,7 +138,7 @@ public class StructureSelectionManagerTest
     SequenceFeature sf = pmap.getSeqs().get(0).getSequenceFeatures()[0];
     assertEquals("RESNUM", sf.getType());
     assertEquals("1gaq", sf.getFeatureGroup());
-    assertEquals("GLU:  19  1gaqA", sf.getDescription());
+    assertEquals("GLU:19 1gaqA", sf.getDescription());
 
     /*
      * Verify a RESNUM sequence feature in the StructureSelectionManager mapped
@@ -148,6 +148,6 @@ public class StructureSelectionManagerTest
     sf = map.sequence.getSequenceFeatures()[0];
     assertEquals("RESNUM", sf.getType());
     assertEquals("1gaq", sf.getFeatureGroup());
-    assertEquals("ALA:   1  1gaqB", sf.getDescription());
+    assertEquals("ALA:1 1gaqB", sf.getDescription());
   }
 }
index dbe1258..2a111ee 100644 (file)
@@ -28,6 +28,7 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.gui.Jalview2XML;
 import jalview.io.AnnotationFile;
+import jalview.io.FileLoader;
 import jalview.io.FormatAdapter;
 import jalview.io.StockholmFileTest;
 import jalview.ws.jws2.Jws2Discoverer;
@@ -49,6 +50,7 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import compbio.metadata.Argument;
 import compbio.metadata.WrongParameterException;
 
 public class RNAStructExportImport
@@ -88,9 +90,9 @@ public class RNAStructExportImport
       Assert.fail("no web service");
     }
 
-    jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
+    FileLoader fl = new FileLoader(false);
 
-    af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.FormatAdapter.FILE);
+    af = fl.LoadFileWaitTillLoaded(testseqs, FormatAdapter.FILE);
 
     assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
 
@@ -143,7 +145,6 @@ public class RNAStructExportImport
       } catch (InterruptedException x)
       {
       }
-      ;
     } while (af.getViewport().getCalcManager().isWorking());
 
     AlignmentI orig_alig = af.getViewport().getAlignment();
@@ -177,7 +178,6 @@ public class RNAStructExportImport
       } catch (InterruptedException x)
       {
       }
-      ;
     } while (af.getViewport().getCalcManager().isWorking());
 
     AlignmentI orig_alig = af.getViewport().getAlignment();
@@ -196,11 +196,11 @@ public class RNAStructExportImport
 
       String anfileout = new AnnotationFile()
               .printAnnotationsForAlignment(al);
-      assertTrue(
+      assertNotNull(
               "Test "
                       + testname
                       + "\nAlignment annotation file was not regenerated. Null string",
-              anfileout != null);
+              anfileout);
       assertTrue(
               "Test "
                       + testname
@@ -235,8 +235,8 @@ public class RNAStructExportImport
   @Test(groups = { "Functional" })
   public void testRnaalifoldSettingsRecovery()
   {
-    List<compbio.metadata.Argument> opts = new ArrayList<compbio.metadata.Argument>();
-    for (compbio.metadata.Argument rg : (List<compbio.metadata.Argument>) rnaalifoldws
+    List<Argument> opts = new ArrayList<Argument>();
+    for (Argument rg : (List<Argument>) rnaalifoldws
             .getRunnerConfig().getArguments())
     {
       if (rg.getDescription().contains("emperature"))
index 1f666a4..1ad5322 100644 (file)
@@ -90,7 +90,7 @@ public class HelpLinksChecker
       return;
     }
 
-    internetAvailable &= connectToUrl("http://www.example.com");
+    internetAvailable &= connectToUrl("http://www.example.org");
 
     Map<String, String> tocTargets = checkHelpMappings(helpFolder);
 
index 7850eb5..9d322df 100644 (file)
@@ -5,6 +5,7 @@ import java.io.IOException;
 import java.util.HashSet;
 import java.util.Properties;
 import java.util.TreeSet;
+import java.util.regex.Pattern;
 
 /**
  * This class scans Java source files for calls to MessageManager and reports
@@ -22,18 +23,32 @@ import java.util.TreeSet;
 public class MessageBundleChecker
 {
   /*
+   * regex ^"[^"]*"$
+   * opening quote, closing quote, no quotes in between
+   */
+  static Pattern STRING_PATTERN = Pattern.compile("^\"[^\"]*\"$");
+
+  /*
    * number of text lines to read at a time in order to parse
    * code that is split over several lines
    */
   static int bufferSize = 3;
 
+  /*
+   * resource bundle key is arg0 for these methods
+   */
   static final String METHOD1 = "MessageManager.getString(";
 
-  static final String METHOD2 = "MessageManager.getStringOrReturn(";
+  static final String METHOD2 = "MessageManager.formatMessage(";
 
-  static final String METHOD3 = "MessageManager.formatMessage(";
+  static final String METHOD3 = "MessageManager.getStringOrReturn(";
 
-  static final String[] METHODS = { METHOD1, METHOD2, METHOD3 };
+  /*
+   * resource bundle key is arg1 for this method
+   */
+  static final String JVINIT = "JvSwingUtils.jvInitComponent(";
+
+  static final String[] METHODS = { METHOD1, METHOD2, METHOD3, JVINIT };
 
   /*
    * root of the Java source folders we want to scan
@@ -123,7 +138,7 @@ public class MessageBundleChecker
             + " possibly invalid parameter calls");
 
     System.out.println(messageKeys.size()
-            + " keys not found, possibly unused");
+            + " keys not found, either unused or constructed dynamically");
     for (String key : messageKeys)
     {
       System.out.println("    " + key);
@@ -169,6 +184,14 @@ public class MessageBundleChecker
     }
     javaCount++;
 
+    /*
+     * skip class with designed dynamic lookup call
+     */
+    if (path.endsWith("gui/JvSwingUtils.java"))
+    {
+      return;
+    }
+
     String[] lines = new String[bufferSize];
     BufferedReader br = new BufferedReader(new FileReader(f));
     for (int i = 0; i < bufferSize; i++)
@@ -231,30 +254,61 @@ public class MessageBundleChecker
       {
         continue;
       }
-      String methodArgs = combined.substring(pos + method.length());
+
+      /*
+       * extract what follows the opening bracket of the method call
+       */
+      String methodArgs = combined.substring(pos + method.length()).trim();
       if ("".equals(methodArgs))
       {
         /*
-         * continues on next line - catch in the next read loop iteration
+         * arguments are on next line - catch in the next read loop iteration
          */
         continue;
       }
-      if (!methodArgs.startsWith("\""))
+      if (methodArgs.indexOf(",") == -1 && methodArgs.indexOf(")") == -1)
       {
-        System.out.println(String.format(
-                "Possible dynamic key at %s line %s %s",
+        /*
+         * arguments continue on next line - catch in the next read loop iteration
+         */
+        continue;
+      }
+
+      if (JVINIT == method && methodArgs.indexOf(",") == -1)
+      {
+        /*
+         * not interested in 1-arg calls to jvInitComponent
+         */
+        continue;
+      }
+
+      if (METHOD3 == method)
+      {
+        System.out.println(String.format("Dynamic key at %s line %s %s",
                 path.substring(sourcePath.length()), lineNos, combined));
         continue;
       }
-      methodArgs = methodArgs.substring(1);
-      int quotePos = methodArgs.indexOf("\"");
-      if (quotePos == -1)
+
+      String messageKey = getMessageKey(method, methodArgs);
+      if (messageKey == null)
       {
         System.out.println(String.format("Trouble parsing %s line %s %s",
                 path.substring(sourcePath.length()), lineNos, combined));
         continue;
       }
-      String messageKey = methodArgs.substring(0, quotePos);
+
+      if (!(STRING_PATTERN.matcher(messageKey).matches()))
+      {
+        System.out.println(String.format("Dynamic key at %s line %s %s",
+                path.substring(sourcePath.length()), lineNos, combined));
+        continue;
+      }
+
+      /*
+       * strip leading and trailing quote
+       */
+      messageKey = messageKey.substring(1, messageKey.length() - 1);
+
       if (!this.messages.containsKey(messageKey))
       {
         System.out.println(String.format(
@@ -269,6 +323,47 @@ public class MessageBundleChecker
     }
   }
 
+  /**
+   * Helper method to parse out the resource bundle key parameter of a method
+   * call
+   * 
+   * @param method
+   * @param methodArgs
+   *          the rest of the source line starting with arguments to method
+   * @return
+   */
+  private String getMessageKey(String method, String methodArgs)
+  {
+    String key = methodArgs;
+
+    /*
+     * locate second argument if calling jvInitComponent()
+     */
+    if (method == JVINIT)
+    {
+      int commaLoc = methodArgs.indexOf(",");
+      if (commaLoc == -1)
+      {
+        return null;
+      }
+      key = key.substring(commaLoc + 1).trim();
+    }
+
+    /*
+     * take up to next comma or ) or end of line
+     */
+    int commaPos = key.indexOf(",");
+    int bracePos = key.indexOf(")");
+    int endPos = commaPos == -1 ? bracePos : (bracePos == -1 ? commaPos
+            : Math.min(commaPos, bracePos));
+    if (endPos == -1 && key.length() > 1 && key.endsWith("\""))
+    {
+      endPos = key.length();
+    }
+
+    return endPos == -1 ? null : key.substring(0, endPos);
+  }
+
   private String combineLines(String[] lines)
   {
     String combined = "";
index 47c404e..01973d2 100755 (executable)
@@ -19,8 +19,7 @@
         var logger = project.getBuildListeners( ).firstElement( );
         logger.setMessageOutputLevel( 1 );
     </script>
-       <echo message="Missing message labels compared to Messages.properties"/>
-       <foreach target="compareProperties" param="file2">
+       <foreach target="compareBundles" param="file2">
                <path>
                        <fileset dir="${basedir}/resources/lang">
                                <exclude name="Messages.properties" />
        </foreach>
 </target>
 
+<target name="compareBundles" description="compare a properties file with Messages.properties and vice versa">
+       <echo message=" "/>
+       <echo message="Missing message labels in ${file2} compared to Messages.properties"/>
+       <antcall target="compareProperties">
+               <param name="file1" value="resources/lang/Messages.properties"/>
+               <param name="file2" value="${file2}" />
+       </antcall>
+       <echo message=" "/>
+       <echo message="Missing message labels in Messages.properties compare to ${file2}"/>
+       <antcall target="compareProperties">
+               <param name="file2" value="resources/lang/Messages.properties"/>
+               <param name="file1" value="${file2}" />
+       </antcall>
+</target>
+               
 <target name="compareProperties" description="reports missing entries in one message bundle">
-    <loadproperties srcFile="resources/lang/Messages.properties" prefix="prefixfile1"/>
+    <loadproperties srcFile="${file1}" prefix="prefixfile1"/>
     <loadproperties srcFile="${file2}" prefix="prefixfile2"/>
 
     <propertyselector property="file1.list" delimiter="," match="prefixfile1\.(.+)" select="\1"/>
     <propertyselector property="file2.list" delimiter="," match="prefixfile2\.(.+)" select="\1"/>
        
-       <echo message=" "/>
-       <echo message="*** ${file2}:" />
     <for list="${file1.list}" param="file1.property">
         <sequential>
             <if>