Merge branch 'develop' into features/JAL-1812_JAL-2083_groovyBinding features/JAL-1812_JAL-2083_groovyBinding
authorJim Procter <jprocter@issues.jalview.org>
Mon, 20 Jun 2016 09:53:46 +0000 (10:53 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Mon, 20 Jun 2016 09:53:46 +0000 (10:53 +0100)
1  2 
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/bin/Jalview.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/Desktop.java

@@@ -675,7 -675,7 +675,7 @@@ label.view_all_representative_structure
  label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment = Opens a new structure viewer with all representative structures\nassociated with the current selection\nsuperimposed with the current alignment.
  label.associate_structure_with_sequence = Associate Structure with Sequence
  label.from_file = From File
- label.enter_pdb_id = Enter PDB Id
+ label.enter_pdb_id = Enter PDB Id (Note: Specific chains can be retrieved by appending the chain code to the PDB Id delimited with a colon i.e. 1abc:X)
  label.discover_pdb_ids = Discover PDB IDs
  label.text_colour = Text Colour
  action.set_text_colour = Text Colour...
@@@ -801,6 -801,8 +801,8 @@@ label.wswublast_client_credits = To dis
  label.blasting_for_unidentified_sequence = BLASTing for unidentified sequences
  label.select_columns_containing = Select columns containing
  label.select_columns_not_containing = Select columns that do not contain
+ label.hide_columns_containing = Hide columns containing
+ label.hide_columns_not_containing = Hide columns that do not contain
  option.trim_retrieved_seqs = Trim retrieved sequences
  label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences.
  label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=/<regex>/=$
@@@ -970,6 -972,7 +972,6 @@@ error.eps_generation_not_implemented = 
  error.png_generation_not_implemented = PNG Generation not yet implemented
  error.try_join_vamsas_session_another = Trying to join a vamsas session when another is already connected
  error.invalid_vamsas_session_id = Invalid vamsas session id
 -error.implementation_error_cannot_create_groovyshell = Implementation Error. Cannot create groovyShell without Groovy on the classpath!
  label.groovy_support_failed = Jalview Groovy Support Failed
  label.couldnt_create_groovy_shell = Couldn't create the groovy Shell. Check the error log for the details of what went wrong.
  error.unsupported_version_calcIdparam = Unsupported Version for calcIdparam {0}
@@@ -1026,7 -1029,7 +1028,7 @@@ error.implementation_error_need_to_have
  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 {2} containing features of type {3}  across {4} sequence(s)
+ label.view_controller_toggled_marked = {0} {1} columns containing features of type {2}  across {3} sequence(s)
  label.toggled = Toggled
  label.marked = Marked
  label.not = not
@@@ -1278,22 -1281,31 +1280,31 @@@ label.structure_chooser_filter_time = S
  label.structure_chooser_no_of_structures = Structure Chooser - {0} Found ({1})
  info.no_pdb_entry_found_for = No PDB entry found for {0}
  exception.unable_to_detect_internet_connection = Jalview is unable to detect an internet connection
- exception.pdb_rest_service_no_longer_available = PDB rest services no longer available!
+ exception.fts_rest_service_no_longer_available = {0} rest services no longer available!
  exception.resource_not_be_found = The requested resource could not be found
- exception.pdb_server_error = There seems to be an error from the PDB server
- exception.pdb_server_unreachable = Jalview is unable to reach the PDBe Solr server. \nPlease ensure that you are connected to the internet and try again.
+ exception.fts_server_error = There seems to be an error from the {0} server
+ exception.fts_server_unreachable = Jalview is unable to reach the {0} server. \nPlease ensure that you are connected to the internet and try again.
  label.nw_mapping = Needleman & Wunsch Alignment
  label.sifts_mapping = SIFTs Mapping
  label.mapping_method = Sequence \u27f7 Structure mapping method
- label.mapping_method = Sequence \u27f7 Structure mapping method
- status.waiting_for_user_to_select_output_file = Waiting for user to select {0} file.
- status.cancelled_image_export_operation = Cancelled {0} export operation.
- info.error_creating_file = Error creating {0} file.
+ status.waiting_for_user_to_select_output_file = Waiting for user to select {0} file
+ status.cancelled_image_export_operation = Cancelled {0} export operation
+ info.error_creating_file = Error creating {0} file
  exception.outofmemory_loading_mmcif_file = Out of memory loading mmCIF File
- info.error_creating_file = Error creating {0} file.
  label.run_groovy = Run Groovy console script
  label.run_groovy_tip = Run the script in the Groovy console over this alignment
  label.couldnt_run_groovy_script = Failed to run Groovy script
  label.uniprot_sequence_fetcher = UniProt Sequence Fetcher
  action.next_page= >> 
- action.prev_page= << 
+ action.prev_page= << 
+ label.next_page_tooltip=Next Page
+ label.prev_page_tooltip=Previous Page
+ exception.bad_request=Bad request. There is a problem with your input.
+ exception.service_not_available=Service not available. The server is being updated, try again later.
+ status.launching_3d_structure_viewer = Launching 3D Structure viewer...
+ status.fetching_3d_structures_for_selected_entries = Fetching 3D Structures for selected entries...
+ status.fetching_dbrefs_for_sequences_without_valid_refs = Fetching db refs for {0} sequence(s) without valid db ref required for SIFTS mapping
+ status.fetching_3d_structures_for = Fetching 3D Structure for {0}
+ status.obtaining_mapping_with_sifts = Obtaining mapping with SIFTS
+ status.obtaining_mapping_with_nw_alignment = Obtaining mapping with NW alignment
+ status.exporting_alignment_as_x_file = Exporting alignment as {0} file
@@@ -277,7 -277,7 +277,7 @@@ label.order_by_params = Ordenar por {0
  label.html_content = <html>{0}</html>
  label.paste_pdb_file= Pegar tu fichero PDB aquí.
  label.paste_pdb_file_for_sequence = Pegar fichero PDB para la secuencia {0}
- label.could_not_parse_newick_file  = No se pudo analizar el fichero Newick\\\!\\n {0}
+ label.could_not_parse_newick_file  = No se pudo analizar el fichero Newick\!\n {0}
  label.successfully_pasted_tcoffee_scores_to_alignment= Pegada exitosamente la puntuación T-Coffee al alineamiento.
  label.failed_add_tcoffee_scores = Fallo al añadir las puntuaciones T-Coffee: 
  label.successfully_pasted_annotation_to_alignment = Anotación pegada exitosamente al alineamiento.
@@@ -321,7 -321,7 +321,7 @@@ action.save_vamsas_session = Guardar Se
  label.select_vamsas_session_opened_as_new_vamsas_session= Selecciones una sesión vamsas para abrirla como una nueva sesión.
  label.open_saved_vamsas_session = Abrir una sesión VAMSAS guardada
  label.groovy_console = Consola Groovy 
- label.lineart = lineart
+ label.lineart = Lineart
  label.dont_ask_me_again = No volver a preguntar
  label.select_eps_character_rendering_style = Seleccionar el carácter EPS como estilo de visualización 
  label.invert_selection = Invertir selección
@@@ -336,26 -336,26 +336,26 @@@ label.example = Ejempl
  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.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?
  label.remove_user_defined_colour = Eliminar el color definido por el usuario
  label.you_must_select_least_two_sequences = Debes seleccionar al menos 2 secuencias.
  label.invalid_selection = Selección inválida
- label.principal_component_analysis_must_take_least_four_input_sequences = El an\u00E1lisis de la componente principal debe tomar\\nal menos 4 secuencias de entrada.
+ label.principal_component_analysis_must_take_least_four_input_sequences = El an\u00E1lisis de la componente principal debe tomar\nal menos 4 secuencias de entrada.
  label.sequence_selection_insufficient = Selección de secuencias insuficiente
  label.you_need_more_two_sequences_selected_build_tree = necesitas seleccionar más de dos secuencias para construir un árbol!
  label.not_enough_sequences = No suficientes secuencias
- label.selected_region_to_tree_may_only_contain_residues_or_gaps = La regi\u00F3n seleccionada para construir un \u00E1rbol puede\\ncontener s\u00F3lo residuos o espacios.\\nPrueba usando la funci\u00F3n Pad en el men\u00FA de edici\u00F3n,\\n o uno de los m\u00FAltiples servicios web de alineamiento de secuencias.
+ label.selected_region_to_tree_may_only_contain_residues_or_gaps = La regi\u00F3n seleccionada para construir un \u00E1rbol puede\ncontener s\u00F3lo residuos o espacios.\nPrueba usando la funci\u00F3n Pad en el men\u00FA de edici\u00F3n,\n o uno de los m\u00FAltiples servicios web de alineamiento de secuencias.
  label.sequences_selection_not_aligned = Las secuencias seleccionadas no están alineadas
- label.sequences_must_be_aligned_before_creating_tree = Las secuencias deben estar alineadas antes de crear el \u00E1rbol.\\nPrueba usando la funci\u00F3n Pad en el men\u00FA de editar,\\n o uno de los m\u00FAltiples servicios web de alineamiento de secuencias.
+ label.sequences_must_be_aligned_before_creating_tree = Las secuencias deben estar alineadas antes de crear el \u00E1rbol.\nPrueba usando la funci\u00F3n Pad en el men\u00FA de editar,\n o uno de los m\u00FAltiples servicios web de alineamiento de secuencias.
  label.sequences_not_aligned = Secuencias no alineadas
  label.problem_reading_tree_file =  Problema al leer el fichero del árbol
  label.possible_problem_with_tree_file = Posible problema con el fichero del árbol
  label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation = Por favor seleccionar al menos tres bases de al menos una secuencia para poder realizar la traducción de cDNA.
  label.translation_failed = Translation Failed
- label.error_when_translating_sequences_submit_bug_report = Desafortunadamente, algo fue mal a la hora de traducir tus secuencias.\\nPor favor, revisa la consola Jalview java \\ny presenta un informe de error que incluya el seguimiento.
+ label.error_when_translating_sequences_submit_bug_report = Desafortunadamente, algo fue mal a la hora de traducir tus secuencias.\nPor favor, revisa la consola Jalview java \ny presenta un informe de error que incluya el seguimiento.
  label.implementation_error  = Error de implementación:
  label.automatically_associate_pdb_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros PDB con las secuencias del alineamiento que tengan el mismo nombre?
  label.automatically_associate_pdb_files_by_name = Asociar los ficheros PDB por nombre automáticamente
@@@ -364,11 -364,11 +364,11 @@@ label.ignore_unmatched_dropped_files = 
  label.enter_view_name = Introducir nombre visible (¿?)
  label.enter_label = Introducir etiqueta
  label.enter_label_for_the_structure = Introducir una etiqueta para la estructura?
- label.pdb_entry_is_already_displayed = {0} Ya est\u00E1 mostrado.\\nQuieres volver a usar este visor?
+ label.pdb_entry_is_already_displayed = {0} Ya est\u00E1 mostrado.\nQuieres volver a usar este visor?
  label.map_sequences_to_visible_window = Mapa de secuencias en ventana visible: {0}
- label.add_pdbentry_to_view = Quieres a\u00F1adir {0} a la vista llamada\\n{1}\\n
+ label.add_pdbentry_to_view = Quieres a\u00F1adir {0} a la vista llamada\n{1}\n
  label.align_to_existing_structure_view = Alinear a una estructura ya existente
- label.pdb_entries_couldnt_be_retrieved = Las siguientes entradas pdb no pueden ser extra\u00EDdas del PDB\\\:\\n{0}\\nPor favor, prueba descarg\u00E1ndolas manualmente.
+ label.pdb_entries_couldnt_be_retrieved = Las siguientes entradas pdb no pueden ser extra\u00EDdas del PDB\:\n{0}\nPor favor, prueba descarg\u00E1ndolas manualmente.
  label.couldnt_load_file = No se pudo cargar el fichero
  label.couldnt_find_pdb_id_in_file = No se pudo encontrar un Id PDB en el fichero suministrado. Por favor, introduzca un Id para identificar esta estructura.
  label.no_pdb_id_in_file = No hay un Id PDB en el fichero
@@@ -394,11 -394,11 +394,11 @@@ label.invalid_url = URL Invalido
  label.error_loading_file = Error al cargar el fichero
  label.problems_opening_file = Encontrados problemas al abrir el fichero {0}!!
  label.file_open_error = Error al abrir el fichero
- label.no_das_sources_selected_warn = No han sido seleccionadas fuentes DAS.\\nPor favor, seleccione algunas fuentes y\\npruebe de nuevo.
+ label.no_das_sources_selected_warn = No han sido seleccionadas fuentes DAS.\nPor favor, seleccione algunas fuentes y\npruebe de nuevo.
  label.no_das_sources_selected_title = No han sido seleccionadas fuentes DAS
- label.colour_scheme_exists_overwrite = El esquema de colores {0} ya existe.\\nContinuar guardando el esquema de colores como {1}?
+ label.colour_scheme_exists_overwrite = El esquema de colores {0} ya existe.\nContinuar guardando el esquema de colores como {1}?
  label.duplicate_scheme_name = Duplicar nombre de esquema
- label.jalview_new_questionnaire = Hay un nuevo cuestionario disponible. Querr\u00EDa completarlo ahora ?\\n
+ label.jalview_new_questionnaire = Hay un nuevo cuestionario disponible. Querr\u00EDa completarlo ahora ?\n
  label.jalview_user_survey = Encuesta de usuario Jalview 
  label.alignment_properties = Propiedades del alineamiento: {0}
  label.alignment_props = Propiedades del alineamiento
@@@ -905,6 -905,7 +905,6 @@@ error.eps_generation_not_implemented = 
  error.png_generation_not_implemented = La generación de PNG no se ha implementado todavía
  error.try_join_vamsas_session_another = Tratando de establecer una sesión VAMSAS cuando ya había otra conectada
  error.invalid_vamsas_session_id = Identificador de sesión VAMSAS no válido
 -error.implementation_error_cannot_create_groovyshell = Error de implementación:no se puede crear groovyShell sin Groovy en el classpath
  label.groovy_support_failed = El soporte Groovy de Jalview ha fallado
  label.couldnt_create_groovy_shell = No es posible crear el shell de Groovy. Compruebe el fichero de log para conocer los detalles.
  error.unsupported_version_calcIdparam = Versión no soportada de {0}
@@@ -961,7 -962,7 +961,7 @@@ error.implementation_error_need_to_have
  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 {2} conteniendo características del tipo  {3} en {4} secuencia(s)
+ label.view_controller_toggled_marked = {0} {1} columnas conteniendo características del tipo {2} en {3} secuencia(s)
  label.toggled = Invertida
  label.marked = Marcada
  label.not = no
@@@ -1054,7 -1055,7 +1054,7 @@@ error.implementation_error_cannot_find_
  error.implementation_error_cannot_find_service_url_in_given_set_param_store = Error de implementación: la URL del servicio en el conjunto de URL  para este almacén de parámetros del servicio({0})
  exception.jobsubmission_invalid_params_set = Conjunto de parámetros no válido. Comprueba la implementación de Jalview
  exception.notvaliddata_group_contains_less_than_min_seqs = El grupo contiene menos de {0} secuencias.
- exception.outofmemory_loading_pdb_file = Sin menoria al cargar el fichero PDB
+ exception.outofmemory_loading_pdb_file = Sin memoria al cargar el fichero PDB
  exception.eps_coudnt_write_output_file = No es posible escribir el fichero de salida: {0}
  exception.eps_method_not_supported = Método actualmente no suportado por la versión {0} de EpsGraphics2D
  exception.eps_unable_to_get_inverse_matrix = Imposible obtener la inversa de la matrix: {0}
@@@ -1083,7 -1084,7 +1083,7 @@@ status.fetching_pdb = Recuperando PDB {
  status.refreshing_news = Refrescando noticias
  status.importing_vamsas_session_from = Importando sesión VAMSAS de {0}
  status.opening_params = Abriendo {0}
- status.waiting_sequence_database_fetchers_init = Esperando la inicialización de los recuperadores de bases de datos de secuencias
+ status.waiting_sequence_database_fetchers_init = Esperando inicialización de los recuperadores de bases de datos de secuencias
  status.init_sequence_database_fetchers = Inicializando recuperadores de bases de datos de secuencias
  status.fetching_sequence_queries_from = Recuperando {0} consultas de secuencias de {1}
  status.finshed_querying = Consulta finalizada
@@@ -1280,3 -1281,36 +1280,36 @@@ info.invalid_msa_input_mininfo=Necesit
  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
+ label.pdb_sequence_fetcher=Recuperador de secuencias PDB
+ exception.fts_server_error=Parece que hay un error desde el servidor {0}
+ exception.service_not_available=Servicio no disponible. El servidor se está actualizando, vuelva a intentarlo más tarde.
+ status.waiting_for_user_to_select_output_file=Esperando que el usuario seleccione el fichero {0}
+ action.prev_page=<< 
+ status.cancelled_image_export_operation=Operación de exportación {0} cancelada
+ label.couldnt_run_groovy_script=No se ha podido ejecutar el script Groovy
+ exception.bad_request=Solicitud incorrecta. Hay un problema con su entrada.
+ label.run_groovy=Ejecutar script Groovy desde la consola
+ action.next_page=>> 
+ label.uniprot_sequence_fetcher=Recuperador de secuencias UniProt
+ label.prev_page_tooltip=Página anterior
+ label.reverse=Invertir
+ label.hide_columns_containing=Ocultar las columnas que contengan
+ label.nucleotides=Nucleótidos
+ label.run_groovy_tip = Ejecutar script Groovy desde la consola sobre este alineamiento
+ label.nw_mapping=Alineamiento Needleman y Wunsch
+ label.proteins=Proteína 
+ label.reverse_complement=Invertir y complementar
+ label.next_page_tooltip=Página siguiente
+ label.sifts_mapping=Mapeado SIFTs
+ label.mapping_method=Método de mapeo de secuencia \u27F7 estructura
+ info.error_creating_file=Error al crear fichero {0}
+ exception.fts_rest_service_no_longer_available= Servicios Rest {0} ya no están disponibles! 
+ status.launching_3d_structure_viewer=Lanzando visualizador de estructura 3D...
+ status.obtaining_mapping_with_sifts=Obteniendo mapeo por SIFTS
+ status.fetching_3d_structures_for=Buscando la estructura 3D para {0}
+ status.fetching_3d_structures_for_selected_entries=Buscando las estructuras 3D para entradas seleccionadas...
+ status.fetching_dbrefs_for_sequences_without_valid_refs=Buscando referencias para {0} secuencia(s) sin referencia válida necesaria para mapeado SIFTS
+ status.obtaining_mapping_with_nw_alignment=Obteniendo mapeo por alineamiento Needleman y Wunsch
   */
  package jalview.bin;
  
 +import groovy.lang.Binding;
 +import groovy.util.GroovyScriptEngine;
 +
  import jalview.gui.AlignFrame;
  import jalview.gui.Desktop;
 +import jalview.gui.PromptUserConfig;
 +import jalview.io.AppletFormatAdapter;
  import jalview.io.BioJsHTMLOutput;
 +import jalview.io.FileLoader;
 +import jalview.io.FormatAdapter;
  import jalview.io.HtmlSvgOutput;
 +import jalview.io.IdentifyFile;
 +import jalview.io.NewickFile;
 +import jalview.schemes.ColourSchemeI;
 +import jalview.schemes.ColourSchemeProperty;
 +import jalview.schemes.UserColourScheme;
  import jalview.util.MessageManager;
  import jalview.util.Platform;
  import jalview.ws.jws2.Jws2Discoverer;
  
 -import java.awt.event.ActionEvent;
 -import java.awt.event.ActionListener;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
 +import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.net.MalformedURLException;
  import java.net.URI;
  import java.net.URL;
 -import java.net.URLDecoder;
  import java.security.AllPermission;
  import java.security.CodeSource;
  import java.security.PermissionCollection;
@@@ -71,15 -62,6 +71,15 @@@ import javax.swing.UIManager
   */
  public class Jalview
  {
 +  /*
 +   * singleton instance of this class
 +   */
 +  private static Jalview instance;
 +
 +  private Desktop desktop;
 +
 +  public static AlignFrame currentAlignFrame;
 +
    static
    {
      // grab all the rights we can the JVM
    }
  
    /**
 +   * keep track of feature fetching tasks.
 +   * 
 +   * @author JimP
 +   * 
 +   */
 +  class FeatureFetcher
 +  {
 +    /*
 +     * TODO: generalise to track all jalview events to orchestrate batch
 +     * processing events.
 +     */
 +
 +    private int queued = 0;
 +
 +    private int running = 0;
 +
 +    public FeatureFetcher()
 +    {
 +
 +    }
 +
 +    public void addFetcher(final AlignFrame af,
 +            final Vector<String> dasSources)
 +    {
 +      final long id = System.currentTimeMillis();
 +      queued++;
 +      final FeatureFetcher us = this;
 +      new Thread(new Runnable()
 +      {
 +
 +        @Override
 +        public void run()
 +        {
 +          synchronized (us)
 +          {
 +            queued--;
 +            running++;
 +          }
 +
 +          af.setProgressBar(MessageManager
 +                  .getString("status.das_features_being_retrived"), id);
 +          af.featureSettings_actionPerformed(null);
 +          af.featureSettings.fetchDasFeatures(dasSources, true);
 +          af.setProgressBar(null, id);
 +          synchronized (us)
 +          {
 +            running--;
 +          }
 +        }
 +      }).start();
 +    }
 +
 +    public synchronized boolean allFinished()
 +    {
 +      return queued == 0 && running == 0;
 +    }
 +
 +  }
 +
 +  public static Jalview getInstance()
 +  {
 +    return instance;
 +  }
 +
 +  /**
     * main class for Jalview application
     * 
     * @param args
     */
    public static void main(String[] args)
    {
 +    instance = new Jalview();
 +    instance.doMain(args);
 +  }
 +
 +  /**
 +   * @param args
 +   */
 +  void doMain(String[] args)
 +  {
+     System.setSecurityManager(null);
      System.out.println("Java version: "
              + System.getProperty("java.version"));
      System.out.println(System.getProperty("os.arch") + " "
      try
      {
        Cache.initLogger();
 -    } catch (java.lang.NoClassDefFoundError error)
 +    } catch (NoClassDefFoundError error)
      {
        error.printStackTrace();
        System.out
        System.exit(0);
      }
  
 -    Desktop desktop = null;
 +    desktop = null;
  
      try
      {
      }
  
      String file = null, protocol = null, format = null, data = null;
 -    jalview.io.FileLoader fileLoader = new jalview.io.FileLoader(!headless);
 -    Vector getFeatures = null; // vector of das source nicknames to fetch
 +    FileLoader fileLoader = new FileLoader(!headless);
 +    Vector<String> getFeatures = null; // vector of das source nicknames to
 +                                       // fetch
      // features from
      // loading is done.
      String groovyscript = null; // script to execute after all loading is
        System.out.println("No files to open!");
        System.exit(1);
      }
 -    String vamsasImport = aparser.getValue("vdoc"), vamsasSession = aparser
 -            .getValue("vsess");
 +    String vamsasImport = aparser.getValue("vdoc");
 +    String vamsasSession = aparser.getValue("vsess");
      if (vamsasImport != null || vamsasSession != null)
      {
        if (desktop == null || headless)
        {
          try
          {
 -          String viprotocol = jalview.io.AppletFormatAdapter
 +          String viprotocol = AppletFormatAdapter
                    .checkProtocol(vamsasImport);
            if (viprotocol == jalview.io.FormatAdapter.FILE)
            {
              inSession = desktop.vamsasImport(new File(vamsasImport));
            }
 -          else if (viprotocol == jalview.io.FormatAdapter.URL)
 +          else if (viprotocol == FormatAdapter.URL)
            {
              inSession = desktop.vamsasImport(new URL(vamsasImport));
            }
  
        if (!file.startsWith("http://"))
        {
 -        if (!(new java.io.File(file)).exists())
 +        if (!(new File(file)).exists())
          {
            System.out.println("Can't find " + file);
            if (headless)
          }
        }
  
 -      protocol = jalview.io.AppletFormatAdapter.checkProtocol(file);
 +      protocol = AppletFormatAdapter.checkProtocol(file);
  
 -      format = new jalview.io.IdentifyFile().identify(file, protocol);
 +      format = new IdentifyFile().identify(file, protocol);
  
        AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
                format);
        }
        else
        {
 -        Desktop.setCurrentAlignFrame(af);
 +        setCurrentAlignFrame(af);
          data = aparser.getValue("colour", true);
          if (data != null)
          {
            data.replaceAll("%20", " ");
  
 -          jalview.schemes.ColourSchemeI cs = jalview.schemes.ColourSchemeProperty
 -                  .getColour(af.getViewport().getAlignment(), data);
 +          ColourSchemeI cs = ColourSchemeProperty.getColour(af
 +                  .getViewport().getAlignment(), data);
  
            if (cs == null)
            {
 -            jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
 -                    "white");
 +            UserColourScheme ucs = new UserColourScheme("white");
              ucs.parseAppletParameter(data);
              cs = ucs;
            }
          if (data != null)
          {
            af.parseFeaturesFile(data,
 -                  jalview.io.AppletFormatAdapter.checkProtocol(data));
 +                  AppletFormatAdapter.checkProtocol(data));
            // System.out.println("Added " + data);
            System.out.println("CMD groups[-" + data
                    + "]  executed successfully!");
          if (data != null)
          {
            af.parseFeaturesFile(data,
 -                  jalview.io.AppletFormatAdapter.checkProtocol(data));
 +                  AppletFormatAdapter.checkProtocol(data));
            // System.out.println("Added " + data);
            System.out.println("CMD [-features " + data
                    + "]  executed successfully!");
            {
              System.out.println("CMD [-tree " + data
                      + "] executed successfully!");
 -            fin = new jalview.io.NewickFile(data,
 -                    jalview.io.AppletFormatAdapter.checkProtocol(data));
 +            fin = new NewickFile(data,
 +                    AppletFormatAdapter.checkProtocol(data));
              if (fin != null)
              {
                af.getViewport().setCurrentTree(
            // Execute the groovy script after we've done all the rendering stuff
            // and before any images or figures are generated.
            System.out.println("Executing script " + groovyscript);
 -          executeGroovyScript(groovyscript, new Object[] { desktop, af });
 +          executeGroovyScript(groovyscript, af);
            System.out.println("CMD groovy[" + groovyscript
                    + "] executed successfully!");
            groovyscript = null;
  
            if (format.equalsIgnoreCase("png"))
            {
 -            af.createPNG(new java.io.File(file));
 -            imageName = (new java.io.File(file)).getName();
 +            af.createPNG(new File(file));
 +            imageName = (new File(file)).getName();
              System.out.println("Creating PNG image: " + file);
              continue;
            }
            else if (format.equalsIgnoreCase("svg"))
            {
 -            File imageFile = new java.io.File(file);
 +            File imageFile = new File(file);
              imageName = imageFile.getName();
              af.createSVG(imageFile);
              System.out.println("Creating SVG image: " + file);
            }
            else if (format.equalsIgnoreCase("html"))
            {
 -            File imageFile = new java.io.File(file);
 +            File imageFile = new File(file);
              imageName = imageFile.getName();
 -            new HtmlSvgOutput(new java.io.File(file), af.alignPanel);
 +            new HtmlSvgOutput(new File(file), af.alignPanel);
              System.out.println("Creating HTML image: " + file);
              continue;
            }
            else if (format.equalsIgnoreCase("imgMap"))
            {
 -            af.createImageMap(new java.io.File(file), imageName);
 +            af.createImageMap(new File(file), imageName);
              System.out.println("Creating image map: " + file);
              continue;
            }
            else if (format.equalsIgnoreCase("eps"))
            {
 -            File outputFile = new java.io.File(file);
 +            File outputFile = new File(file);
              System.out.println("Creating EPS file: "
                      + outputFile.getAbsolutePath());
              af.createEPS(outputFile);
        }
        else
        {
 -        format = new jalview.io.IdentifyFile().identify(file, protocol);
 +        format = new IdentifyFile().identify(file, protocol);
        }
  
        startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
      // Once all other stuff is done, execute any groovy scripts (in order)
      if (groovyscript != null)
      {
 -      if (jalview.bin.Cache.groovyJarsPresent())
 +      if (Cache.groovyJarsPresent())
        {
          System.out.println("Executing script " + groovyscript);
 -        executeGroovyScript(groovyscript, new Object[] { desktop,
 -            startUpAlframe });
 +        executeGroovyScript(groovyscript, startUpAlframe);
        }
        else
        {
      /**
       * start a User Config prompt asking if we can log usage statistics.
       */
 -    jalview.gui.PromptUserConfig prompter = new jalview.gui.PromptUserConfig(
 -            desktop.desktop,
 +    PromptUserConfig prompter = new PromptUserConfig(
 +            Desktop.desktop,
              "USAGESTATS",
              "Jalview Usage Statistics",
              "Do you want to help make Jalview better by enabling "
     *          the Jalview Desktop object passed in to the groovy binding as the
     *          'Jalview' object.
     */
 -  private static void executeGroovyScript(String groovyscript,
 -          Object[] jalviewContext)
 +  private void executeGroovyScript(String groovyscript, AlignFrame af)
    {
 -    if (jalviewContext == null)
 -    {
 -      System.err
 -              .println("Sorry. Groovy support is currently only available when running with the Jalview GUI enabled.");
 -    }
      /**
       * for scripts contained in files
       */
          tfile = File.createTempFile("jalview", "groovy");
          PrintWriter outfile = new PrintWriter(new OutputStreamWriter(
                  new FileOutputStream(tfile)));
 -        BufferedReader br = new BufferedReader(
 -                new java.io.InputStreamReader(System.in));
 +        BufferedReader br = new BufferedReader(new InputStreamReader(
 +                System.in));
          String line = null;
          while ((line = br.readLine()) != null)
          {
          }
        }
      }
 -    boolean success = false;
      try
      {
 -      /*
 -       * The following code performs the GroovyScriptEngine invocation using
 -       * reflection, and is equivalent to this fragment from the embedding
 -       * groovy documentation on the groovy site: <code> import
 -       * groovy.lang.Binding; import groovy.util.GroovyScriptEngine;
 -       * 
 -       * String[] roots = new String[] { "/my/groovy/script/path" };
 -       * GroovyScriptEngine gse = new GroovyScriptEngine(roots); Binding binding
 -       * = new Binding(); binding.setVariable("input", "world");
 -       * gse.run("hello.groovy", binding); </code>
 -       */
 -      Class<?>[] bspec;
 -      Object[] binding;
 -      int blen = ((jalviewContext[0] == null) ? 0 : 1)
 -              + ((jalviewContext[1] == null) ? 0 : 1);
 -      String cnames[] = new String[] { "Jalview", "currentAlFrame" };
 -      bspec = new Class[blen * 2];
 -      binding = new Object[blen * 2];
 -      blen = 0;
 -      ClassLoader cl = null;
        Map<String, Object> vbinding = new HashMap<String, Object>();
 -      for (int jc = 0; jc < jalviewContext.length; jc++)
 +      vbinding.put("Jalview", this);
 +      if (af != null)
        {
 -        if (jalviewContext[jc] != null)
 -        {
 -          if (cl == null)
 -          {
 -            cl = jalviewContext[jc].getClass().getClassLoader();
 -          }
 -          bspec[blen * 2] = String.class;
 -          bspec[blen * 2 + 1] = Object.class;
 -          binding[blen * 2] = cnames[jc];
 -          binding[blen * 2 + 1] = jalviewContext[jc];
 -          vbinding.put(cnames[jc], jalviewContext[jc]);
 -          blen++;
 -        }
 +        vbinding.put("currentAlFrame", af);
        }
 -      Class<?> gbindingc = cl.loadClass("groovy.lang.Binding");
 -      Constructor<?> gbcons;
 -      Object gbinding;
 -      try
 -      {
 -        gbcons = gbindingc.getConstructor(Map.class);
 -        gbinding = gbcons.newInstance(vbinding);
 -      } catch (NoSuchMethodException x)
 +      Binding gbinding = new Binding(vbinding);
 +      GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
 +      gse.run(sfile.toString(), gbinding);
 +      if ("STDIN".equals(groovyscript))
        {
 -        // old style binding config - using series of string/object values to
 -        // setVariable.
 -        gbcons = gbindingc.getConstructor();
 -        gbinding = gbcons.newInstance();
 -        java.lang.reflect.Method setvar = gbindingc.getMethod(
 -                "setVariable", bspec);
 -        setvar.invoke(gbinding, binding);
 +        // delete temp file that we made -
 +        // only if it was successfully executed
 +        tfile.delete();
        }
 -
 -      Class<?> gsec = cl.loadClass("groovy.util.GroovyScriptEngine");
 -      Constructor<?> gseccons = gsec
 -              .getConstructor(new Class[] { URL[].class }); // String[].class
 -                                                            // });
 -      Object gse = gseccons
 -              .newInstance(new Object[] { new URL[] { sfile } }); // .toString()
 -                                                                  // } });
 -      java.lang.reflect.Method run = gsec.getMethod("run", new Class[] {
 -          String.class, gbindingc });
 -      run.invoke(gse, new Object[] { sfile.toString(), gbinding });
 -      success = true;
      } catch (Exception e)
      {
        System.err.println("Exception Whilst trying to execute file " + sfile
        e.printStackTrace(System.err);
  
      }
 -    if (success && groovyscript.equals("STDIN"))
 -    {
 -      // delete temp file that we made - but only if it was successfully
 -      // executed
 -      tfile.delete();
 -    }
    }
  
    /**
     * 
     * @return vector of DAS source nicknames to retrieve from
     */
 -  private static Vector checkDasArguments(ArgsParser aparser)
 +  private static Vector<String> checkDasArguments(ArgsParser aparser)
    {
 -    Vector source = null;
 +    Vector<String> source = null;
      String data;
      String locsources = Cache.getProperty(Cache.DAS_LOCAL_SOURCE);
      while ((data = aparser.getValue("dasserver", true)) != null)
      {
        String nickname = null;
        String url = null;
 -      boolean seq = false, feat = true;
        int pos = data.indexOf('=');
        // determine capabilities
        if (pos > 0)
                          + nickname + "|" + url);
          if (source == null)
          {
 -          source = new Vector();
 +          source = new Vector<String>();
          }
          source.addElement(nickname);
        }
        System.out.println("adding source '" + data + "'");
        if (source == null)
        {
 -        source = new Vector();
 +        source = new Vector<String>();
        }
        source.addElement(data);
      }
     * 
     * @param dasSources
     */
 -  private static FeatureFetcher startFeatureFetching(final Vector dasSources)
 +  private FeatureFetcher startFeatureFetching(
 +          final Vector<String> dasSources)
    {
      FeatureFetcher ff = new FeatureFetcher();
      AlignFrame afs[] = Desktop.getAlignFrames();
      }
      return false;
    }
 -}
 -
 -/**
 - * Notes: this argParser does not distinguish between parameter switches,
 - * parameter values and argument text. If an argument happens to be identical to
 - * a parameter, it will be taken as such (even though it didn't have a '-'
 - * prefixing it).
 - * 
 - * @author Andrew Waterhouse and JBP documented.
 - * 
 - */
 -
 -class rnabuttonlistener implements ActionListener
 -{
 -  @Override
 -  public void actionPerformed(ActionEvent arg0)
 -  {
 -    System.out.println("Good idea ! ");
 -
 -  }
 -}
 -
 -class pbuttonlistener implements ActionListener
 -{
 -  @Override
 -  public void actionPerformed(ActionEvent arg0)
 -  {
 -
 -  }
 -}
 -
 -class ArgsParser
 -{
 -  Vector vargs = null;
  
 -  public ArgsParser(String[] args)
 -  {
 -    vargs = new Vector();
 -    for (int i = 0; i < args.length; i++)
 -    {
 -      String arg = args[i].trim();
 -      if (arg.charAt(0) == '-')
 -      {
 -        arg = arg.substring(1);
 -      }
 -      vargs.addElement(arg);
 -    }
 -  }
 -
 -  /**
 -   * check for and remove first occurence of arg+parameter in arglist.
 -   * 
 -   * @param arg
 -   * @return return the argument following the given arg if arg was in list.
 -   */
 -  public String getValue(String arg)
 +  public AlignFrame[] getAlignFrames()
    {
 -    return getValue(arg, false);
 -  }
 +    return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
 +            : Desktop.getAlignFrames();
  
    }
  
    /**
 -   * check for and remove first occurence of arg in arglist.
 -   * 
 -   * @param arg
 -   * @return true if arg was present in argslist.
 +   * Quit method delegates to Desktop.quit - unless running in headless mode
 +   * when it just ends the JVM
     */
 -  public boolean contains(String arg)
 +  public void quit()
    {
 -    if (vargs.contains(arg))
 +    if (desktop != null)
      {
 -      vargs.removeElement(arg);
 -      return true;
 +      desktop.quit();
      }
      else
      {
 -      return false;
 +      System.exit(0);
      }
    }
  
 -  public String nextValue()
 +  public static AlignFrame getCurrentAlignFrame()
    {
 -    return vargs.remove(0).toString();
 +    return Jalview.currentAlignFrame;
    }
  
 -  public int getSize()
 +  public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
    {
 -    return vargs.size();
 +    Jalview.currentAlignFrame = currentAlignFrame;
    }
 -
 -}
 -
 -/**
 - * keep track of feature fetching tasks.
 - * 
 - * @author JimP
 - * 
 - */
 -class FeatureFetcher
 -{
 -  /*
 -   * TODO: generalise to track all jalview events to orchestrate batch
 -   * processing events.
 -   */
 -
 -  private int queued = 0;
 -
 -  private int running = 0;
 -
 -  public FeatureFetcher()
 -  {
 -
 -  }
 -
 -  public void addFetcher(final AlignFrame af, final Vector dasSources)
 -  {
 -    final long id = System.currentTimeMillis();
 -    queued++;
 -    final FeatureFetcher us = this;
 -    new Thread(new Runnable()
 -    {
 -
 -      @Override
 -      public void run()
 -      {
 -        synchronized (us)
 -        {
 -          queued--;
 -          running++;
 -        }
 -
 -        af.setProgressBar(MessageManager
 -                .getString("status.das_features_being_retrived"), id);
 -        af.featureSettings_actionPerformed(null);
 -        af.featureSettings.fetchDasFeatures(dasSources, true);
 -        af.setProgressBar(null, id);
 -        synchronized (us)
 -        {
 -          running--;
 -        }
 -      }
 -    }).start();
 -  }
 -
 -  public synchronized boolean allFinished()
 -  {
 -    return queued == 0 && running == 0;
 -  }
 -
  }
@@@ -74,6 -74,7 +74,7 @@@ import jalview.io.JalviewFileView
  import jalview.io.JnetAnnotationMaker;
  import jalview.io.NewickFile;
  import jalview.io.TCoffeeScoreFile;
+ import jalview.io.gff.SequenceOntologyI;
  import jalview.jbgui.GAlignFrame;
  import jalview.schemes.Blosum62ColourScheme;
  import jalview.schemes.BuriedColourScheme;
@@@ -112,7 -113,6 +113,6 @@@ import java.awt.datatransfer.Clipboard
  import java.awt.datatransfer.DataFlavor;
  import java.awt.datatransfer.StringSelection;
  import java.awt.datatransfer.Transferable;
- import java.awt.dnd.DnDConstants;
  import java.awt.dnd.DropTargetDragEvent;
  import java.awt.dnd.DropTargetDropEvent;
  import java.awt.dnd.DropTargetEvent;
@@@ -473,7 -473,7 +473,7 @@@ public class AlignFrame extends GAlignF
        @Override
        public void focusGained(FocusEvent e)
        {
 -        Desktop.setCurrentAlignFrame(AlignFrame.this);
 +        Jalview.setCurrentAlignFrame(AlignFrame.this);
        }
      });
  
  
      if (viewport.hasHiddenColumns() && !settings.isExportHiddenColumns())
      {
-       omitHidden = viewport.getViewAsString(false);
+       omitHidden = viewport.getViewAsString(false,
+               settings.isExportHiddenSequences());
      }
  
      int[] alignmentStartEnd = new int[2];
      else
      {
        alignmentToExport = viewport.getAlignment();
-       alignmentStartEnd = viewport.getAlignment()
-               .getVisibleStartAndEndIndex(
-                       viewport
-               .getColumnSelection().getHiddenColumns());
      }
+     alignmentStartEnd = alignmentToExport
+             .getVisibleStartAndEndIndex(viewport.getColumnSelection()
+                     .getHiddenColumns());
      AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
              omitHidden, alignmentStartEnd, settings);
      return ed;
    }
  
    /**
     * DOCUMENT ME!
     * 
      return showp;
    }
  
+   /**
+    * Finds and displays cross-references for the selected sequences (protein
+    * products for nucleotide sequences, dna coding sequences for peptides).
+    * 
+    * @param sel
+    *          the sequences to show cross-references for
+    * @param dna
+    *          true if from a nucleotide alignment (so showing proteins)
+    * @param source
+    *          the database to show cross-references for
+    */
    protected void showProductsFor(final SequenceI[] sel, final boolean dna,
            final String source)
    {
  
              AlignFrame newFrame = new AlignFrame(al, DEFAULT_WIDTH,
                      DEFAULT_HEIGHT);
+             if (Cache.getDefault("HIDE_INTRONS", true))
+             {
+               newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
+             }
              String newtitle = String.format("%s %s %s",
                      MessageManager.getString(dna ? "label.proteins"
                              : "label.nucleotides"), MessageManager
                  System.err.println("Failed to make CDS alignment");
                }
                al.getCodonFrames().clear();
-               al.getCodonFrames().addAll(copyAlignment.getCodonFrames());
+               al.addCodonFrames(copyAlignment.getCodonFrames());
+               al.addCodonFrames(cf);
  
                /*
                 * pending getting Embl transcripts to 'align', 
              {
                copyAlignment = AlignmentUtils.makeCopyAlignment(
                        sequenceSelection, xrefs.getSequencesArray());
-               copyAlignment.getCodonFrames().addAll(cf);
+               copyAlignment.addCodonFrames(cf);
+               al.addCodonFrames(copyAlignment.getCodonFrames());
+               al.addCodonFrames(cf);
              }
              copyAlignment.setGapCharacter(AlignFrame.this.viewport
                      .getGapCharacter());
            }
          } catch (Exception e)
          {
-           Cache.log.error(
-                   "Exception when finding crossreferences", e);
+           Cache.log.error("Exception when finding crossreferences", e);
          } catch (OutOfMemoryError e)
          {
            new OOMWarning("whilst fetching crossreferences", e);
          } catch (Throwable e)
          {
-           Cache.log.error("Error when finding crossreferences",
-                   e);
+           Cache.log.error("Error when finding crossreferences", e);
          } finally
          {
            AlignFrame.this.setProgressBar(MessageManager.formatMessage(
                .getString("label.error_when_translating_sequences_submit_bug_report");
        final String errorTitle = MessageManager
                .getString("label.implementation_error")
-               + MessageManager.getString("translation_failed");
+               + MessageManager.getString("label.translation_failed");
        JOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
                JOptionPane.ERROR_MESSAGE);
        return;
    public void drop(DropTargetDropEvent evt)
    {
      Transferable t = evt.getTransferable();
-     java.util.List files = null;
+     java.util.List<String> files = new ArrayList<String>(), protocols = new ArrayList<String>();
  
      try
      {
-       DataFlavor uriListFlavor = new DataFlavor(
-               "text/uri-list;class=java.lang.String");
-       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
-       {
-         // Works on Windows and MacOSX
-         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
-         files = (java.util.List) t
-                 .getTransferData(DataFlavor.javaFileListFlavor);
-       }
-       else if (t.isDataFlavorSupported(uriListFlavor))
-       {
-         // This is used by Unix drag system
-         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
-         String data = (String) t.getTransferData(uriListFlavor);
-         files = new java.util.ArrayList(1);
-         for (java.util.StringTokenizer st = new java.util.StringTokenizer(
-                 data, "\r\n"); st.hasMoreTokens();)
-         {
-           String s = st.nextToken();
-           if (s.startsWith("#"))
-           {
-             // the line is a comment (as per the RFC 2483)
-             continue;
-           }
-           java.net.URI uri = new java.net.URI(s);
-           // check to see if we can handle this kind of URI
-           if (uri.getScheme().toLowerCase().startsWith("http"))
-           {
-             files.add(uri.toString());
-           }
-           else
-           {
-             // otherwise preserve old behaviour: catch all for file objects
-             java.io.File file = new java.io.File(uri);
-             files.add(file.toString());
-           }
-         }
-       }
+       Desktop.transferFromDropTarget(files, protocols, evt, t);
      } catch (Exception e)
      {
        e.printStackTrace();
                  AlignFrame.this.setMenusForViewport();
                }
              });
-             dbRefFetcher
-                     .fetchDBRefs(false);
+             dbRefFetcher.fetchDBRefs(false);
            }
          }).start();
  
      try
      {
        Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
        al = dna.reverseCdna(complement);
        viewport.addAlignment(al, "");
+       addHistoryItem(new EditCommand(
+               MessageManager.getString("label.add_sequences"),
+               Action.PASTE, al.getSequencesArray(), 0, al.getWidth(),
+               viewport.getAlignment()));
      } catch (Exception ex)
      {
        System.err.println(ex.getMessage());
    @Override
    protected void runGroovy_actionPerformed()
    {
 -    Desktop.setCurrentAlignFrame(this);
 +    Jalview.setCurrentAlignFrame(this);
      groovy.ui.Console console = Desktop.getGroovyConsole();
      if (console != null)
      {
        System.err.println("Can't run Groovy script as console not found");
      }
    }
+   /**
+    * Hides columns containing (or not containing) a specified feature, provided
+    * that would not leave all columns hidden
+    * 
+    * @param featureType
+    * @param columnsContaining
+    * @return
+    */
+   public boolean hideFeatureColumns(String featureType,
+           boolean columnsContaining)
+   {
+     boolean notForHiding = avc.markColumnsContainingFeatures(
+             columnsContaining, false, false, featureType);
+     if (notForHiding)
+     {
+       if (avc.markColumnsContainingFeatures(!columnsContaining, false,
+               false, featureType))
+       {
+         getViewport().hideSelectedColumns();
+         return true;
+       }
+     }
+     return false;
+   }
  }
  
  class PrintThread extends Thread
@@@ -169,6 -169,8 +169,6 @@@ public class Desktop extends jalview.jb
  
    static final int yOffset = 30;
  
 -  private static AlignFrame currentAlignFrame;
 -
    public static jalview.ws.jws1.Discoverer discoverer;
  
    public static Object[] jalviewClipboard;
    {
      boolean success = true;
      Transferable t = evt.getTransferable();
-     java.util.List files = null;
-     java.util.List protocols = null;
+     java.util.List<String> files = new ArrayList<String>();
+     java.util.List<String> protocols = new ArrayList<String>();
  
      try
      {
-       DataFlavor uriListFlavor = new DataFlavor(
-               "text/uri-list;class=java.lang.String");
-       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
-       {
-         // Works on Windows and MacOSX
-         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
-         files = (java.util.List) t
-                 .getTransferData(DataFlavor.javaFileListFlavor);
-       }
-       else if (t.isDataFlavorSupported(uriListFlavor))
-       {
-         // This is used by Unix drag system
-         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
-         String data = (String) t.getTransferData(uriListFlavor);
-         files = new java.util.ArrayList(1);
-         protocols = new java.util.ArrayList(1);
-         for (java.util.StringTokenizer st = new java.util.StringTokenizer(
-                 data, "\r\n"); st.hasMoreTokens();)
-         {
-           String s = st.nextToken();
-           if (s.startsWith("#"))
-           {
-             // the line is a comment (as per the RFC 2483)
-             continue;
-           }
-           java.net.URI uri = new java.net.URI(s);
-           if (uri.getScheme().toLowerCase().startsWith("http"))
-           {
-             protocols.add(FormatAdapter.URL);
-             files.add(uri.toString());
-           }
-           else
-           {
-             // otherwise preserve old behaviour: catch all for file objects
-             java.io.File file = new java.io.File(uri);
-             protocols.add(FormatAdapter.FILE);
-             files.add(file.toString());
-           }
-         }
-       }
+       Desktop.transferFromDropTarget(files, protocols, evt, t);
      } catch (Exception e)
      {
+       e.printStackTrace();
        success = false;
      }
  
      if (Jalview.isHeadlessMode())
      {
        // Desktop.desktop is null in headless mode
 -      return new AlignFrame[] { currentAlignFrame };
 +      return new AlignFrame[] { Jalview.currentAlignFrame };
      }
  
      JInternalFrame[] frames = Desktop.desktop.getAllFrames();
        @Override
        public void windowClosed(WindowEvent e)
        {
 -        groovyShell.setEnabled(true);
          enableExecuteGroovy(false);
        }
      });
       * if we got this far, enable 'Run Groovy' in AlignFrame menus
       * and disable opening a second console
       */
 -    groovyShell.setEnabled(false);
      enableExecuteGroovy(true);
    }
  
     * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
     * 
     * @param enabled
 +   *          true if Groovy console is open
     */
    public void enableExecuteGroovy(boolean enabled)
    {
 +    /*
 +     * disable opening a second Groovy console
 +     * (or re-enable when the console is closed)
 +     */
 +    groovyShell.setEnabled(!enabled);
 +
      AlignFrame[] alignFrames = getAlignFrames();
      if (alignFrames != null)
      {
       * The dust settles...give focus to the tab we did this from.
       */
      myTopFrame.setDisplayedView(myTopFrame.alignPanel);
 -
 -  }
 -
 -  public static AlignFrame getCurrentAlignFrame()
 -  {
 -    return currentAlignFrame;
 -  }
 -
 -  public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
 -  {
 -    Desktop.currentAlignFrame = currentAlignFrame;
    }
  
    public static groovy.ui.Console getGroovyConsole()
      return groovyConsole;
    }
  
+   public static void transferFromDropTarget(List<String> files,
+           List<String> protocols, DropTargetDropEvent evt, Transferable t)
+           throws Exception
+   {
+     DataFlavor uriListFlavor = new DataFlavor(
+             "text/uri-list;class=java.lang.String");
+     if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
+     {
+       // Works on Windows and MacOSX
+       Cache.log.debug("Drop handled as javaFileListFlavor");
+       evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+       for (Object file : (List) t
+               .getTransferData(DataFlavor.javaFileListFlavor))
+       {
+         files.add(((File)file).toString());
+         protocols.add(FormatAdapter.FILE);
+       }
+     }
+     else
+     {
+       // Unix like behaviour
+       boolean added = false;
+       String data = null;
+       if (t.isDataFlavorSupported(uriListFlavor))
+       {
+         Cache.log.debug("Drop handled as uriListFlavor");
+         // This is used by Unix drag system
+         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+         data = (String) t.getTransferData(uriListFlavor);
+       }
+       if (data == null)
+       {
+         // fallback to text: workaround - on OSX where there's a JVM bug
+         Cache.log.debug("standard URIListFlavor failed. Trying text");
+         // try text fallback
+         data = (String) t.getTransferData(new DataFlavor(
+                 "text/plain;class=java.lang.String"));
+         if (Cache.log.isDebugEnabled())
+         {
+           Cache.log.debug("fallback returned " + data);
+         }
+       }
+       while (protocols.size() < files.size())
+       {
+         Cache.log.debug("Adding missing FILE protocol for "
+                 + files.get(protocols.size()));
+         protocols.add(FormatAdapter.FILE);
+       }
+       for (java.util.StringTokenizer st = new java.util.StringTokenizer(
+               data, "\r\n"); st.hasMoreTokens();)
+       {
+         added = true;
+         String s = st.nextToken();
+         if (s.startsWith("#"))
+         {
+           // the line is a comment (as per the RFC 2483)
+           continue;
+         }
+         java.net.URI uri = new java.net.URI(s);
+         if (uri.getScheme().toLowerCase().startsWith("http"))
+         {
+           protocols.add(FormatAdapter.URL);
+           files.add(uri.toString());
+         }
+         else
+         {
+           // otherwise preserve old behaviour: catch all for file objects
+           java.io.File file = new java.io.File(uri);
+           protocols.add(FormatAdapter.FILE);
+           files.add(file.toString());
+         }
+       }
+       if (Cache.log.isDebugEnabled())
+       {
+         if (data == null || !added)
+         {
+           Cache.log
+                   .debug("Couldn't resolve drop data. Here are the supported flavors:");
+           for (DataFlavor fl : t.getTransferDataFlavors())
+           {
+             Cache.log.debug("Supported transfer dataflavor: "
+                     + fl.toString());
+             evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+             Object df = t.getTransferData(fl);
+             if (df != null)
+             {
+               Cache.log.debug("Retrieves: " + df);
+             }
+             else
+             {
+               Cache.log.debug("Retrieved nothing");
+             }
+           }
+         }
+       }
+     }
+   }
  }