From: gmungoc Date: Wed, 13 Mar 2019 09:26:03 +0000 (+0000) Subject: Merge branch 'develop' into trialMerge X-Git-Tag: Release_2_11_4_0~45^2~18^2~235 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=3da878124135ff033f42d19d8733891b09e953cd;p=jalview.git Merge branch 'develop' into trialMerge Conflicts: .classpath resources/lang/Messages.properties resources/lang/Messages_es.properties src/jalview/api/AlignViewportI.java src/jalview/fts/core/GFTSPanel.java src/jalview/gui/AlignFrame.java src/jalview/gui/AnnotationPanel.java src/jalview/gui/Desktop.java src/jalview/gui/FeatureSettings.java src/jalview/gui/Finder.java src/jalview/gui/IdPanel.java src/jalview/gui/Jalview2XML.java src/jalview/gui/PCAPanel.java src/jalview/gui/PopupMenu.java src/jalview/gui/Preferences.java src/jalview/gui/ScalePanel.java src/jalview/gui/SeqPanel.java src/jalview/io/JalviewFileChooser.java src/jalview/jbgui/GDesktop.java src/jalview/jbgui/GFinder.java src/jalview/jbgui/GPCAPanel.java src/jalview/util/DBRefUtils.java src/jalview/viewmodel/AlignmentViewport.java src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java test/jalview/io/CrossRef2xmlTests.java test/jalview/io/Jalview2xmlTests.java test/jalview/ws/dbsources/UniprotTest.java --- 3da878124135ff033f42d19d8733891b09e953cd diff --cc .ant-targets-build.xml index c965779,2a9de83..1daa59d --- a/.ant-targets-build.xml +++ b/.ant-targets-build.xml @@@ -4,15 -3,12 +4,15 @@@ buildPropertiesFil buildTests buildextclients buildindices - castorbinding clean +clean-site +compile-site compileApplet distclean +eclipse-install help init + jaxb-bindings linkcheck makeApplet makedist diff --cc .classpath index 9900500,4f9cb8a..c1e931c --- a/.classpath +++ b/.classpath @@@ -70,7 -67,6 +67,8 @@@ + + + diff --cc resources/lang/Messages.properties index 9764721,6b56f07..a105dfb --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@@ -1355,12 -1336,60 +1330,67 @@@ label.most_bound_molecules = Most Boun label.most_polymer_residues = Most Polymer Residues label.cached_structures = Cached Structures label.free_text_search = Free Text Search +label.annotation_name = Annotation Name +label.annotation_description = Annotation Description +label.edit_annotation_name_description = Edit Annotation Name/Description +label.alignment = alignment +label.pca = PCA +label.create_image_of = Create {0} image of {1} +label.click_to_edit = Click to edit, right-click for menu + label.backupfiles_confirm_delete = Confirm delete + label.backupfiles_confirm_delete_old_files = Delete the following older backup files? (see the Backups tab in Preferences for more options) + label.backupfiles_confirm_save_file = Confirm save file + label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Something possibly went wrong with the backups of this file. + label.backupfiles_confirm_save_new_saved_file_ok = The new saved file seems okay. + label.backupfiles_confirm_save_new_saved_file_not_ok = The new saved file might not be okay. + label.backups = Backups + label.backup = Backup + label.backup_files = Backup Files + label.enable_backupfiles = Enable backup files + label.backup_filename_strategy = Backup filename strategy + label.append_to_filename = Append to filename (%n is replaced by the backup number) + label.append_to_filename_tooltip = %n in the text will be replaced by the backup number. The text will appear after the filename. See the summary box above. + label.index_digits = Number of digits to use for the backup number (%n) + label.summary_of_backups_scheme = Summary of backup scheme + label.increment_index = Increase appended text numbers - newest file has largest number. + label.reverse_roll = "Roll" appended text numbers - newest backup file is always number 1. + label.keep_files = Deleting old backup files + label.keep_all_backup_files = Do not delete old backup files + label.keep_only_this_number_of_backup_files = Keep only this number of most recent backup files + label.autodelete_old_backup_files = Autodelete old backup files: + label.always_ask = Always ask + label.auto_delete = Automatically delete + label.filename = filename + label.braced_oldest = (oldest) + label.braced_newest = (most recent) label.configuration = Configuration label.configure_feature_tooltip = Click to configure variable colour or filters + label.schemes = Schemes + label.customise = Customise + label.default = Default + label.single_file = Single backup + label.keep_all_versions = Keep all versions + label.rolled_backups = Rolled backup files + label.previously_saved_scheme = Previously saved scheme + label.no_backup_files = NO BACKUP FILES + label.include_backup_files = Include backup files + label.cancel_changes = Cancel changes + label.warning_confirm_change_reverse = Warning!\nIf you change the increment/decrement of the backup filename number, without changing the suffix or number of digits,\nthis may cause loss of backup files created with the previous backup filename scheme.\nAre you sure you wish to do this? + label.change_increment_decrement = Change increment/decrement? + label.was_previous = was {0} + label.newerdelete_replacement_line = Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted and replaced by apparently older file\n''{1}''\t(modified {3}, size {5}). + label.confirm_deletion_or_rename = Confirm deletion of ''{0}'' or rename to ''{1}''? + label.newerdelete_line = Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted but is newer than the oldest remaining backup file\n''{1}''\t(modified {3}, size {5}). + label.confirm_deletion = Confirm deletion of ''{0}''? + label.delete = Delete + label.rename = Rename + label.keep = Keep + label.file_info = (modified {0}, size {1}) + label.annotation_name = Annotation Name + label.annotation_description = Annotation Description + label.edit_annotation_name_description = Edit Annotation Name/Description + label.alignment = alignment + label.pca = PCA + label.create_image_of = Create {0} image of {1} + label.click_to_edit = Click to edit, right-click for menu + label.by_annotation_tooltip = Annotation Colour is configured from the main Colour menu diff --cc resources/lang/Messages_es.properties index 1cca7a6,c367eea..f2695b2 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@@ -1356,12 -1337,60 +1331,67 @@@ label.most_bound_molecules = Más Molécu label.most_polymer_residues = Más Residuos de Polímeros label.cached_structures = Estructuras en Caché label.free_text_search = Búsqueda de texto libre +label.annotation_name = Nombre de la anotación +label.annotation_description = Descripción de la anotación +label.edit_annotation_name_description = Editar el nombre/descripción de la anotación +label.alignment = alineamiento +label.pca = ACP +label.create_image_of = Crear imagen {0} de {1} +label.click_to_edit = Haga clic para editar, clic en el botón derecho para ver el menú + label.backupfiles_confirm_delete = Confirmar borrar + label.backupfiles_confirm_delete_old_files = ¿Borrar los siguientes archivos? (ver la pestaña 'Copias' de la ventana de Preferencias para más opciones) + label.backupfiles_confirm_save_file = Confirmar guardar archivo + label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Posiblemente algo está mal con los archivos de respaldos. + label.backupfiles_confirm_save_new_saved_file_ok = El nuevo archivo guardado parece estar bien. + label.backupfiles_confirm_save_new_saved_file_not_ok = El nuevo archivo guardado podría no estar bien. + label.backups = Respaldos + label.backup = Respaldo + label.backup_files = Archivos de respaldos + label.enable_backupfiles = Habilitar archivos de respaldos + label.backup_filename_strategy = Estrategia de nombres de archivo de respaldos + label.append_to_filename = Adjuntar texto (%n es reemplazado por el número de respaldo) + label.append_to_filename_tooltip = %n en el texto será reemplazado por el número de respaldo. El texto será después del nombre del archivo. Vea el cuadro de resumen arriba. + label.index_digits = Número de dígitos a utilizar para el número de respaldo. + label.summary_of_backups_scheme = Resumen del esquema de copias de seguridad + label.increment_index = Aumente los números de texto adjuntos: el archivo más nuevo tiene el número más grande + label.reverse_roll = Ciclos de texto adjuntos: el respaldo más reciente es siempre el número 1 + label.keep_files = Borrando los respaldos antiguos + label.keep_all_backup_files = No borrar respaldos antiguas + label.keep_only_this_number_of_backup_files = Mantenga solo este número de respaldos más recientes + label.autodelete_old_backup_files = Borrer automáticamente respaldos antiguos: + label.always_ask = Pregunta siempre + label.auto_delete = Borrer automáticamente + label.filename = nombre_de_archivo + label.braced_oldest = (mas antiguo) + label.braced_newest = (mas nuevo) label.configuration = Configuración label.configure_feature_tooltip = Haga clic para configurar el color o los filtros + label.schemes = Esquemas + label.customise = Personalizado + label.default = Defecto + label.single_file = Solo uno respaldo + label.keep_all_versions = Mantener todas las versiones + label.rolled_backups = Ciclos respaldos + label.previously_saved_scheme = Esquema previamente guardado + label.no_backup_files = NO ARCHIVOS DE RESPALDOS + label.include_backup_files = Incluir archivos de respaldos + label.cancel_changes = Cancelar cambios + label.warning_confirm_change_reverse = ¡Advertencia!\nSi cambia el incremento/decremento del número de archivos de respaldos, sin cambiar el sufijo o número de dígitos,\nesto puede causar la pérdida de los archivos de respaldos creados con el esquema anterior de nombre de archivo de respaldos.\n¿Está seguro de que desea hacer esto? + label.change_increment_decrement = ¿Cambiar de incremento/decremento? + label.was_previous = era {0} + label.newerdelete_replacement_line = El archivo de respaldo\n''{0}''\t(modificado {2}, tamaño {4})\nserá borrado y reemplazarse por un archivo aparentemente más antiguo\n''{1}''\t(modificado {3}, tamaño {5}). + label.confirm_deletion_or_rename = Confirmar borrar ''{0}'', o cambiar el nombre a ''{1}''? + label.newerdelete_line = El archivo de respaldo\n''{0}''\t(modificado {2}, tamaño {4})\nserá borrado pero es mas nuevo que el archivo de respaldo restante más antiguo\n''{1}''\t(modified {3}, size {5}). + label.confirm_deletion = Confirmar eliminar ''{0}''? + label.delete = Borrar + label.rename = Cambiar + label.keep = Mantener + label.file_info = (modificado {0}, tamaño {1}) + label.annotation_name = Nombre de la anotación + label.annotation_description = Descripción de la anotación + label.edit_annotation_name_description = Editar el nombre/descripción de la anotación + label.alignment = alineamiento + label.pca = ACP + label.create_image_of = Crear imagen {0} de {1} + label.click_to_edit = Haga clic para editar, clic en el botón derecho para ver el menú + label.by_annotation_tooltip = El color de anotación se configura desde el menú principal de colores diff --cc src/jalview/api/AlignViewportI.java index b976a3d,389d9cf..fd4f74d --- a/src/jalview/api/AlignViewportI.java +++ b/src/jalview/api/AlignViewportI.java @@@ -488,16 -487,35 +488,44 @@@ public interface AlignViewportI extend @Override void setProteinFontAsCdna(boolean b); - public abstract TreeModel getCurrentTree(); + TreeModel getCurrentTree(); - public abstract void setCurrentTree(TreeModel tree); + void setCurrentTree(TreeModel tree); + + /** + * Answers a data bean containing data for export as configured by the + * supplied options + * + * @param options + * @return + */ + AlignmentExportData getAlignExportData(AlignExportSettingsI options); + + /** + * @param update + * - set the flag for updating structures on next repaint + */ + void setUpdateStructures(boolean update); + + /** + * + * @return true if structure views will be updated on next refresh + */ + boolean isUpdateStructures(); + + /** + * check if structure views need to be updated, and clear the flag afterwards. + * + * @return if an update is needed + */ + boolean needToUpdateStructureViews(); + + /** + * Adds sequencegroup to the alignment in the view. Also adds a group to the + * complement view if one is defined. + * + * @param sequenceGroup + * - a group defined on sequences in the alignment held by the view + */ + void addSequenceGroup(SequenceGroup sequenceGroup); } diff --cc src/jalview/bin/Cache.java index 888dc29,19aa800..3c919cb --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@@ -616,9 -591,27 +607,27 @@@ public class Cach return def; } + public static int getDefault(String property, int def) + { + String string = getProperty(property); + if (string != null) + { + try + { + def = Integer.parseInt(string); + } catch (NumberFormatException e) + { + System.out.println("Error parsing int property '" + property + + "' with value '" + string + "'"); + } + } + + return def; + } + /** - * These methods are used when checking if the saved preference is different - * to the default setting + * Answers the value of the given property, or the supplied default value if + * the property is not set */ public static String getDefault(String property, String def) { diff --cc src/jalview/commands/EditCommand.java index 385a33e,b9d32f7..f2b3904 --- a/src/jalview/commands/EditCommand.java +++ b/src/jalview/commands/EditCommand.java @@@ -1475,14 -1476,20 +1476,20 @@@ public class EditCommand implements Com SequenceI[] seqs; - private int[] alIndex; + int[] alIndex; - private int position; + int position; - private int number; + int number; - private char gapChar; + char gapChar; + /* + * flag that identifies edits inserted to balance + * user edits in a 'locked editing' region + */ + private boolean systemGenerated; + public Edit(Action cmd, SequenceI[] sqs, int pos, int count, char gap) { diff --cc src/jalview/fts/core/GFTSPanel.java index abda7ac,232561c..51363b2 --- a/src/jalview/fts/core/GFTSPanel.java +++ b/src/jalview/fts/core/GFTSPanel.java @@@ -533,9 -548,10 +549,9 @@@ public abstract class GFTSPanel extend } }); - txt_search.getComponent().setFont(new java.awt.Font("Verdana", 0, 12)); - txt_search.setFont(VERDANA_12); ++ txt_search.getComponent().setFont(VERDANA_12); - txt_search.getEditor().getEditorComponent() - .addKeyListener(new KeyAdapter() + txt_search.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) @@@ -663,7 -681,8 +679,8 @@@ pnl_results.add(tabbedPane); pnl_inputs.add(cmb_searchTarget); - pnl_inputs.add(txt_search); + pnl_inputs.add(txt_search.getComponent()); + pnl_inputs.add(txt_help); pnl_inputs.add(btn_autosearch); pnl_inputs.add(lbl_loading); pnl_inputs.add(lbl_warning); diff --cc src/jalview/gui/AlignFrame.java index 2a5d372,a587ac3..011610c --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@@ -24,9 -24,10 +24,10 @@@ import jalview.analysis.AlignmentSorter import jalview.analysis.AlignmentUtils; import jalview.analysis.CrossRef; import jalview.analysis.Dna; + import jalview.analysis.GeneticCodeI; import jalview.analysis.ParseProperties; import jalview.analysis.SequenceIdMatcher; -import jalview.api.AlignExportSettingI; +import jalview.api.AlignExportSettingsI; import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; import jalview.api.AlignViewportI; @@@ -83,6 -85,6 +85,7 @@@ import jalview.io.ScoreMatrixFile import jalview.io.TCoffeeScoreFile; import jalview.io.vcf.VCFLoader; import jalview.jbgui.GAlignFrame; ++import jalview.project.Jalview2XML; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemes; import jalview.schemes.ResidueColourScheme; @@@ -137,11 -136,10 +140,12 @@@ import java.util.Hashtable import java.util.List; import java.util.Vector; + import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JInternalFrame; +import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JMenu; import javax.swing.JMenuItem; @@@ -1237,78 -1155,91 +1246,84 @@@ public class AlignFrame extends GAlignF if (FileFormat.Jalview.equals(format)) { String shortName = title; - - if (shortName.indexOf(java.io.File.separatorChar) > -1) + if (shortName.indexOf(File.separatorChar) > -1) { shortName = shortName.substring( - shortName.lastIndexOf(java.io.File.separatorChar) + 1); + shortName.lastIndexOf(File.separatorChar) + 1); } - lastSaveSuccessful = new jalview.project.Jalview2XML().saveAlignment(this, file, - shortName); - - success = new jalview.project.Jalview2XML().saveAlignment(this, file, - shortName); - ++ lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file, shortName); + statusBar.setText(MessageManager.formatMessage( "label.successfully_saved_to_file_in_format", new Object[] { fileName, format })); - + + return; } - else + + AlignExportSettingsI options = new AlignExportSettingsAdapter(false); + Runnable cancelAction = new Runnable() { - AlignmentExportData exportData = getAlignmentForExport(format, - viewport, null); - if (exportData.getSettings().isCancelled()) - { - return false; - } - FormatAdapter f = new FormatAdapter(alignPanel, - exportData.getSettings()); - String output = f.formatSequences(format, exportData.getAlignment(), // class - // cast - // exceptions - // will - // occur in the distant future - exportData.getOmitHidden(), exportData.getStartEndPostions(), - f.getCacheSuffixDefault(format), - viewport.getAlignment().getHiddenColumns()); - - if (output == null) + @Override + public void run() { - success = false; + lastSaveSuccessful = false; } - else + }; + Runnable outputAction = new Runnable() + { + @Override + public void run() { - // create backupfiles object and get new temp filename destination - BackupFiles backupfiles = new BackupFiles(file); - - try + // todo defer this to inside formatSequences (or later) + AlignmentExportData exportData = viewport + .getAlignExportData(options); + String output = new FormatAdapter(alignPanel, options) + .formatSequences(format, exportData.getAlignment(), + exportData.getOmitHidden(), + exportData.getStartEndPostions(), + viewport.getAlignment().getHiddenColumns()); + if (output == null) + { + lastSaveSuccessful = false; + } + else { - PrintWriter out = new PrintWriter( - new FileWriter(backupfiles.getTempFilePath())); ++ // create backupfiles object and get new temp filename destination ++ BackupFiles backupfiles = new BackupFiles(file); + try + { - PrintWriter out = new PrintWriter(new FileWriter(file)); ++ PrintWriter out = new PrintWriter( ++ new FileWriter(backupfiles.getTempFilePath())); + - out.print(output); - out.close(); - this.setTitle(file); - statusBar.setText(MessageManager.formatMessage( + out.print(output); + out.close(); + AlignFrame.this.setTitle(file); - setStatus(MessageManager.formatMessage( - "label.successfully_saved_to_file_in_format", - new Object[] - { fileName, format.getName() })); ++ statusBar.setText(MessageManager.formatMessage( + "label.successfully_saved_to_file_in_format", new Object[] + { fileName, format.getName() })); - } catch (Exception ex) - { - success = false; - ex.printStackTrace(); - } - - backupfiles.setWriteSuccess(success); - // do the backup file roll and rename the temp file to actual file - success = backupfiles.rollBackupsAndRenameTempFile(); + } catch (Exception ex) + { + lastSaveSuccessful = false; + ex.printStackTrace(); + } + ++ backupfiles.setWriteSuccess(lastSaveSuccessful); ++ // do the backup file roll and rename the temp file to actual file ++ lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile(); + } } - } + }; - if (!success) - { - JvOptionPane.showInternalMessageDialog(this, MessageManager - .formatMessage("label.couldnt_save_file", new Object[] - { fileName }), - MessageManager.getString("label.error_saving_file"), - JvOptionPane.WARNING_MESSAGE); - } - - return success; - } - - private void warningMessage(String warning, String title) - { - if (new jalview.util.Platform().isHeadless()) + /* + * show dialog with export options if applicable; else just do it + */ + if (AlignExportOptions.isNeeded(viewport, format)) { - System.err.println("Warning: " + title + "\nWarning: " + warning); - + AlignExportOptions choices = new AlignExportOptions( + alignPanel.getAlignViewport(), format, options); + choices.setResponseAction(0, outputAction); + choices.setResponseAction(1, cancelAction); + choices.showDialog(); } else { diff --cc src/jalview/gui/AlignmentPanel.java index 0ea2b8a,92b9a50..2aa21bb --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@@ -334,11 -333,11 +334,11 @@@ public class AlignmentPanel extends GAl */ public void highlightSearchResults(SearchResultsI results) { - boolean scrolled = scrollToPosition(results, 0, true, false); + boolean scrolled = scrollToPosition(results, 0, false); - boolean noFastPaint = scrolled && av.getWrapAlignment(); + boolean fastPaint = !(scrolled && av.getWrapAlignment()); - getSeqPanel().seqCanvas.highlightSearchResults(results, noFastPaint); + getSeqPanel().seqCanvas.highlightSearchResults(results, fastPaint); } /** @@@ -1192,35 -1204,34 +1176,30 @@@ } else { - if (graphics != null) - { - printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, - graphics, graphics); - im.writeImage(); - } + printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, + graphics, graphics); } - - } catch (OutOfMemoryError err) - { - // Be noisy here. - System.out.println("########################\n" + "OUT OF MEMORY " - + file + "\n" + "########################"); - new OOMWarning("Creating Image for " + file, err); - // System.out.println("Create IMAGE: " + err); - } catch (Exception ex) - { - ex.printStackTrace(); } - } finally - { + }; - } + String fileTitle = alignFrame.getTitle(); + ImageExporter exporter = new ImageExporter(writer, alignFrame, type, + fileTitle); + int imageWidth = aDimension.getWidth(); + int imageHeight = aDimension.getHeight() + borderBottomOffset; + String of = MessageManager.getString("label.alignment"); + exporter.doExport(file, this, imageWidth, imageHeight, of); } + /** + * Calculates and returns a suitable width and height (in pixels) for an + * exported image + * + * @return + */ public AlignmentDimension getAlignmentDimension() { - int maxwidth = av.getAlignment().getWidth(); - if (av.hasHiddenColumns()) - { - maxwidth = av.getAlignment().getHiddenColumns() - .absoluteToVisibleColumn(maxwidth); - } + int maxwidth = av.getAlignment().getVisibleWidth(); int height = ((av.getAlignment().getHeight() + 1) * av.getCharHeight()) + getScalePanel().getHeight(); diff --cc src/jalview/gui/Desktop.java index 30c37de,5071918..89499c1 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@@ -26,7 -26,7 +26,8 @@@ import jalview.api.AlignViewportI import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.bin.Jalview; +import jalview.gui.ImageExporter.ImageWriterI; + import jalview.io.BackupFiles; import jalview.io.DataSourceType; import jalview.io.FileFormat; import jalview.io.FileFormatException; @@@ -39,10 -39,10 +40,11 @@@ import jalview.io.JalviewFileChooser import jalview.io.JalviewFileView; import jalview.jbgui.GSplitFrame; import jalview.jbgui.GStructureViewer; + import jalview.project.Jalview2XML; import jalview.structure.StructureSelectionManager; import jalview.urls.IdOrgSettings; -import jalview.util.ImageMaker; +import jalview.util.BrowserLauncher; +import jalview.util.ImageMaker.TYPE; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.util.UrlConstants; @@@ -1645,24 -1600,49 +1647,49 @@@ public class Desktop extends jalview.jb } /** - * Shows a file chooser dialog and writes out the current session as a Jalview - * project file + * Prompts the user to choose a file and then saves the Jalview state as a + * Jalview project file */ @Override - public void saveState_actionPerformed(boolean asCastor) + public void saveState_actionPerformed() { - JalviewFileChooser chooser = new JalviewFileChooser( - asCastor ? "jvp" : "jvx", - "Jalview Project"); + saveState_actionPerformed(false); + } - chooser.setFileView(new JalviewFileView()); - chooser.setDialogTitle(MessageManager.getString("label.save_state")); - int option = chooser.showSaveDialog(this); - if (option == JalviewFileChooser.APPROVE_OPTION) + public void saveState_actionPerformed(boolean saveAs) + { + java.io.File projectFile = getProjectFile(); + // autoSave indicates we already have a file and don't need to ask + boolean autoSave = projectFile != null && !saveAs + && BackupFiles.getEnabled(); + + // System.out.println("autoSave="+autoSave+", projectFile='"+projectFile+"', + // saveAs="+saveAs+", Backups + // "+(BackupFiles.getEnabled()?"enabled":"disabled")); + + boolean approveSave = false; + if (!autoSave) { - File choice = chooser.getSelectedFile(); - setProjectFile(choice); + JalviewFileChooser chooser = new JalviewFileChooser("jvp", + "Jalview Project"); + + chooser.setFileView(new JalviewFileView()); + chooser.setDialogTitle(MessageManager.getString("label.save_state")); + + int value = chooser.showSaveDialog(this); + + if (value == JalviewFileChooser.APPROVE_OPTION) + { + projectFile = chooser.getSelectedFile(); + setProjectFile(projectFile); + approveSave = true; + } + } + if (approveSave || autoSave) + { + final Desktop me = this; + final java.io.File chosenFile = projectFile; new Thread(new Runnable() { @Override @@@ -1704,13 -1680,19 +1727,19 @@@ MessageManager.getString("label.couldnt_save_project"), JvOptionPane.WARNING_MESSAGE); } - setProgressBar(null, choice.hashCode()); + setProgressBar(null, chosenFile.hashCode()); } }).start(); - } + } } - void setProjectFile(File choice) + @Override + public void saveAsState_actionPerformed(ActionEvent e) + { + saveState_actionPerformed(true); + } + + private void setProjectFile(File choice) { this.projectFile = choice; } @@@ -1721,70 -1703,60 +1750,59 @@@ } /** - * Prompts the user to choose a file and loads in as a Jalview project file + * Shows a file chooser dialog and tries to read in the selected file as a + * Jalview project */ @Override - public void loadState_actionPerformed(boolean asCastor) + public void loadState_actionPerformed() { - // TODO: GET RID OF .JVX BEFORE RELEASE JIM! - final String[] suffix = asCastor ? new String[] { "jvp", "jar" } - : new String[] - { "jvx" }; - final String[] desc = asCastor - ? new String[] - { "Jalview Project", "Jalview Project (old)" } - : new String[] - { "Jalview Project" }; + final String[] suffix = new String[] { "jvp", "jar" }; + final String[] desc = new String[] { "Jalview Project", + "Jalview Project (old)" }; JalviewFileChooser chooser = new JalviewFileChooser( - Cache.getProperty("LAST_DIRECTORY"), suffix, - desc, - "Jalview Project"); + Cache.getProperty("LAST_DIRECTORY"), suffix, desc, + "Jalview Project", true, true); // last two booleans: allFiles, + // allowBackupFiles chooser.setFileView(new JalviewFileView()); chooser.setDialogTitle(MessageManager.getString("label.restore_state")); - - int value = chooser.showOpenDialog(this); - - if (value == JalviewFileChooser.APPROVE_OPTION) + chooser.setResponseHandler(0, new Runnable() { - final File selectedFile = chooser.getSelectedFile(); - setProjectFile(selectedFile); - final String choice = selectedFile.getAbsolutePath(); - Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent()); - new Thread(new Runnable() + @Override + public void run() { - @Override - public void run() + File selectedFile = chooser.getSelectedFile(); + setProjectFile(selectedFile); + String choice = selectedFile.getAbsolutePath(); + Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent()); + new Thread(new Runnable() { - setProgressBar(MessageManager.formatMessage( - "label.loading_jalview_project", new Object[] - { choice }), choice.hashCode()); - try - { - new Jalview2XML().loadJalviewAlign(choice); - } catch (OutOfMemoryError oom) - { - new OOMWarning("Whilst loading project from " + choice, oom); - } catch (Exception ex) + @Override + public void run() { - try { - if (asCastor) - { - new Jalview2XML().loadJalviewAlign(choice); - } - else - { - new jalview.project.Jalview2XML().loadJalviewAlign(selectedFile); - } - } catch (OutOfMemoryError oom) - Cache.log.error( - "Problems whilst loading project from " + choice, ex); - JvOptionPane.showMessageDialog(Desktop.desktop, - MessageManager.formatMessage( - "label.error_whilst_loading_project_from", - new Object[] - { choice }), - MessageManager.getString("label.couldnt_load_project"), - JvOptionPane.WARNING_MESSAGE); ++ try + { - new OOMWarning("Whilst loading project from " + choice, oom); - } catch (Exception ex) - { - Cache.log.error( - "Problems whilst loading project from " + choice, ex); - JvOptionPane.showMessageDialog(Desktop.desktop, - MessageManager.formatMessage( - "label.error_whilst_loading_project_from", - new Object[] - { choice }), - MessageManager.getString("label.couldnt_load_project"), - JvOptionPane.WARNING_MESSAGE); - } ++ new Jalview2XML().loadJalviewAlign(choice); ++ } catch (OutOfMemoryError oom) ++ { ++ new OOMWarning("Whilst loading project from " + choice, oom); ++ } catch (Exception ex) ++ { ++ Cache.log.error( ++ "Problems whilst loading project from " + choice, ex); ++ JvOptionPane.showMessageDialog(Desktop.desktop, ++ MessageManager.formatMessage( ++ "label.error_whilst_loading_project_from", ++ new Object[] ++ { choice }), ++ MessageManager.getString("label.couldnt_load_project"), ++ JvOptionPane.WARNING_MESSAGE); ++ } } - setProgressBar(null, choice.hashCode()); - } - }).start(); - } + }).start(); + } + }); + + chooser.showOpenDialog(this); } @Override diff --cc src/jalview/gui/FeatureSettings.java index b657ed3,4526517..33c22f4 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@@ -283,23 -249,19 +251,18 @@@ public class FeatureSettings extends JP return loc; } }; - - // next line is needed to avoid (quiet) exceptions thrown - // when column ordering changes so that the above constants - // no longer apply. - table.getTableHeader().setReorderingAllowed(false); // BH 2018 - - table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12)); - ToolTipManager.sharedInstance().registerComponent(table); - + JTableHeader tableHeader = table.getTableHeader(); + tableHeader.setFont(new Font("Verdana", Font.PLAIN, 12)); + tableHeader.setReorderingAllowed(false); + table.setFont(new Font("Verdana", Font.PLAIN, 12)); - - table.setDefaultEditor(FeatureColour.class, new ColorEditor(this)); + table.setDefaultEditor(FeatureColour.class, new ColorEditor()); table.setDefaultRenderer(FeatureColour.class, new ColorRenderer()); - table.setDefaultEditor(FeatureMatcherSet.class, new FilterEditor(this)); + table.setDefaultEditor(FeatureMatcherSet.class, new FilterEditor()); table.setDefaultRenderer(FeatureMatcherSet.class, new FilterRenderer()); - + TableColumn colourColumn = new TableColumn(COLOUR_COLUMN, 75, - new ColorRenderer(), new ColorEditor(this)); + new ColorRenderer(), new ColorEditor()); table.addColumn(colourColumn); TableColumn filterColumn = new TableColumn(FILTER_COLUMN, 75, diff --cc src/jalview/gui/FeatureTypeSettings.java index 060d976,82e826f..9ff51a8 --- a/src/jalview/gui/FeatureTypeSettings.java +++ b/src/jalview/gui/FeatureTypeSettings.java @@@ -941,14 -900,9 +915,9 @@@ public class FeatureTypeSettings extend { // invalid inputs are already handled on entry } - - /* - * min-max range is to (or from) threshold value if - * 'threshold is min/max' is selected - */ float minValue = min; float maxValue = max; - final int thresholdOption = threshold.getSelectedIndex(); + int thresholdOption = threshold.getSelectedIndex(); if (thresholdIsMin.isSelected() && thresholdOption == ABOVE_THRESHOLD_OPTION) { diff --cc src/jalview/gui/Finder.java index 2bad006,a4d7ad0..a1693f7 --- a/src/jalview/gui/Finder.java +++ b/src/jalview/gui/Finder.java @@@ -208,14 -211,10 +209,14 @@@ public class Finder extends GFinde @Override public void createFeatures_actionPerformed() { + if (searchResults.isEmpty()) + { + return; // shouldn't happen + } - List seqs = new ArrayList(); - List features = new ArrayList(); + List seqs = new ArrayList<>(); + List features = new ArrayList<>(); - String searchString = searchBox.getEditor().getItem().toString().trim(); + String searchString = searchBox.getUserInput(); String desc = "Search Results"; /* @@@ -286,23 -293,17 +284,19 @@@ } else { - searchResults = null; + createFeatures.setEnabled(true); } + searchBox.updateCache(); + ap.highlightSearchResults(searchResults); // TODO: add enablers for 'SelectSequences' or 'SelectColumns' or // 'SelectRegion' selection - if (!haveResults) + if (idMatch.isEmpty() && searchResults == null) { - resIndex = -1; - seqIndex = 0; JvOptionPane.showInternalMessageDialog(this, MessageManager.getString("label.finished_searching"), null, - JvOptionPane.INFORMATION_MESSAGE); + JvOptionPane.PLAIN_MESSAGE); } else { @@@ -320,12 -321,11 +314,10 @@@ message += searchResults.getSize() + " subsequence matches found."; } - resIndex = -1; - seqIndex = 0; JvOptionPane.showInternalMessageDialog(this, message, null, - JvOptionPane.INFORMATION_MESSAGE); + JvOptionPane.PLAIN_MESSAGE); } } - searchBox.updateCache(); } /** diff --cc src/jalview/gui/IdPanel.java index d34c653,d11d7a1..46e5f14 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@@ -41,8 -41,8 +43,9 @@@ import java.awt.event.MouseWheelListene import java.util.List; import javax.swing.JPanel; + import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; +import javax.swing.Timer; import javax.swing.ToolTipManager; /** diff --cc src/jalview/gui/PCAPanel.java index dbb014a,3388d4d..0a23517 --- a/src/jalview/gui/PCAPanel.java +++ b/src/jalview/gui/PCAPanel.java @@@ -29,9 -30,8 +30,10 @@@ import jalview.datamodel.AlignmentI import jalview.datamodel.AlignmentView; import jalview.datamodel.HiddenColumns; import jalview.datamodel.SequenceI; +import jalview.gui.ImageExporter.ImageWriterI; +import jalview.gui.JalviewColourChooser.ColourChooserListener; import jalview.jbgui.GPCAPanel; + import jalview.math.RotatableMatrix.Axis; import jalview.util.ImageMaker; import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; @@@ -49,7 -49,7 +51,6 @@@ import java.awt.print.PrinterException import java.awt.print.PrinterJob; import javax.swing.ButtonGroup; - import javax.swing.JCheckBoxMenuItem; -import javax.swing.JColorChooser; import javax.swing.JMenuItem; import javax.swing.JRadioButtonMenuItem; import javax.swing.event.InternalFrameAdapter; @@@ -210,20 -144,17 +145,20 @@@ public class PCAPanel extends GPCAPane } @Override - public void bgcolour_actionPerformed(ActionEvent e) + protected void bgcolour_actionPerformed() { - Color col = JColorChooser.showDialog(this, - MessageManager.getString("label.select_background_colour"), - getRotatableCanvas().getBgColour()); - - if (col != null) + String ttl = MessageManager.getString("label.select_background_colour"); + ColourChooserListener listener = new ColourChooserListener() { - getRotatableCanvas().setBgColour(col); - } - getRotatableCanvas().repaint(); + @Override + public void colourSelected(Color c) + { - rc.bgColour = c; ++ rc.setBgColour(c); + rc.repaint(); + } + }; - JalviewColourChooser.showColourChooser(this, ttl, rc.bgColour, ++ JalviewColourChooser.showColourChooser(this, ttl, rc.getBgColour(), + listener); } /** @@@ -518,26 -408,59 +412,27 @@@ } } - /** - * Handler for 'Save as EPS' option - */ - @Override - protected void eps_actionPerformed() - { - makePCAImage(ImageMaker.TYPE.EPS); - } - - /** - * Handler for 'Save as PNG' option - */ - @Override - protected void png_actionPerformed() - { - makePCAImage(ImageMaker.TYPE.PNG); - } - - void makePCAImage(ImageMaker.TYPE type) + public void makePCAImage(ImageMaker.TYPE type) { - int width = rc.getWidth(); - int height = rc.getHeight(); + int width = getRotatableCanvas().getWidth(); + int height = getRotatableCanvas().getHeight(); - - ImageMaker im; - - switch (type) + ImageWriterI writer = new ImageWriterI() { - case PNG: - im = new ImageMaker(this, ImageMaker.TYPE.PNG, - "Make PNG image from PCA", width, height, null, null, null, 0, - false); - break; - case EPS: - im = new ImageMaker(this, ImageMaker.TYPE.EPS, - "Make EPS file from PCA", width, height, null, - this.getTitle(), null, 0, false); - break; - default: - im = new ImageMaker(this, ImageMaker.TYPE.SVG, - "Make SVG file from PCA", width, height, null, - this.getTitle(), null, 0, false); - } - - if (im.getGraphics() != null) - { - getRotatableCanvas().drawBackground(im.getGraphics()); - getRotatableCanvas().drawScene(im.getGraphics()); - if (getRotatableCanvas().drawAxes) + @Override + public void exportImage(Graphics g) throws Exception { - rc.drawBackground(g, Color.black); - rc.drawScene(g); - if (rc.drawAxes) - getRotatableCanvas().drawAxes(im.getGraphics()); ++ RotatableCanvas canvas = getRotatableCanvas(); ++ canvas.drawBackground(g); ++ canvas.drawScene(g); ++ if (canvas.drawAxes) + { - rc.drawAxes(g); ++ canvas.drawAxes(g); + } } - im.writeImage(); - } + }; + String pca = MessageManager.getString("label.pca"); + ImageExporter exporter = new ImageExporter(writer, null, type, pca); + exporter.doExport(null, this, width, height, pca); } @Override diff --cc src/jalview/gui/PopupMenu.java index 6902c88,86febed..e78eaf2 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@@ -71,14 -69,13 +72,16 @@@ import java.util.SortedMap import java.util.TreeMap; import java.util.Vector; + import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; -import javax.swing.JColorChooser; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; +import javax.swing.JPanel; import javax.swing.JPopupMenu; + import javax.swing.JRadioButtonMenuItem; +import javax.swing.JScrollPane; /** * DOCUMENT ME! diff --cc src/jalview/gui/Preferences.java index 35641f8,ad3bfb5..284d3af --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@@ -819,10 -800,28 +826,31 @@@ public class Preferences extends GPrefe Cache.applicationProperties.setProperty("PAD_GAPS", Boolean.toString(padGaps.isSelected())); - wsPrefs.updateAndRefreshWsMenuConfig(false); + if (!Platform.isJS()) + { + wsPrefs.updateAndRefreshWsMenuConfig(false); + } + + /* + * Save Backups settings + */ + Cache.applicationProperties.setProperty(BackupFiles.CONFIRM_DELETE_OLD, + Boolean.toString(backupfilesConfirmDelete.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.ENABLED, + Boolean.toString(enableBackupFiles.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.NO_MAX, + Boolean.toString(backupfilesKeepAll.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.REVERSE_ORDER, + Boolean.toString(suffixReverse.isSelected())); + Cache.applicationProperties.setProperty(BackupFiles.SUFFIX, + suffixTemplate.getText()); + Cache.applicationProperties.setProperty(BackupFiles.ROLL_MAX, + Integer.toString(getSpinnerInt(backupfilesRollMaxSpinner, 4))); + Cache.applicationProperties.setProperty(BackupFiles.SUFFIX_DIGITS, + Integer.toString(getSpinnerInt(suffixDigitsSpinner, 3))); + Cache.applicationProperties.setProperty(BackupFiles.NS+"_PRESET", + Integer.toString(getComboIntStringKey(backupfilesPresetsCombo))); + Cache.saveProperties(); Desktop.instance.doConfigureStructurePrefs(); try diff --cc src/jalview/gui/ScalePanel.java index 6912a02,b95c569..9c2b42f --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@@ -276,12 -278,9 +276,11 @@@ public class ScalePanel extends JPane mouseDragging = false; ap.getSeqPanel().stopScrolling(); + // todo res calculation should be a method on AlignViewport int xCords = Math.max(0, evt.getX()); // prevent negative X coordinates - int res = (xCords / av.getCharWidth()) + av.getRanges().getStartRes(); + if (av.hasHiddenColumns()) { res = av.getAlignment().getHiddenColumns() diff --cc src/jalview/gui/SeqCanvas.java index de136ae,b3fcc54..2139b6b --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@@ -52,8 -53,13 +52,13 @@@ import javax.swing.JPanel * Wrapped mode, but not the scale above in Unwrapped mode. * */ -public class SeqCanvas extends JComponent implements ViewportListenerI +public class SeqCanvas extends JPanel implements ViewportListenerI { + /* + * pixels gap between sequences and annotations when in wrapped mode + */ + static final int SEQS_ANNOTATION_GAP = 3; + private static final String ZEROS = "0000000000"; final FeatureRenderer fr; @@@ -707,8 -728,9 +722,8 @@@ annotations.renderer.drawComponent(annotations, av, g, -1, startColumn, endx + 1); - g.translate(0, -cHeight - ypos - 3); + g.translate(0, -yShift); } - g.setClip(clip); g.translate(-xOffset, 0); } diff --cc src/jalview/gui/SeqPanel.java index e94ced2,4a1a9ee..546838d --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@@ -882,11 -996,37 +1005,39 @@@ public class SeqPanel extends JPane } } - + /** + * When the view is in wrapped mode, and the mouse is over an annotation row, + * shows the corresponding tooltip and status message (if any) + * + * @param pos + * @param column + */ + protected void mouseMovedOverAnnotation(MousePos pos) + { + final int column = pos.column; + final int rowIndex = pos.annotationIndex; + + if (column < 0 || !av.getWrapAlignment() || !av.isShowAnnotation() + || rowIndex < 0) + { + return; + } + AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation(); + + String tooltip = AnnotationPanel.buildToolTip(anns[rowIndex], column, + anns); + setToolTipText(tooltip); + lastTooltip = tooltip; + + String msg = AnnotationPanel.getStatusMessage(av.getAlignment(), column, + anns[rowIndex]); + ap.alignFrame.setStatus(msg); + } + private Point lastp = null; + private JToolTip tempTip = new JLabel().createToolTip(); + /* * (non-Javadoc) * @@@ -895,32 -1035,26 +1046,31 @@@ @Override public Point getToolTipLocation(MouseEvent event) { + // BH 2018 + - if (tooltipText == null || tooltipText.length() == 6) + if (tooltipText == null || tooltipText.length() <= 6) + { - lastp = null; return null; + } - int x = event.getX(); - int w = getWidth(); - // switch sides when tooltip is too close to edge - int wdth = (w - x < 200) ? -(w / 2) : 5; - Point p = lastp; - if (!event.isShiftDown() || p == null) + if (lastp != null && event.isShiftDown()) + { - p = new Point(event.getX() + wdth, event.getY() - 20); - lastp = p; + return lastp; + } - /* - * TODO: try to set position so region is not obscured by tooltip - */ - return p; + + Point p = lastp; + int x = event.getX(); + int y = event.getY(); + int w = getWidth(); + + tempTip.setTipText(formattedTooltipText); + int tipWidth = (int) tempTip.getPreferredSize().getWidth(); + + // was x += (w - x < 200) ? -(w / 2) : 5; + x = (x + tipWidth < w ? x + 10 : w - tipWidth); + p = new Point(x, y + 20); // BH 2018 was - 20? - /* - * TODO: try to modify position region is not obcured by tooltip - * - * Done? - */ + + return lastp = p; } String lastTooltip; @@@ -1625,9 -1924,15 +1940,15 @@@ @Override public void mouseExited(MouseEvent e) { - if (mouseDragging) + ap.alignFrame.setStatus(" "); + if (av.getWrapAlignment()) + { + return; + } + + if (mouseDragging && scrollThread == null) { - scrollThread = new ScrollThread(); + startScrolling(e.getPoint()); } } @@@ -1770,14 -2081,8 +2087,14 @@@ * (where isPopupTrigger() will answer true) * NB isRightMouseButton is also true for Cmd-click on Mac */ - if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac()) + if (Platform.isWinRightButton(evt)) + { + return; + } + + if (evt.isPopupTrigger()) // Mac: mousePressed { - showPopupMenu(evt); ++ showPopupMenu(evt, pos); return; } diff --cc src/jalview/gui/TreeCanvas.java index a0296ec,180467a..29ba52b --- a/src/jalview/gui/TreeCanvas.java +++ b/src/jalview/gui/TreeCanvas.java @@@ -27,13 -27,9 +27,10 @@@ import jalview.datamodel.Sequence import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.datamodel.SequenceNode; +import jalview.gui.JalviewColourChooser.ColourChooserListener; import jalview.schemes.ColourSchemeI; - import jalview.schemes.ColourSchemeProperty; - import jalview.schemes.UserColourScheme; import jalview.structure.SelectionSource; import jalview.util.Format; - import jalview.util.MappingUtils; import jalview.util.MessageManager; import java.awt.Color; diff --cc src/jalview/io/JalviewFileChooser.java index 67f1115,7fbe801..95f4c94 --- a/src/jalview/io/JalviewFileChooser.java +++ b/src/jalview/io/JalviewFileChooser.java @@@ -31,15 -30,13 +31,17 @@@ import java.awt.Component import java.awt.Dimension; import java.awt.EventQueue; import java.awt.HeadlessException; + import java.awt.event.ActionEvent; + import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.StringTokenizer; import java.util.Vector; @@@ -49,6 -48,9 +53,7 @@@ import javax.swing.JList import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SpringLayout; -import javax.swing.SwingUtilities; -import javax.swing.border.TitledBorder; + import javax.swing.filechooser.FileFilter; import javax.swing.plaf.basic.BasicFileChooserUI; /** @@@ -60,16 -62,17 +65,24 @@@ * @author AMW * */ -public class JalviewFileChooser extends JFileChooser +public class JalviewFileChooser extends JFileChooser implements DialogRunnerI, + PropertyChangeListener { + private static final long serialVersionUID = 1L; + + private Map callbacks = new HashMap<>(); + + File selectedFile = null; + /** + * backupfilesCheckBox = "Include backup files" checkbox includeBackupfiles = + * flag set by checkbox + */ + private JCheckBox backupfilesCheckBox = null; + + protected boolean includeBackupFiles = false; + + /** * Factory method to return a file chooser that offers readable alignment file * formats * @@@ -149,8 -160,14 +170,14 @@@ } JalviewFileChooser(String dir, String[] extensions, String[] descs, - String selected, boolean allFiles) + String selected, boolean acceptAny) { - this(dir, extensions, descs, selected, allFiles, false); ++ this(dir, extensions, descs, selected, acceptAny, false); + } + + public JalviewFileChooser(String dir, String[] extensions, String[] descs, - String selected, boolean allFiles, boolean allowBackupFiles) ++ String selected, boolean acceptAny, boolean allowBackupFiles) + { super(safePath(dir)); if (extensions.length == descs.length) { @@@ -159,7 -176,7 +186,7 @@@ { formats.add(new String[] { extensions[i], descs[i] }); } - init(formats, selected, acceptAny); - init(formats, selected, allFiles, allowBackupFiles); ++ init(formats, selected, acceptAny, allowBackupFiles); } else { @@@ -209,11 -205,17 +236,17 @@@ * @param formats * a list of {extensions, description} for each file format * @param selected - * @param allFiles + * @param acceptAny * if true, 'any format' option is included */ - void init(List formats, String selected, boolean allFiles) + void init(List formats, String selected, boolean acceptAny) { - init(formats, selected, allFiles, false); ++ init(formats, selected, acceptAny, false); + } + - void init(List formats, String selected, boolean allFiles, ++ void init(List formats, String selected, boolean acceptAny, + boolean allowBackupFiles) + { JalviewFileFilter chosen = null; diff --cc src/jalview/jbgui/GFinder.java index eb4b910,b433570..0da40cd --- a/src/jalview/jbgui/GFinder.java +++ b/src/jalview/jbgui/GFinder.java @@@ -140,10 -132,11 +131,10 @@@ public class GFinder extends JPane @Override public void caretUpdate(CaretEvent e) { - textfield_caretUpdate(e); + textfield_caretUpdate(); } }); - searchBox.getEditor().getEditorComponent() - .addKeyListener(new java.awt.event.KeyAdapter() + searchBox.addKeyListener(new java.awt.event.KeyAdapter() { @Override public void keyPressed(KeyEvent e) @@@ -167,10 -156,17 +154,17 @@@ actionsPanel.add(createFeatures, null); this.add(jLabelFind, java.awt.BorderLayout.WEST); this.add(actionsPanel, java.awt.BorderLayout.EAST); - // this.add(jPanel2, java.awt.BorderLayout.SOUTH); + + JPanel jPanel2 = new JPanel(); + jPanel2.setPreferredSize(new Dimension(10, 1)); + JPanel jPanel3 = new JPanel(); + jPanel3.setPreferredSize(new Dimension(10, 1)); + JPanel jPanel4 = new JPanel(); + jPanel4.setLayout(new BorderLayout()); + this.add(jPanel2, java.awt.BorderLayout.SOUTH); this.add(jPanel3, java.awt.BorderLayout.NORTH); this.add(jPanel4, java.awt.BorderLayout.CENTER); - jPanel4.add(searchBox, java.awt.BorderLayout.NORTH); + jPanel4.add(searchBox.getComponent(), java.awt.BorderLayout.NORTH); JPanel optionsPanel = new JPanel(); diff --cc src/jalview/jbgui/GPCAPanel.java index 4a9770f,122ad0f..32bd77d --- a/src/jalview/jbgui/GPCAPanel.java +++ b/src/jalview/jbgui/GPCAPanel.java @@@ -337,43 -287,23 +288,19 @@@ public class GPCAPanel extends JInterna viewMenu.add(associateViewsMenu); } - protected void scoreModel_menuSelected() - { - // TODO Auto-generated method stub - - } - - protected void resetButton_actionPerformed(ActionEvent e) - { - // TODO Auto-generated method stub - - } - - protected void protSetting_actionPerfomed(ActionEvent arg0) + protected void resetButton_actionPerformed() { - // TODO Auto-generated method stub - } - protected void nuclSetting_actionPerfomed(ActionEvent arg0) + protected void outputPoints_actionPerformed() { - // TODO Auto-generated method stub - } - protected void outputPoints_actionPerformed(ActionEvent e) + protected void outputProjPoints_actionPerformed() { - // TODO Auto-generated method stub - } - protected void outputProjPoints_actionPerformed(ActionEvent e) - { - // TODO Auto-generated method stub - - } - - protected void xCombobox_actionPerformed(ActionEvent e) - protected void eps_actionPerformed() - { - } - - protected void png_actionPerformed() ++ public void makePCAImage(TYPE imageType) { } diff --cc src/jalview/jbgui/GPreferences.java index 1e01cc3,87cc87b..cc95723 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@@ -23,10 -24,14 +24,15 @@@ import jalview.bin.Cache import jalview.fts.core.FTSDataColumnPreferences; import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource; import jalview.fts.service.pdb.PDBFTSRestClient; + import jalview.gui.Desktop; + import jalview.gui.JalviewBooleanRadioButtons; + import jalview.gui.JvOptionPane; import jalview.gui.JvSwingUtils; import jalview.gui.StructureViewer.ViewerType; + import jalview.io.BackupFilenameParts; + import jalview.io.BackupFiles; import jalview.util.MessageManager; +import jalview.util.Platform; import java.awt.BorderLayout; import java.awt.Color; diff --cc src/jalview/project/Jalview2XML.java index 336ea47,cf5974c..09f1675 --- a/src/jalview/project/Jalview2XML.java +++ b/src/jalview/project/Jalview2XML.java @@@ -29,9 -38,9 +38,10 @@@ import jalview.datamodel.AlignedCodonFr import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; +import jalview.datamodel.DBRefEntry; import jalview.datamodel.GraphLine; import jalview.datamodel.PDBEntry; + import jalview.datamodel.Point; import jalview.datamodel.RnaViewerModel; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; diff --cc src/jalview/util/DBRefUtils.java index 485d98c,5afbca5..fb54bba --- a/src/jalview/util/DBRefUtils.java +++ b/src/jalview/util/DBRefUtils.java @@@ -38,625 -38,668 +39,656 @@@ import com.stevesoft.pat.Regex /** * Utilities for handling DBRef objects and their collections. */ - public class DBRefUtils { + public class DBRefUtils + { + /* + * lookup from lower-case form of a name to its canonical (standardised) form + */ + private static Map canonicalSourceNameLookup = new HashMap<>(); - - static - { - // TODO load these from a resource file? - canonicalSourceNameLookup.put("uniprotkb/swiss-prot", - DBRefSource.UNIPROT); - canonicalSourceNameLookup.put("uniprotkb/trembl", DBRefSource.UNIPROT); - - // Ensembl values for dbname in xref REST service: - canonicalSourceNameLookup.put("uniprot/sptrembl", DBRefSource.UNIPROT); - canonicalSourceNameLookup.put("uniprot/swissprot", DBRefSource.UNIPROT); - - canonicalSourceNameLookup.put("pdb", DBRefSource.PDB); - canonicalSourceNameLookup.put("ensembl", DBRefSource.ENSEMBL); - // Ensembl Gn and Tr are for Ensembl genomic and transcript IDs as served - // from ENA. - canonicalSourceNameLookup.put("ensembl-tr", DBRefSource.ENSEMBL); - canonicalSourceNameLookup.put("ensembl-gn", DBRefSource.ENSEMBL); - - // Make sure we have lowercase entries for all canonical string lookups - Set keys = canonicalSourceNameLookup.keySet(); - for (String k : keys) - { - canonicalSourceNameLookup.put(k.toLowerCase(), - canonicalSourceNameLookup.get(k)); - } - - } + public final static int DB_SOURCE = 1; + public final static int DB_VERSION = 2; + public final static int DB_ID = 4; + public final static int DB_MAP = 8; + + public final static int SEARCH_MODE_NO_MAP_NO_VERSION = DB_SOURCE | DB_ID; + public final static int SEARCH_MODE_FULL = DB_SOURCE | DB_VERSION | DB_ID | DB_MAP; + - /* - * lookup from lower-case form of a name to its canonical (standardised) form - */ - private static Map canonicalSourceNameLookup = new HashMap(); - - private static Map dasCoordinateSystemsLookup = new HashMap(); - - static { ++ static ++ { + // TODO load these from a resource file? + canonicalSourceNameLookup.put("uniprotkb/swiss-prot", DBRefSource.UNIPROT); + canonicalSourceNameLookup.put("uniprotkb/trembl", DBRefSource.UNIPROT); + + // Ensembl values for dbname in xref REST service: + canonicalSourceNameLookup.put("uniprot/sptrembl", DBRefSource.UNIPROT); + canonicalSourceNameLookup.put("uniprot/swissprot", DBRefSource.UNIPROT); + + canonicalSourceNameLookup.put("pdb", DBRefSource.PDB); + canonicalSourceNameLookup.put("ensembl", DBRefSource.ENSEMBL); + // Ensembl Gn and Tr are for Ensembl genomic and transcript IDs as served + // from ENA. + canonicalSourceNameLookup.put("ensembl-tr", DBRefSource.ENSEMBL); + canonicalSourceNameLookup.put("ensembl-gn", DBRefSource.ENSEMBL); + - // Make sure we have lowercase entries for all canonical string lookups - // BH 2019.01.25 unnecessary -- they are all lower case already - // Set keys = canonicalSourceNameLookup.keySet(); - // for (String k : keys) - // { - // canonicalSourceNameLookup.put(k.toLowerCase(), - // canonicalSourceNameLookup.get(k)); - // } - - dasCoordinateSystemsLookup.put("pdbresnum", DBRefSource.PDB); - dasCoordinateSystemsLookup.put("uniprot", DBRefSource.UNIPROT); - dasCoordinateSystemsLookup.put("embl", DBRefSource.EMBL); - // dasCoordinateSystemsLookup.put("embl", DBRefSource.EMBLCDS); ++ // guarantee we always have lowercase entries for canonical string lookups ++ for (String k : canonicalSourceNameLookup.keySet()) ++ { ++ canonicalSourceNameLookup.put(k.toLowerCase(), ++ canonicalSourceNameLookup.get(k)); ++ } ++ } + + /** + * Returns those DBRefEntry objects whose source identifier (once converted to + * Jalview's canonical form) is in the list of sources to search for. Returns + * null if no matches found. + * - * @param dbrefs - * DBRefEntry objects to search - * @param sources - * array of sources to select ++ * @param dbrefs DBRefEntry objects to search ++ * @param sources array of sources to select + * @return + */ - public static DBRefEntry[] selectRefs(DBRefEntry[] dbrefs, - String[] sources) ++ public static List selectRefs(List dbrefs, String[] sources) + { - if (dbrefs == null || sources == null) - { - return dbrefs; - } - HashSet srcs = new HashSet<>(); - for (String src : sources) - { - srcs.add(src.toUpperCase()); - } - - List res = new ArrayList<>(); - for (DBRefEntry dbr : dbrefs) - { - String source = getCanonicalName(dbr.getSource()); - if (srcs.contains(source.toUpperCase())) - { - res.add(dbr); - } - } - - if (res.size() > 0) - { - DBRefEntry[] reply = new DBRefEntry[res.size()]; - return res.toArray(reply); - } - return null; ++ if (dbrefs == null || sources == null) ++ { ++ return dbrefs; + } + - /** - * Returns those DBRefEntry objects whose source identifier (once converted to - * Jalview's canonical form) is in the list of sources to search for. Returns - * null if no matches found. - * - * @param dbrefs DBRefEntry objects to search - * @param sources array of sources to select - * @return - */ - public static List selectRefs(List dbrefs, String[] sources) { - if (dbrefs == null || sources == null) { - return dbrefs; - } - - // BH TODO - HashSet srcs = new HashSet(); - for (String src : sources) { - srcs.add(src.toUpperCase()); - } - - int nrefs = dbrefs.size(); - List res = new ArrayList(); - for (int ib = 0; ib < nrefs; ib++) { - DBRefEntry dbr = dbrefs.get(ib); - String source = getCanonicalName(dbr.getSource()); - if (srcs.contains(source.toUpperCase())) { - res.add(dbr); - } - } - - if (res.size() > 0) { - // List reply = new DBRefEntry[res.size()]; - return res;// .toArray(reply); - } - return null; ++ // BH TODO (what?) ++ HashSet srcs = new HashSet(); ++ for (String src : sources) ++ { ++ srcs.add(src.toUpperCase()); + } + - private static boolean selectRefsBS(List dbrefs, int sourceKeys, BitSet bsSelect) { - if (dbrefs == null || sourceKeys == 0) { - return false; - } - for (int i = 0, n = dbrefs.size(); i < n; i++) { - DBRefEntry dbr = dbrefs.get(i); - if ((dbr.getSourceKey() & sourceKeys) != 0) { - bsSelect.clear(i); - } - } - return !bsSelect.isEmpty(); ++ int nrefs = dbrefs.size(); ++ List res = new ArrayList(); ++ for (int ib = 0; ib < nrefs; ib++) ++ { ++ DBRefEntry dbr = dbrefs.get(ib); ++ String source = getCanonicalName(dbr.getSource()); ++ if (srcs.contains(source.toUpperCase())) ++ { ++ res.add(dbr); ++ } + } - - /** - * isDasCoordinateSystem - * - * @param string String - * @param dBRefEntry DBRefEntry - * @return boolean true if Source DBRefEntry is compatible with DAS - * CoordinateSystem name - */ - - public static boolean isDasCoordinateSystem(String string, DBRefEntry dBRefEntry) { - if (string == null || dBRefEntry == null) { - return false; - } - String coordsys = dasCoordinateSystemsLookup.get(string.toLowerCase()); - return coordsys == null ? false : coordsys.equals(dBRefEntry.getSource()); ++ if (res.size() > 0) ++ { ++ // List reply = new DBRefEntry[res.size()]; ++ return res;// .toArray(reply); + } ++ return null; + } + - /** - * look up source in an internal list of database reference sources and return - * the canonical jalview name for the source, or the original string if it has - * no canonical form. - * - * @param source - * @return canonical jalview source (one of jalview.datamodel.DBRefSource.*) - * or original source - */ - public static String getCanonicalName(String source) ++ private static boolean selectRefsBS(List dbrefs, int sourceKeys, BitSet bsSelect) + { - if (source == null) - { - return null; - } - String canonical = canonicalSourceNameLookup.get(source.toLowerCase()); - return canonical == null ? source : canonical; - } - - /** - * Returns a (possibly empty) list of those references that match the given - * entry. Currently uses a comparator which matches if - *
    - *
  • database sources are the same
  • - *
  • accession ids are the same
  • - *
  • both have no mapping, or the mappings are the same
  • - *
- * - * @param ref - * Set of references to search - * @param entry - * pattern to match - * @return - */ - public static List searchRefs(DBRefEntry[] ref, - DBRefEntry entry) - { - return searchRefs(ref, entry, - matchDbAndIdAndEitherMapOrEquivalentMapList); - } - - /** - * Returns a list of those references that match the given accession id - *
    - *
  • database sources are the same
  • - *
  • accession ids are the same
  • - *
  • both have no mapping, or the mappings are the same
  • - *
- * - * @param refs - * Set of references to search - * @param accId - * accession id to match - * @return - */ - public static List searchRefs(DBRefEntry[] refs, String accId) - { - return searchRefs(refs, new DBRefEntry("", "", accId), matchId); ++ if (dbrefs == null || sourceKeys == 0) ++ { ++ return false; ++ } ++ for (int i = 0, n = dbrefs.size(); i < n; i++) ++ { ++ DBRefEntry dbr = dbrefs.get(i); ++ if ((dbr.getSourceKey() & sourceKeys) != 0) ++ { ++ bsSelect.clear(i); ++ } ++ } ++ return !bsSelect.isEmpty(); + } + + /** + * Returns a (possibly empty) list of those references that match the given + * entry, according to the given comparator. + * + * @param refs + * an array of database references to search + * @param entry + * an entry to compare against + * @param comparator + * @return + */ + static List searchRefs(DBRefEntry[] refs, DBRefEntry entry, + DbRefComp comparator) + { + List rfs = new ArrayList<>(); + if (refs == null || entry == null) + { + return rfs; + } + for (int i = 0; i < refs.length; i++) + { + if (comparator.matches(entry, refs[i])) + { + rfs.add(refs[i]); + } + } + return rfs; + } - interface DbRefComp - { - public boolean matches(DBRefEntry refa, DBRefEntry refb); - } - - /** - * match on all non-null fields in refa - */ - // TODO unused - remove? - public static DbRefComp matchNonNullonA = new DbRefComp() - { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb) - { - if (refa.getSource() == null - || DBRefUtils.getCanonicalName(refb.getSource()).equals( - DBRefUtils.getCanonicalName(refa.getSource()))) - { - if (refa.getVersion() == null - || refb.getVersion().equals(refa.getVersion())) - { - if (refa.getAccessionId() == null - || refb.getAccessionId().equals(refa.getAccessionId())) - { - if (refa.getMap() == null || (refb.getMap() != null - && refb.getMap().equals(refa.getMap()))) - { - return true; - } - } - } - } - return false; - } - }; - - /** - * either field is null or field matches for all of source, version, accession - * id and map. - */ - // TODO unused - remove? - public static DbRefComp matchEitherNonNull = new DbRefComp() - { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb) - { - if (nullOrEqualSource(refa.getSource(), refb.getSource()) - && nullOrEqual(refa.getVersion(), refb.getVersion()) - && nullOrEqual(refa.getAccessionId(), refb.getAccessionId()) - && nullOrEqual(refa.getMap(), refb.getMap())) - { - return true; - } - return false; - } - }; - - /** - * accession ID and DB must be identical. Version is ignored. Map is either - * not defined or is a match (or is compatible?) - */ - // TODO unused - remove? - public static DbRefComp matchDbAndIdAndEitherMap = new DbRefComp() - { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb) - { - if (refa.getSource() != null && refb.getSource() != null - && DBRefUtils.getCanonicalName(refb.getSource()).equals( - DBRefUtils.getCanonicalName(refa.getSource()))) - { - // We dont care about version - if (refa.getAccessionId() != null && refb.getAccessionId() != null - // FIXME should be && not || here? - || refb.getAccessionId().equals(refa.getAccessionId())) - { - if ((refa.getMap() == null || refb.getMap() == null) - || (refa.getMap() != null && refb.getMap() != null - && refb.getMap().equals(refa.getMap()))) - { - return true; - } - } - } - return false; - } - }; - - /** - * accession ID and DB must be identical. Version is ignored. No map on either - * or map but no maplist on either or maplist of map on a is the complement of - * maplist of map on b. - */ - // TODO unused - remove? - public static DbRefComp matchDbAndIdAndComplementaryMapList = new DbRefComp() - { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb) - { - if (refa.getSource() != null && refb.getSource() != null - && DBRefUtils.getCanonicalName(refb.getSource()).equals( - DBRefUtils.getCanonicalName(refa.getSource()))) - { - // We dont care about version - if (refa.getAccessionId() != null && refb.getAccessionId() != null - || refb.getAccessionId().equals(refa.getAccessionId())) - { - if ((refa.getMap() == null && refb.getMap() == null) - || (refa.getMap() != null && refb.getMap() != null)) - { - if ((refb.getMap().getMap() == null - && refa.getMap().getMap() == null) - || (refb.getMap().getMap() != null - && refa.getMap().getMap() != null - && refb.getMap().getMap().getInverse() - .equals(refa.getMap().getMap()))) - { - return true; - } - } - } - } - return false; - } - }; - - /** - * accession ID and DB must be identical. Version is ignored. No map on both - * or or map but no maplist on either or maplist of map on a is equivalent to - * the maplist of map on b. - */ - // TODO unused - remove? - public static DbRefComp matchDbAndIdAndEquivalentMapList = new DbRefComp() - { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb) - { - if (refa.getSource() != null && refb.getSource() != null - && DBRefUtils.getCanonicalName(refb.getSource()).equals( - DBRefUtils.getCanonicalName(refa.getSource()))) - { - // We dont care about version - // if ((refa.getVersion()==null || refb.getVersion()==null) - // || refb.getVersion().equals(refa.getVersion())) - // { - if (refa.getAccessionId() != null && refb.getAccessionId() != null - || refb.getAccessionId().equals(refa.getAccessionId())) - { - if (refa.getMap() == null && refb.getMap() == null) - { - return true; - } - if (refa.getMap() != null && refb.getMap() != null - && ((refb.getMap().getMap() == null - && refa.getMap().getMap() == null) - || (refb.getMap().getMap() != null - && refa.getMap().getMap() != null - && refb.getMap().getMap() - .equals(refa.getMap().getMap())))) - { - return true; - } - } - } - return false; - } - }; - - /** - * accession ID and DB must be identical, or null on a. Version is ignored. No - * map on either or map but no maplist on either or maplist of map on a is - * equivalent to the maplist of map on b. - */ - public static DbRefComp matchDbAndIdAndEitherMapOrEquivalentMapList = new DbRefComp() - { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb) - { - if (refa.getSource() != null && refb.getSource() != null - && DBRefUtils.getCanonicalName(refb.getSource()).equals( - DBRefUtils.getCanonicalName(refa.getSource()))) - { - // We dont care about version - - if (refa.getAccessionId() == null - || refa.getAccessionId().equals(refb.getAccessionId())) - { - if (refa.getMap() == null || refb.getMap() == null) - { - return true; - } - if ((refa.getMap() != null && refb.getMap() != null) - && (refb.getMap().getMap() == null - && refa.getMap().getMap() == null) - || (refb.getMap().getMap() != null - && refa.getMap().getMap() != null - && (refb.getMap().getMap() - .equals(refa.getMap().getMap())))) - { - return true; - } - } - } - return false; - } - }; - - /** - * accession ID only must be identical. - */ - public static DbRefComp matchId = new DbRefComp() - { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb) - { - if (refa.getAccessionId() != null && refb.getAccessionId() != null - && refb.getAccessionId().equals(refa.getAccessionId())) - { - return true; - } - return false; - } - }; - - /** - * Parses a DBRefEntry and adds it to the sequence, also a PDBEntry if the - * database is PDB. - *

- * Used by file parsers to generate DBRefs from annotation within file (eg - * Stockholm) - * - * @param dbname - * @param version - * @param acn - * @param seq - * where to annotate with reference - * @return parsed version of entry that was added to seq (if any) - */ - public static DBRefEntry parseToDbRef(SequenceI seq, String dbname, - String version, String acn) - { - DBRefEntry ref = null; - if (dbname != null) - { - String locsrc = DBRefUtils.getCanonicalName(dbname); - if (locsrc.equals(DBRefSource.PDB)) - { - /* - * Check for PFAM style stockhom PDB accession id citation e.g. - * "1WRI A; 7-80;" - */ - Regex r = new com.stevesoft.pat.Regex( - "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)"); - if (r.search(acn.trim())) - { - String pdbid = r.stringMatched(1); - String chaincode = r.stringMatched(2); - if (chaincode == null) - { - chaincode = " "; - } - // String mapstart = r.stringMatched(3); - // String mapend = r.stringMatched(4); - if (chaincode.equals(" ")) - { - chaincode = "_"; - } - // construct pdb ref. - ref = new DBRefEntry(locsrc, version, pdbid + chaincode); - PDBEntry pdbr = new PDBEntry(); - pdbr.setId(pdbid); - pdbr.setType(PDBEntry.Type.PDB); - pdbr.setChainCode(chaincode); - seq.addPDBId(pdbr); - } - else - { - System.err.println("Malformed PDB DR line:" + acn); - } - } - else - { - // default: - ref = new DBRefEntry(locsrc, version, acn); - } - } - if (ref != null) - { - seq.addDBRef(ref); - } - return ref; - } - - /** - * Returns true if either object is null, or they are equal - * - * @param o1 - * @param o2 - * @return - */ - public static boolean nullOrEqual(Object o1, Object o2) - { - if (o1 == null || o2 == null) - { - return true; - } - return o1.equals(o2); - } - - /** - * canonicalise source string before comparing. null is always wildcard - * - * @param o1 - * - null or source string to compare - * @param o2 - * - null or source string to compare - * @return true if either o1 or o2 are null, or o1 equals o2 under - * DBRefUtils.getCanonicalName - * (o1).equals(DBRefUtils.getCanonicalName(o2)) - */ - public static boolean nullOrEqualSource(String o1, String o2) - { - if (o1 == null || o2 == null) - { - return true; - } - return DBRefUtils.getCanonicalName(o1) - .equals(DBRefUtils.getCanonicalName(o2)); - } - - /** - * Selects just the DNA or protein references from a set of references - * - * @param selectDna - * if true, select references to 'standard' DNA databases, else to - * 'standard' peptide databases - * @param refs - * a set of references to select from - * @return - */ - public static DBRefEntry[] selectDbRefs(boolean selectDna, - DBRefEntry[] refs) - { - return selectRefs(refs, - selectDna ? DBRefSource.DNACODINGDBS : DBRefSource.PROTEINDBS); - // could attempt to find other cross - // refs here - ie PDB xrefs - // (not dna, not protein seq) - } - - /** + /** + * look up source in an internal list of database reference sources and return + * the canonical jalview name for the source, or the original string if it has + * no canonical form. + * + * @param source + * @return canonical jalview source (one of jalview.datamodel.DBRefSource.*) or + * original source + */ - public static String getCanonicalName(String source) { - if (source == null) { - return null; - } - String canonical = canonicalSourceNameLookup.get(source.toLowerCase()); - return canonical == null ? source : canonical; ++ public static String getCanonicalName(String source) ++ { ++ if (source == null) ++ { ++ return null; ++ } ++ String canonical = canonicalSourceNameLookup.get(source.toLowerCase()); ++ return canonical == null ? source : canonical; + } + + /** + * Returns a (possibly empty) list of those references that match the given + * entry. Currently uses a comparator which matches if + *

    + *
  • database sources are the same
  • + *
  • accession ids are the same
  • + *
  • both have no mapping, or the mappings are the same
  • + *
+ * + * @param ref Set of references to search + * @param entry pattern to match + * @param mode SEARCH_MODE_FULL for all; SEARCH_MODE_NO_MAP_NO_VERSION optional + * @return + */ + public static List searchRefs(List ref, DBRefEntry entry, int mode) { + return searchRefs(ref, entry, matchDbAndIdAndEitherMapOrEquivalentMapList, mode); + } + + /** + * Returns a list of those references that match the given accession id + *
    + *
  • database sources are the same
  • + *
  • accession ids are the same
  • + *
  • both have no mapping, or the mappings are the same
  • + *
+ * + * @param refs Set of references to search + * @param accId accession id to match + * @return + */ + public static List searchRefs(List refs, String accId) { + List rfs = new ArrayList(); + if (refs == null || accId == null) { + return rfs; + } + for (int i = 0, n = refs.size(); i < n; i++) { + DBRefEntry e = refs.get(i); + if (accId.equals(e.getAccessionId())) { + rfs.add(e); + } + } + return rfs; +// return searchRefs(refs, new DBRefEntry("", "", accId), matchId, SEARCH_MODE_FULL); + } + + /** + * Returns a (possibly empty) list of those references that match the given + * entry, according to the given comparator. + * + * @param refs an array of database references to search + * @param entry an entry to compare against + * @param comparator + * @param mode SEARCH_MODE_FULL for all; SEARCH_MODE_NO_MAP_NO_VERSION + * optional + * @return + */ + static List searchRefs(List refs, DBRefEntry entry, DbRefComp comparator, int mode) { + List rfs = new ArrayList(); + if (refs == null || entry == null) { + return rfs; + } + for (int i = 0, n = refs.size(); i < n; i++) { + DBRefEntry e = refs.get(i); + if (comparator.matches(entry, e, SEARCH_MODE_FULL)) { + rfs.add(e); + } + } + return rfs; + } + + interface DbRefComp { + default public boolean matches(DBRefEntry refa, DBRefEntry refb) { + return matches(refa, refb, SEARCH_MODE_FULL); + }; + + public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode); + } + + /** + * match on all non-null fields in refa + */ + // TODO unused - remove? would be broken by equating "" with null + public static DbRefComp matchNonNullonA = new DbRefComp() { + @Override + public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) { + if ((mode & DB_SOURCE) != 0 && + (refa.getSource() == null || DBRefUtils.getCanonicalName(refb.getSource()) + .equals(DBRefUtils.getCanonicalName(refa.getSource())))) { + if ((mode & DB_VERSION) != 0 && + (refa.getVersion() == null || refb.getVersion().equals(refa.getVersion()))) { + if ((mode & DB_ID) != 0 && + (refa.getAccessionId() == null || refb.getAccessionId().equals(refa.getAccessionId()))) { + if ((mode & DB_MAP) != 0 && + (refa.getMap() == null || (refb.getMap() != null && refb.getMap().equals(refa.getMap())))) { + return true; + } + } + } + } + return false; + } + }; + + /** + * either field is null or field matches for all of source, version, accession + * id and map. + */ + // TODO unused - remove? + public static DbRefComp matchEitherNonNull = new DbRefComp() { + @Override + public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) { + if (nullOrEqualSource(refa.getSource(), refb.getSource()) + && nullOrEqual(refa.getVersion(), refb.getVersion()) + && nullOrEqual(refa.getAccessionId(), refb.getAccessionId()) + && nullOrEqual(refa.getMap(), refb.getMap())) { + return true; + } + return false; + } + + }; + + /** + * accession ID and DB must be identical. Version is ignored. Map is either not + * defined or is a match (or is compatible?) + */ + // TODO unused - remove? + public static DbRefComp matchDbAndIdAndEitherMap = new DbRefComp() { + @Override + public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) { + if (refa.getSource() != null && refb.getSource() != null && DBRefUtils.getCanonicalName(refb.getSource()) + .equals(DBRefUtils.getCanonicalName(refa.getSource()))) { + // We dont care about version + if (refa.getAccessionId() != null && refb.getAccessionId() != null + // FIXME should be && not || here? + || refb.getAccessionId().equals(refa.getAccessionId())) { + if ((refa.getMap() == null || refb.getMap() == null) || (refa.getMap() != null + && refb.getMap() != null && refb.getMap().equals(refa.getMap()))) { + return true; + } + } + } + return false; + } + }; + + /** + * accession ID and DB must be identical. Version is ignored. No map on either + * or map but no maplist on either or maplist of map on a is the complement of + * maplist of map on b. + */ + // TODO unused - remove? + public static DbRefComp matchDbAndIdAndComplementaryMapList = new DbRefComp() { + @Override + public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) { + if (refa.getSource() != null && refb.getSource() != null && DBRefUtils.getCanonicalName(refb.getSource()) + .equals(DBRefUtils.getCanonicalName(refa.getSource()))) { + // We dont care about version + if (refa.getAccessionId() != null && refb.getAccessionId() != null + || refb.getAccessionId().equals(refa.getAccessionId())) { + if ((refa.getMap() == null && refb.getMap() == null) + || (refa.getMap() != null && refb.getMap() != null)) { + if ((refb.getMap().getMap() == null && refa.getMap().getMap() == null) + || (refb.getMap().getMap() != null && refa.getMap().getMap() != null + && refb.getMap().getMap().getInverse().equals(refa.getMap().getMap()))) { + return true; + } + } + } + } + return false; + } + }; + + /** + * accession ID and DB must be identical. Version is ignored. No map on both or + * or map but no maplist on either or maplist of map on a is equivalent to the + * maplist of map on b. + */ + // TODO unused - remove? + public static DbRefComp matchDbAndIdAndEquivalentMapList = new DbRefComp() { + @Override + public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) { + if (refa.getSource() != null && refb.getSource() != null && DBRefUtils.getCanonicalName(refb.getSource()) + .equals(DBRefUtils.getCanonicalName(refa.getSource()))) { + // We dont care about version + // if ((refa.getVersion()==null || refb.getVersion()==null) + // || refb.getVersion().equals(refa.getVersion())) + // { + if (refa.getAccessionId() != null && refb.getAccessionId() != null + || refb.getAccessionId().equals(refa.getAccessionId())) { + if (refa.getMap() == null && refb.getMap() == null) { + return true; + } + if (refa.getMap() != null && refb.getMap() != null + && ((refb.getMap().getMap() == null && refa.getMap().getMap() == null) + || (refb.getMap().getMap() != null && refa.getMap().getMap() != null + && refb.getMap().getMap().equals(refa.getMap().getMap())))) { + return true; + } + } + } + return false; + } + }; + + /** + * accession ID and DB must be identical, or null on a. Version is ignored. No + * map on either or map but no maplist on either or maplist of map on a is + * equivalent to the maplist of map on b. + */ - public static DbRefComp matchDbAndIdAndEitherMapOrEquivalentMapList = new DbRefComp() { ++ public static DbRefComp matchDbAndIdAndEitherMapOrEquivalentMapList = new DbRefComp() ++ { + @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) { ++ public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) ++ { + if (refa.getSource() != null && refb.getSource() != null && DBRefUtils.getCanonicalName(refb.getSource()) - .equals(DBRefUtils.getCanonicalName(refa.getSource()))) { ++ .equals(DBRefUtils.getCanonicalName(refa.getSource()))) ++ { + // We dont care about version - - if (refa.getAccessionId() == null || refa.getAccessionId().equals(refb.getAccessionId())) { - if (refa.getMap() == null || refb.getMap() == null) { ++ if (refa.getAccessionId() == null || refa.getAccessionId().equals(refb.getAccessionId())) ++ { ++ if (refa.getMap() == null || refb.getMap() == null) ++ { + return true; + } + if ((refa.getMap() != null && refb.getMap() != null) + && (refb.getMap().getMap() == null && refa.getMap().getMap() == null) + || (refb.getMap().getMap() != null && refa.getMap().getMap() != null - && (refb.getMap().getMap().equals(refa.getMap().getMap())))) { ++ && (refb.getMap().getMap().equals(refa.getMap().getMap())))) ++ { + return true; + } + } + } + return false; + } + }; + + /** - * accession ID only must be identical. - */ - public static DbRefComp matchId = new DbRefComp() { - @Override - public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode) { - if (refa.getAccessionId() != null && refb.getAccessionId() != null - && refb.getAccessionId().equals(refa.getAccessionId())) { - return true; - } - return false; - } - }; + * Returns the (possibly empty) list of those supplied dbrefs which have the + * specified source database, with a case-insensitive match of source name + * + * @param dbRefs + * @param source + * @return + */ + public static List searchRefsForSource(DBRefEntry[] dbRefs, + String source) + { + List matches = new ArrayList<>(); + if (dbRefs != null && source != null) + { + for (DBRefEntry dbref : dbRefs) + { + if (source.equalsIgnoreCase(dbref.getSource())) + { + matches.add(dbref); + } + } + } + return matches; + } - /** - * promote direct database references to primary for nucleotide or protein - * sequences if they have an appropriate primary ref - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
Seq TypePrimary DBDirect which will be promoted
peptidesEnsemblUniprot
peptidesEnsemblUniprot
dnaEnsemblENA
- * - * @param sequence - */ - public static void ensurePrimaries(SequenceI sequence) - { - List pr = sequence.getPrimaryDBRefs(); - if (pr.size() == 0) - { - // nothing to do - return; - } - List selfs = new ArrayList<>(); - { - DBRefEntry[] selfArray = selectDbRefs(!sequence.isProtein(), - sequence.getDBRefs()); - if (selfArray == null || selfArray.length == 0) - { - // nothing to do - return; - } - selfs.addAll(Arrays.asList(selfArray)); - } - - // filter non-primary refs - for (DBRefEntry p : pr) - { - while (selfs.contains(p)) - { - selfs.remove(p); - } - } - List toPromote = new ArrayList<>(); - - for (DBRefEntry p : pr) - { - List promType = new ArrayList<>(); - if (sequence.isProtein()) - { - switch (getCanonicalName(p.getSource())) - { - case DBRefSource.UNIPROT: - // case DBRefSource.UNIPROTKB: - // case DBRefSource.UP_NAME: - // search for and promote ensembl - promType.add(DBRefSource.ENSEMBL); - break; - case DBRefSource.ENSEMBL: - // search for and promote Uniprot - promType.add(DBRefSource.UNIPROT); - break; - } - } - else - { - // TODO: promote transcript refs - } - - // collate candidates and promote them - DBRefEntry[] candidates = selectRefs(selfs.toArray(new DBRefEntry[0]), - promType.toArray(new String[0])); - if (candidates != null) - { - for (DBRefEntry cand : candidates) - { - if (cand.hasMap()) - { - if (cand.getMap().getTo() != null - && cand.getMap().getTo() != sequence) - { - // can't promote refs with mappings to other sequences - continue; - } - if (cand.getMap().getMap().getFromLowest() != sequence - .getStart() - && cand.getMap().getMap().getFromHighest() != sequence - .getEnd()) - { - // can't promote refs with mappings from a region of this sequence - // - eg CDS - continue; - } - } - // and promote - cand.setVersion(p.getVersion() + " (promoted)"); - selfs.remove(cand); - toPromote.add(cand); - if (!cand.isPrimaryCandidate()) - { - System.out.println( - "Warning: Couldn't promote dbref " + cand.toString() - + " for sequence " + sequence.toString()); - } - } - } - } - } + /** + * Parses a DBRefEntry and adds it to the sequence, also a PDBEntry if the + * database is PDB. + *

+ * Used by file parsers to generate DBRefs from annotation within file (eg + * Stockholm) + * + * @param dbname + * @param version + * @param acn + * @param seq where to annotate with reference + * @return parsed version of entry that was added to seq (if any) + */ + public static DBRefEntry parseToDbRef(SequenceI seq, String dbname, String version, String acn) { + DBRefEntry ref = null; + if (dbname != null) { + String locsrc = DBRefUtils.getCanonicalName(dbname); + if (locsrc.equals(DBRefSource.PDB)) { + /* + * Check for PFAM style stockhom PDB accession id citation e.g. "1WRI A; 7-80;" + */ + Regex r = new com.stevesoft.pat.Regex("([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)"); + if (r.search(acn.trim())) { + String pdbid = r.stringMatched(1); + String chaincode = r.stringMatched(2); + if (chaincode == null) { + chaincode = " "; + } + // String mapstart = r.stringMatched(3); + // String mapend = r.stringMatched(4); + if (chaincode.equals(" ")) { + chaincode = "_"; + } + // construct pdb ref. + ref = new DBRefEntry(locsrc, version, pdbid + chaincode); + PDBEntry pdbr = new PDBEntry(); + pdbr.setId(pdbid); + pdbr.setType(PDBEntry.Type.PDB); + pdbr.setChainCode(chaincode); + seq.addPDBId(pdbr); + } else { + System.err.println("Malformed PDB DR line:" + acn); + } + } else { + // default: + ref = new DBRefEntry(locsrc, version, acn); + } + } + if (ref != null) { + seq.addDBRef(ref); + } + return ref; + } + + /** + * Returns true if either object is null, or they are equal + * + * @param o1 + * @param o2 + * @return + */ + public static boolean nullOrEqual(Object o1, Object o2) { + if (o1 == null || o2 == null) { + return true; + } + return o1.equals(o2); + } + + /** + * canonicalise source string before comparing. null is always wildcard + * + * @param o1 - null or source string to compare + * @param o2 - null or source string to compare + * @return true if either o1 or o2 are null, or o1 equals o2 under + * DBRefUtils.getCanonicalName + * (o1).equals(DBRefUtils.getCanonicalName(o2)) + */ + public static boolean nullOrEqualSource(String o1, String o2) { + if (o1 == null || o2 == null) { + return true; + } + return DBRefUtils.getCanonicalName(o1).equals(DBRefUtils.getCanonicalName(o2)); + } + + /** + * Selects just the DNA or protein references from a set of references + * + * @param selectDna if true, select references to 'standard' DNA databases, else + * to 'standard' peptide databases + * @param refs a set of references to select from + * @return + */ + public static List selectDbRefs(boolean selectDna, List refs) { + return selectRefs(refs, selectDna ? DBRefSource.DNACODINGDBS : DBRefSource.PROTEINDBS); + // could attempt to find other cross + // refs here - ie PDB xrefs + // (not dna, not protein seq) + } + + /** + * Returns the (possibly empty) list of those supplied dbrefs which have the + * specified source database, with a case-insensitive match of source name + * + * @param dbRefs + * @param source + * @return + */ + public static List searchRefsForSource(List dbRefs, String source) { + List matches = new ArrayList(); + if (dbRefs != null && source != null) { + for (DBRefEntry dbref : dbRefs) { + if (source.equalsIgnoreCase(dbref.getSource())) { + matches.add(dbref); + } + } + } + return matches; + } + + /** + * promote direct database references to primary for nucleotide or protein + * sequences if they have an appropriate primary ref + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Seq TypePrimary DBDirect which will be promoted
peptidesEnsemblUniprot
peptidesEnsemblUniprot
dnaEnsemblENA
+ * + * @param sequence + */ + public static void ensurePrimaries(SequenceI sequence, List pr) { + if (pr.size() == 0) { + // nothing to do + return; + } + int sstart = sequence.getStart(); + int send = sequence.getEnd(); + boolean isProtein = sequence.isProtein(); + BitSet bsSelect = new BitSet(); + +// List selfs = new ArrayList(); +// { + +// List selddfs = selectDbRefs(!isprot, sequence.getDBRefs()); +// if (selfs == null || selfs.size() == 0) +// { +// // nothing to do +// return; +// } + + List dbrefs = sequence.getDBRefs(); + bsSelect.set(0, dbrefs.size()); + + if (!selectRefsBS(dbrefs, isProtein ? DBRefSource.PROTEIN_MASK : DBRefSource.DNA_CODING_MASK, bsSelect)) + return; + +// selfs.addAll(selfArray); +// } + + // filter non-primary refs + for (int ip = pr.size(); --ip >= 0;) { + DBRefEntry p = pr.get(ip); + for (int i = bsSelect.nextSetBit(0); i >= 0; i = bsSelect.nextSetBit(i + 1)) { + if (dbrefs.get(i) == p) + bsSelect.clear(i); + } +// while (selfs.contains(p)) +// { +// selfs.remove(p); +// } + } +// List toPromote = new ArrayList(); + + for (int ip = pr.size(), keys = 0; --ip >= 0 && keys != DBRefSource.PRIMARY_MASK;) { + DBRefEntry p = pr.get(ip); + if (isProtein) { + switch (getCanonicalName(p.getSource())) { + case DBRefSource.UNIPROT: + keys |= DBRefSource.UNIPROT_MASK; + break; + case DBRefSource.ENSEMBL: + keys |= DBRefSource.ENSEMBL_MASK; + break; + } + } else { + // TODO: promote transcript refs ?? + } + if (keys == 0 || !selectRefsBS(dbrefs, keys, bsSelect)) + return; +// if (candidates != null) + { + for (int ic = bsSelect.nextSetBit(0); ic >= 0; ic = bsSelect.nextSetBit(ic + 1)) +// for (int ic = 0, n = candidates.size(); ic < n; ic++) + { + DBRefEntry cand = dbrefs.get(ic);// candidates.get(ic); + if (cand.hasMap()) { + Mapping map = cand.getMap(); + SequenceI cto = map.getTo(); + if (cto != null && cto != sequence) { + // can't promote refs with mappings to other sequences + continue; + } + MapList mlist = map.getMap(); + if (mlist.getFromLowest() != sstart && mlist.getFromHighest() != send) { + // can't promote refs with mappings from a region of this sequence + // - eg CDS + continue; + } + } + // and promote - not that version must be non-null here, + // as p must have passed isPrimaryCandidate() + cand.setVersion(p.getVersion() + " (promoted)"); + bsSelect.clear(ic); + // selfs.remove(cand); +// toPromote.add(cand); + if (!cand.isPrimaryCandidate()) { + System.out.println("Warning: Couldn't promote dbref " + cand.toString() + " for sequence " + + sequence.toString()); + } + } + } + } + } } diff --cc src/jalview/viewmodel/AlignmentViewport.java index b764959,148ea16..e74f2e0 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@@ -2957,33 -2957,67 +2959,97 @@@ public abstract class AlignmentViewpor return currentTree; } + @Override + public AlignmentExportData getAlignExportData(AlignExportSettingsI options) + { + AlignmentI alignmentToExport = null; + String[] omitHidden = null; + alignmentToExport = null; + + if (hasHiddenColumns() && !options.isExportHiddenColumns()) + { + omitHidden = getViewAsString(false, + options.isExportHiddenSequences()); + } + + int[] alignmentStartEnd = new int[2]; + if (hasHiddenRows() && options.isExportHiddenSequences()) + { + alignmentToExport = getAlignment().getHiddenSequences() + .getFullAlignment(); + } + else + { + alignmentToExport = getAlignment(); + } + alignmentStartEnd = getAlignment().getHiddenColumns() + .getVisibleStartAndEndIndex(alignmentToExport.getWidth()); + AlignmentExportData ed = new AlignmentExportData(alignmentToExport, + omitHidden, alignmentStartEnd); + return ed; + } ++ + /** + * flag set to indicate if structure views might be out of sync with sequences + * in the alignment + */ + + private boolean needToUpdateStructureViews = false; + + @Override + public boolean isUpdateStructures() + { + return needToUpdateStructureViews; + } + + @Override + public void setUpdateStructures(boolean update) + { + needToUpdateStructureViews = update; + } + + @Override + public boolean needToUpdateStructureViews() + { + boolean update = needToUpdateStructureViews; + needToUpdateStructureViews = false; + return update; + } + + @Override + public void addSequenceGroup(SequenceGroup sequenceGroup) + { + alignment.addGroup(sequenceGroup); + + Color col = sequenceGroup.idColour; + if (col != null) + { + col = col.brighter(); + + for (SequenceI sq : sequenceGroup.getSequences()) + { + setSequenceColour(sq, col); + } + } + + if (codingComplement != null) + { + SequenceGroup mappedGroup = MappingUtils + .mapSequenceGroup(sequenceGroup, this, codingComplement); + if (mappedGroup.getSequences().size() > 0) + { + codingComplement.getAlignment().addGroup(mappedGroup); + + if (col != null) + { + for (SequenceI seq : mappedGroup.getSequences()) + { + codingComplement.setSequenceColour(seq, col); + } + } + } + // propagate the structure view update flag according to our own setting + codingComplement.setUpdateStructures(needToUpdateStructureViews); + } + } } diff --cc src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index 719cde4,4af6fde..6bf1f45 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@@ -1151,30 -1156,32 +1157,58 @@@ public abstract class FeatureRendererMo return filter == null ? true : filter.matches(sf); } + /** + * Answers true unless the specified group is set to hidden. Defaults to true + * if group visibility is not set. + * + * @param group + * @return + */ + public boolean isGroupVisible(String group) + { + if (!featureGroups.containsKey(group)) + { + return true; + } + return featureGroups.get(group); + } + + /** + * Orders features in render precedence (last in order is last to render, so + * displayed on top of other features) + * + * @param order + */ + public void orderFeatures(Comparator order) + { + Arrays.sort(renderOrder, order); + } ++ + @Override + public boolean isVisible(SequenceFeature feature) + { + if (feature == null) + { + return false; + } + if (getFeaturesDisplayed() == null + || !getFeaturesDisplayed().isVisible(feature.getType())) + { + return false; + } + if (featureGroupNotShown(feature)) + { + return false; + } + FeatureColourI fc = featureColours.get(feature.getType()); + if (fc != null && fc.isOutwithThreshold(feature)) + { + return false; + } + if (!featureMatchesFilters(feature)) + { + return false; + } + return true; + } - } diff --cc test/jalview/io/CrossRef2xmlTests.java index f8157ec,53a0acb..6e4593d --- a/test/jalview/io/CrossRef2xmlTests.java +++ b/test/jalview/io/CrossRef2xmlTests.java @@@ -29,9 -29,8 +29,9 @@@ import jalview.datamodel.SequenceI import jalview.gui.AlignFrame; import jalview.gui.CrossRefAction; import jalview.gui.Desktop; - import jalview.gui.Jalview2XML; import jalview.gui.JvOptionPane; +import jalview.gui.SequenceFetcher; + import jalview.project.Jalview2XML; import jalview.util.DBRefUtils; import java.io.File; diff --cc test/jalview/project/Jalview2xmlTests.java index 1443950,d902fa2..e9221e0 --- a/test/jalview/project/Jalview2xmlTests.java +++ b/test/jalview/project/Jalview2xmlTests.java @@@ -105,13 -109,13 +109,14 @@@ public class Jalview2xmlTests extends J assertNotNull(af, "Didn't read input file " + inFile); int olddsann = countDsAnn(af.getViewport()); assertTrue(olddsann > 0, "Didn't find any dataset annotations"); - af.changeColour_actionPerformed(JalviewColourScheme.RNAHelices - .toString()); + af.changeColour_actionPerformed( + JalviewColourScheme.RNAHelices.toString()); assertTrue( - af.getViewport().getGlobalColourScheme() instanceof RNAHelicesColour, + af.getViewport() + .getGlobalColourScheme() instanceof RNAHelicesColour, "Couldn't apply RNA helices colourscheme"); - assertTrue(af.saveAlignment(tfile, FileFormat.Jalview), + af.saveAlignment(tfile, FileFormat.Jalview); + assertTrue(af.isSaveAlignmentSuccessful(), "Failed to store as a project."); af.closeMenuItem_actionPerformed(true); af = null; @@@ -141,14 -147,17 +148,18 @@@ DataSourceType.FILE); assertNotNull(af, "Didn't read input file " + inFile); af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null); - assertSame(af.getViewport().getGlobalColourScheme().getClass(), + AlignViewport viewport = af.getViewport(); + assertSame(viewport.getGlobalColourScheme().getClass(), TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme"); - assertNotNull(ColourSchemeProperty.getColourScheme(af.getViewport() - .getAlignment(), af.getViewport().getGlobalColourScheme() - .getSchemeName()), "Recognise T-Coffee score from string"); + assertNotNull( + ColourSchemeProperty.getColourScheme(viewport, + viewport.getAlignment(), + viewport.getGlobalColourScheme() + .getSchemeName()), + "Recognise T-Coffee score from string"); - assertTrue(af.saveAlignment(tfile, FileFormat.Jalview), + af.saveAlignment(tfile, FileFormat.Jalview); + assertTrue(af.isSaveAlignmentSuccessful(), "Failed to store as a project."); af.closeMenuItem_actionPerformed(true); af = null; diff --cc test/jalview/ws/dbsources/UniprotTest.java index e6b465b,86f5602..d8ed08e --- a/test/jalview/ws/dbsources/UniprotTest.java +++ b/test/jalview/ws/dbsources/UniprotTest.java @@@ -215,8 -215,10 +215,9 @@@ public class UniprotTes is).get(0); SequenceI seq = new Uniprot().uniprotEntryToSequence(entry); assertNotNull(seq); - assertEquals(6, seq.getDBRefs().length); // 2*Uniprot, PDB, PDBsum, 2*EMBL + assertEquals(6, seq.getDBRefs().size()); // 2*Uniprot, PDB, PDBsum, 2*EMBL - + assertEquals(seq.getSequenceAsString(), + seq.createDatasetSequence().getSequenceAsString()); - } /**